Updated 24-nbody to demonstrate how to use indirect buffer.

This commit is contained in:
Branimir Karadžić 2015-05-01 19:52:11 -07:00
parent a91232015f
commit bfa4df4ba1
3 changed files with 75 additions and 7 deletions

View file

@ -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);
}

View file

@ -118,7 +118,8 @@ int _main_(int /*_argc*/, char** /*_argv*/)
); );
const bgfx::Caps* caps = bgfx::getCaps(); 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) 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::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv, 3);
bgfx::ShaderHandle initInstancesShader = loadShader("cs_init_instances"); bgfx::ProgramHandle initInstancesProgram = bgfx::createProgram(loadShader("cs_init_instances"), true);
bgfx::ProgramHandle initInstancesProgram = bgfx::createProgram(initInstancesShader, true); bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(loadShader("cs_update_instances"), true);
bgfx::ShaderHandle updateInstancesShader = loadShader("cs_update_instances");
bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(updateInstancesShader, 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; u_paramsDataStruct u_paramsData;
InitializeParams(0, &u_paramsData); InitializeParams(0, &u_paramsData);
@ -184,6 +192,8 @@ int _main_(int /*_argc*/, char** /*_argv*/)
int32_t scrollArea = 0; int32_t scrollArea = 0;
bool useIndirect = false;
entry::MouseState mouseState; entry::MouseState mouseState;
while (!entry::processEvents(width, height, debug, reset, &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 double freq = double(bx::getHPFrequency() );
const float deltaTime = float(frameTime/freq); const float deltaTime = float(frameTime/freq);
if (deltaTime > 1000.0)
{
abort();
}
// Set view 0 default viewport. // Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, width, height); 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 intensity", u_paramsData.particleIntensity, 0.0f, 1.0f, 0.001f);
imguiSlider("Particle size", u_paramsData.particleSize, 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); imguiSlider("Particle power", u_paramsData.particlePower, 0.001f, 16.0f, 0.01f);
imguiSeparatorLine();
if (imguiCheck("Use draw/dispatch indirect", useIndirect, indirectSupported) )
{
useIndirect = !useIndirect;
}
imguiEndScrollArea(); imguiEndScrollArea();
imguiEndFrame(); imguiEndFrame();
@ -243,12 +263,27 @@ int _main_(int /*_argc*/, char** /*_argv*/)
bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1); 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(0, prevPositionBuffer0, bgfx::Access::Read);
bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Read); bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Read);
bgfx::setBuffer(2, prevPositionBuffer1, bgfx::Access::Write); bgfx::setBuffer(2, prevPositionBuffer1, bgfx::Access::Write);
bgfx::setBuffer(3, currPositionBuffer1, bgfx::Access::Write); bgfx::setBuffer(3, currPositionBuffer1, bgfx::Access::Write);
bgfx::setUniform(u_params, &u_paramsData, 3); 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(currPositionBuffer0, currPositionBuffer1);
bx::xchg(prevPositionBuffer0, prevPositionBuffer1); bx::xchg(prevPositionBuffer0, prevPositionBuffer1);
@ -305,7 +340,14 @@ int _main_(int /*_argc*/, char** /*_argv*/)
); );
// Submit primitive for rendering to view 0. // 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 // Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives. // process submitted rendering primitives.
@ -315,6 +357,14 @@ int _main_(int /*_argc*/, char** /*_argv*/)
// Cleanup. // Cleanup.
cameraDestroy(); cameraDestroy();
imguiDestroy(); imguiDestroy();
if (indirectSupported)
{
bgfx::destroyProgram(indirectProgram);
bgfx::destroyIndirectBuffer(indirectBuffer);
}
bgfx::destroyUniform(u_params); bgfx::destroyUniform(u_params);
bgfx::destroyDynamicVertexBuffer(currPositionBuffer0); bgfx::destroyDynamicVertexBuffer(currPositionBuffer0);
bgfx::destroyDynamicVertexBuffer(currPositionBuffer1); bgfx::destroyDynamicVertexBuffer(currPositionBuffer1);

View file

@ -5,6 +5,8 @@
uniform vec4 u_params[3]; uniform vec4 u_params[3];
#define threadGroupUpdateSize 512
#define u_timeStep u_params[0].x #define u_timeStep u_params[0].x
#define u_dispatchSize floatBitsToUint(u_params[0].y) #define u_dispatchSize floatBitsToUint(u_params[0].y)
#define u_gravity u_params[0].z #define u_gravity u_params[0].z