From bfa4df4ba19fddd82630cfd640d12cf41052c350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 1 May 2015 19:52:11 -0700 Subject: [PATCH] Updated 24-nbody to demonstrate how to use indirect buffer. --- examples/24-nbody/cs_indirect.sc | 16 ++++++++ examples/24-nbody/nbody.cpp | 64 ++++++++++++++++++++++++++++---- examples/24-nbody/uniforms.sh | 2 + 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 examples/24-nbody/cs_indirect.sc diff --git a/examples/24-nbody/cs_indirect.sc b/examples/24-nbody/cs_indirect.sc new file mode 100644 index 000000000..8dfc01935 --- /dev/null +++ b/examples/24-nbody/cs_indirect.sc @@ -0,0 +1,16 @@ +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "bgfx_compute.sh" +#include "uniforms.sh" + +BUFFER_WR(indirectBuffer, uvec4, 0); + +NUM_THREADS(1, 1, 1) +void main() +{ + drawIndexedIndirect(indirectBuffer, 0, 6, u_dispatchSize * threadGroupUpdateSize, 0, 0, 0); + dispatchIndirect(indirectBuffer, 1, u_dispatchSize, 1, 1); +} diff --git a/examples/24-nbody/nbody.cpp b/examples/24-nbody/nbody.cpp index b006f0b13..72da9e38a 100644 --- a/examples/24-nbody/nbody.cpp +++ b/examples/24-nbody/nbody.cpp @@ -118,7 +118,8 @@ int _main_(int /*_argc*/, char** /*_argv*/) ); const bgfx::Caps* caps = bgfx::getCaps(); - const bool computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); + const bool computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); + const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT); if (computeSupported) { @@ -162,10 +163,17 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv, 3); - bgfx::ShaderHandle initInstancesShader = loadShader("cs_init_instances"); - bgfx::ProgramHandle initInstancesProgram = bgfx::createProgram(initInstancesShader, true); - bgfx::ShaderHandle updateInstancesShader = loadShader("cs_update_instances"); - bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(updateInstancesShader, true); + bgfx::ProgramHandle initInstancesProgram = bgfx::createProgram(loadShader("cs_init_instances"), true); + bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(loadShader("cs_update_instances"), true); + + bgfx::ProgramHandle indirectProgram = BGFX_INVALID_HANDLE; + bgfx::IndirectBufferHandle indirectBuffer = BGFX_INVALID_HANDLE; + + if (indirectSupported) + { + indirectProgram = bgfx::createProgram(loadShader("cs_indirect"), true); + indirectBuffer = bgfx::createIndirectBuffer(2); + } u_paramsDataStruct u_paramsData; InitializeParams(0, &u_paramsData); @@ -184,6 +192,8 @@ int _main_(int /*_argc*/, char** /*_argv*/) int32_t scrollArea = 0; + bool useIndirect = false; + entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { @@ -194,6 +204,11 @@ int _main_(int /*_argc*/, char** /*_argv*/) const double freq = double(bx::getHPFrequency() ); const float deltaTime = float(frameTime/freq); + if (deltaTime > 1000.0) + { + abort(); + } + // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); @@ -225,6 +240,11 @@ int _main_(int /*_argc*/, char** /*_argv*/) imguiSlider("Particle intensity", u_paramsData.particleIntensity, 0.0f, 1.0f, 0.001f); imguiSlider("Particle size", u_paramsData.particleSize, 0.0f, 1.0f, 0.001f); imguiSlider("Particle power", u_paramsData.particlePower, 0.001f, 16.0f, 0.01f); + imguiSeparatorLine(); + if (imguiCheck("Use draw/dispatch indirect", useIndirect, indirectSupported) ) + { + useIndirect = !useIndirect; + } imguiEndScrollArea(); imguiEndFrame(); @@ -243,12 +263,27 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1); } + if (useIndirect) + { + bgfx::setUniform(u_params, &u_paramsData, 3); + bgfx::setBuffer(0, indirectBuffer, bgfx::Access::Write); + bgfx::dispatch(0, indirectProgram); + } + bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Read); bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Read); bgfx::setBuffer(2, prevPositionBuffer1, bgfx::Access::Write); bgfx::setBuffer(3, currPositionBuffer1, bgfx::Access::Write); bgfx::setUniform(u_params, &u_paramsData, 3); - bgfx::dispatch(0, updateInstancesProgram, u_paramsData.dispatchSize, 1, 1); + + if (useIndirect) + { + bgfx::dispatch(0, updateInstancesProgram, indirectBuffer, 1); + } + else + { + bgfx::dispatch(0, updateInstancesProgram, u_paramsData.dispatchSize, 1, 1); + } bx::xchg(currPositionBuffer0, currPositionBuffer1); bx::xchg(prevPositionBuffer0, prevPositionBuffer1); @@ -305,7 +340,14 @@ int _main_(int /*_argc*/, char** /*_argv*/) ); // Submit primitive for rendering to view 0. - bgfx::submit(0); + if (useIndirect) + { + bgfx::submit(0, indirectBuffer, 0); + } + else + { + bgfx::submit(0); + } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. @@ -315,6 +357,14 @@ int _main_(int /*_argc*/, char** /*_argv*/) // Cleanup. cameraDestroy(); imguiDestroy(); + + if (indirectSupported) + { + bgfx::destroyProgram(indirectProgram); + bgfx::destroyIndirectBuffer(indirectBuffer); + } + + bgfx::destroyUniform(u_params); bgfx::destroyDynamicVertexBuffer(currPositionBuffer0); bgfx::destroyDynamicVertexBuffer(currPositionBuffer1); diff --git a/examples/24-nbody/uniforms.sh b/examples/24-nbody/uniforms.sh index e77698e20..70540164d 100644 --- a/examples/24-nbody/uniforms.sh +++ b/examples/24-nbody/uniforms.sh @@ -5,6 +5,8 @@ uniform vec4 u_params[3]; +#define threadGroupUpdateSize 512 + #define u_timeStep u_params[0].x #define u_dispatchSize floatBitsToUint(u_params[0].y) #define u_gravity u_params[0].z