diff --git a/README.md b/README.md index 7b6575b10..61471706b 100644 --- a/README.md +++ b/README.md @@ -290,6 +290,12 @@ Rendering lines as oldschool vectors. ![example-23-vectordisplay](https://github.com/bkaradzic/bgfx/raw/master/examples/23-vectordisplay/screenshot.png) +### [24-nbody](https://github.com/bkaradzic/bgfx/tree/master/examples/24-nbody) + +N-body simulation with compute shaders using buffers. + +![example-24-nbody](https://github.com/bkaradzic/bgfx/raw/master/examples/24-nbody/screenshot.png) + Dependencies ------------ @@ -717,6 +723,7 @@ p0nce ([@p0nce](https://github.com/p0nce)) - D language API bindings. Mike Popoloski ([@MikePopoloski](https://github.com/MikePopoloski)) - C#/VB/F# language API bindings, WinRT/WinPhone support. Kai Jourdan ([@questor](https://github.com/questor)) - 23-vectordisplay example +Stanlo Slasinski [@stanlo](https://github.com/stanlo) - 24-nbody example [License (BSD 2-clause)](https://github.com/bkaradzic/bgfx/blob/master/LICENSE) ------------------------------------------------------------------------------- diff --git a/examples/24-nbody/cs_init_instances.sc b/examples/24-nbody/cs_init_instances.sc new file mode 100644 index 000000000..495cdd60d --- /dev/null +++ b/examples/24-nbody/cs_init_instances.sc @@ -0,0 +1,105 @@ +/* + * 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(prevPositionBuffer, vec4, 0); +BUFFER_WR(curPositionBuffer, vec4, 1); + +uint rotl(uint _x, uint _r) +{ + return (_x << _r) | (_x >> (32u - _r) ); +} + +uint hash(uint _key, uint _seed) +{ + uint c1 = 0xcc9e2d51u; + uint c2 = 0x1b873593u; + + uint k1 = _key; + uint h1 = _seed; + k1 *= c1; + k1 = rotl(k1, 15u); + k1 *= c2; + + h1 ^= k1; + h1 = rotl(h1, 13u); + h1 = h1 * 5u + 0xe6546b64u; + k1 *= c1; + k1 = rotl(k1, 15u); + k1 *= c2; + h1 ^= k1; + + h1 ^= h1 >> uint(16u); + h1 *= 0x85ebca6bu; + h1 ^= h1 >> 13u; + h1 *= 0xc2b2ae35u; + h1 ^= h1 >> 16u; + + return h1; +} + +vec3 randomPointOnSphere(uint _id, uint _seed) +{ + uvec2 u = uvec2( + hash(_id, _seed + 0u), + hash(_id, _seed + 1u) + ); + vec2 v = uintBitsToFloat( (u >> 9u) | 0x3f800000u) - 1.0; + + float lambda = v.x * 3.14159 * 2.0; + float phi = acos(2.0 * v.y - 1.0) - 3.14159 / 2.0; + + vec3 p; + p.x = cos(lambda) * cos(phi); + p.y = sin(phi); + p.z = sin(lambda) * cos(phi); + + return p; +} + +NUM_THREADS(512, 1, 1) +void main() +{ + uint key = gl_GlobalInvocationID.x; + + vec3 position; + + if (u_initialShape == 0u) + { + position = vec3_splat(0.0); + } + else if (u_initialShape == 1u) + { + position = 20.0 * randomPointOnSphere(gl_GlobalInvocationID.x, u_baseSeed * 7u); + } + else if (u_initialShape == 2u) + { + uvec3 u = uvec3( + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 0u), + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 1u), + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 2u) + ); + position = 20.0 * (uintBitsToFloat((u >> 9u) | uvec3(0x40000000, 0x40000000, 0x40000000) ) - 3.0); + } + else + { + uvec3 u = uvec3( + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 0u), + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 1u), + hash(gl_GlobalInvocationID.x, u_baseSeed * 7u + 2u) + ); + vec3 v = 3.14159 * 2.0 * (uintBitsToFloat( (u >> 9u) | uvec3(0x3f800000u, 0x3f800000u, 0x3f800000u) ) - 1.0); + position.x = 20.0 * cos(v.x) + 3.0 * cos(v.y) * cos(v.x); + position.y = 3.0 * sin(v.y); + position.z = 20.0 * sin(v.x) + 3.0 * cos(v.y) * sin(v.x); + } + + vec3 velocity = u_initialSpeed * randomPointOnSphere(gl_GlobalInvocationID.x, u_baseSeed * 7u + 3u); + + prevPositionBuffer[gl_GlobalInvocationID.x] = vec4(position - velocity * u_timeStep, 0.0); + curPositionBuffer[ gl_GlobalInvocationID.x] = vec4(position, 0.0); +} diff --git a/examples/24-nbody/cs_update_instances.sc b/examples/24-nbody/cs_update_instances.sc new file mode 100644 index 000000000..3ca1f9962 --- /dev/null +++ b/examples/24-nbody/cs_update_instances.sc @@ -0,0 +1,67 @@ +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "bgfx_compute.sh" +#include "uniforms.sh" + +BUFFER_RO(prevPositionBuffer, vec4, 0); +BUFFER_RO(curPositionBuffer, vec4, 1); +BUFFER_WR(outPrevPositionBuffer, vec4, 2); +BUFFER_WR(outCurPositionBuffer, vec4, 3); + +#define GROUP_SIZE 512 +SHARED vec3 otherEntries[GROUP_SIZE]; + +vec3 calcAcceleration(vec3 _curPosition, vec3 _otherPosition) +{ + vec3 difference = _otherPosition - _curPosition; + float dist2 = dot(difference, difference); + float dist6 = dist2 * dist2 * dist2; + float invDist3 = 1.0 / (sqrt(dist6) + 0.1); + return u_gravity * invDist3 * difference; +} + +NUM_THREADS(GROUP_SIZE, 1, 1) +void main() +{ + vec3 prevPosition = prevPositionBuffer[gl_GlobalInvocationID.x].xyz; + vec3 curPosition = curPositionBuffer[ gl_GlobalInvocationID.x].xyz; + + vec3 newAcceleration = vec3_splat(0.0); + + for (int j = 0; j < int(u_dispatchSize); ++j) + { + otherEntries[gl_LocalInvocationIndex] = curPositionBuffer[j * GROUP_SIZE + int(gl_LocalInvocationIndex)].xyz; + + barrier(); + for (int i = 0; i < GROUP_SIZE; ++i) + { + newAcceleration += calcAcceleration(curPosition, otherEntries[i]); + } + } + + newAcceleration += (prevPosition - curPosition) * u_damping; + float accelerationMagnitude = length(newAcceleration); + float color = pow(min(accelerationMagnitude / 3.0, 1.0), 0.25); + if (accelerationMagnitude > 0.0) + { + newAcceleration = normalize(newAcceleration) * min(accelerationMagnitude, u_maxAcceleration); + } + + vec3 newPosition = 2.0 * curPosition - prevPosition + newAcceleration * u_timeStep; + + if (any(isnan(newPosition) ) ) + { + newPosition = vec3_splat(0.0); + } + + if (any(isnan(curPosition) ) ) + { + curPosition = vec3_splat(0.0); + } + + outPrevPositionBuffer[gl_GlobalInvocationID.x] = vec4(curPosition, 0.0); + outCurPositionBuffer[ gl_GlobalInvocationID.x] = vec4(newPosition, color); +} diff --git a/examples/24-nbody/fs_particle.sc b/examples/24-nbody/fs_particle.sc new file mode 100644 index 000000000..ac78c23b5 --- /dev/null +++ b/examples/24-nbody/fs_particle.sc @@ -0,0 +1,16 @@ +$input v_texCoord + +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +void main() +{ + vec3 color = mix(vec3(0.1f, 0.8f, 0.2f), 0.5 * vec3(0.3, 0.25, 0.05), v_texCoord.z); + float f = u_particleIntensity * pow(max(1.0 - length(v_texCoord.xy), 0.0), u_particlePower); + gl_FragColor = vec4(color * f, 1.0); +} diff --git a/examples/24-nbody/makefile b/examples/24-nbody/makefile new file mode 100644 index 000000000..5ce066214 --- /dev/null +++ b/examples/24-nbody/makefile @@ -0,0 +1,17 @@ +# +# Copyright 2011-2014 Branimir Karadzic. All rights reserved. +# License: http://www.opensource.org/licenses/BSD-2-Clause +# + +BGFX_DIR=../.. +RUNTIME_DIR=$(BGFX_DIR)/examples/runtime +BUILD_DIR=../../.build + +include $(BGFX_DIR)/scripts/shader.mk + +rebuild: + @make -s --no-print-directory TARGET=0 clean all + @make -s --no-print-directory TARGET=1 clean all + @make -s --no-print-directory TARGET=2 clean all + @make -s --no-print-directory TARGET=3 clean all + @make -s --no-print-directory TARGET=4 clean all diff --git a/examples/24-nbody/nbody.cpp b/examples/24-nbody/nbody.cpp new file mode 100644 index 000000000..38f9eadb8 --- /dev/null +++ b/examples/24-nbody/nbody.cpp @@ -0,0 +1,272 @@ +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "common.h" +#include "bgfx_utils.h" +#include "imgui/imgui.h" +#include "camera.h" +#include + +static const float s_quadVertices[] = +{ + 1.0f, 1.0f, + -1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, -1.0f, +}; + +static const uint16_t s_quadIndices[] = { 0, 1, 2, 2, 3, 0, }; + +int _main_(int /*_argc*/, char** /*_argv*/) +{ + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + uint32_t reset = BGFX_RESET_VSYNC; + + bgfx::init(); + bgfx::reset(width, height, reset); + + // Enable debug text. + bgfx::setDebug(debug); + + // Set view 0 clear state. + bgfx::setViewClear(0 + , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT + , 0x303030ff + , 1.0f + , 0 + ); + + void* data = load("font/droidsans.ttf"); + imguiCreate(data); + free(data); + + bgfx::VertexDecl quadVertexDecl; + quadVertexDecl.begin() + .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) + .end(); + + // Create static vertex buffer. + bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer( + // Static data can be passed with bgfx::makeRef + bgfx::makeRef(s_quadVertices, sizeof(s_quadVertices) ) + , quadVertexDecl + ); + + // Create static index buffer. + bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer( + // Static data can be passed with bgfx::makeRef + bgfx::makeRef(s_quadIndices, sizeof(s_quadIndices) ) + ); + + // Create particle program from shaders. + bgfx::ProgramHandle particleProgram = loadProgram("vs_particle", "fs_particle"); + + // Setup compute buffers + bgfx::VertexDecl computeVertexDecl; + computeVertexDecl.begin() + .add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float) + .end(); + + const uint32_t threadGroupUpdateSize = 512; + + bgfx::DynamicVertexBufferHandle currPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); + bgfx::DynamicVertexBufferHandle currPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); + bgfx::DynamicVertexBufferHandle prevPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); + bgfx::DynamicVertexBufferHandle prevPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); + + bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv, 3); + struct + { + float timeStep; + int32_t dispatchSize; + float gravity; + float damping; + float particleIntensity; + float particleSize; + int32_t baseSeed; + float particlePower; + float initialSpeed; + int32_t initialShape; + float maxAccel; + + } u_paramsData; + + u_paramsData.timeStep = 0.0083f; + u_paramsData.dispatchSize = 16; + u_paramsData.gravity = 0.069f * 0.069f; + u_paramsData.damping = 0.07f; + u_paramsData.particleIntensity = 0.35f; + u_paramsData.particleSize = 0.4f; + u_paramsData.baseSeed = 0; + u_paramsData.particlePower = 5.0f; + u_paramsData.initialSpeed = 85.0f; //112.0f; + u_paramsData.initialShape = 0; + u_paramsData.maxAccel = 30.0; + + float uiGravity = 0.069f; + + 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::setUniform(u_params, &u_paramsData, 3); + bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write); + bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write); + bgfx::dispatch(0, initInstancesProgram, (32 * threadGroupUpdateSize) / 1024, 1, 1); + + float view[16]; + float initialPos[3] = { 0.0f, 0.0f, -25.0f }; + cameraCreate(); + cameraSetPosition(initialPos); + cameraSetVerticalAngle(0.0f); + cameraGetViewMtx(view); + + int32_t scrollArea = 0; + + entry::MouseState mouseState; + while (!entry::processEvents(width, height, debug, reset, &mouseState) ) + { + int64_t now = bx::getHPCounter(); + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency() ); + const float deltaTime = float(frameTime/freq); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers."); + + imguiBeginFrame(mouseState.m_mx + , mouseState.m_my + , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) + | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) + , 0 + , width + , height + ); + imguiBeginScrollArea("Settings", width - width / 4 - 10, 10, width / 4, 500, &scrollArea); + imguiSlider("Random seed", u_paramsData.baseSeed, 0, 100); + u_paramsData.initialShape = imguiChoose(u_paramsData.initialShape, "Point", "Sphere", "Box", "Donut"); + imguiSlider("Initial speed", u_paramsData.initialSpeed, 0.0f, 300.0f, 0.1f); + bool reset = imguiButton("Reset"); + imguiSeparatorLine(); + imguiSlider("Particle count (x1024)", u_paramsData.dispatchSize, 1, 32); + imguiSlider("Gravity", uiGravity, 0.0f, 0.3f, 0.001f); + imguiSlider("Damping", u_paramsData.damping, 0.0f, 1.0f, 0.01f); + imguiSlider("Max acceleration", u_paramsData.maxAccel, 0.0f, 100.0f, 0.01f); + imguiSlider("Time step", u_paramsData.timeStep, 0.0f, 0.02f, 0.0001f); + imguiSeparatorLine(); + 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); + imguiEndScrollArea(); + imguiEndFrame(); + + u_paramsData.gravity = uiGravity * uiGravity; + + float eye[3] = { 0.0f, 0.0f, -35.0f }; + float view[16]; + + // Update camera. + cameraUpdate(deltaTime, mouseState); + cameraGetViewMtx(view); + + // Set view and projection matrix for view 0. + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 10000.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float proj[16]; + bx::mtxProj(proj, 90.0f, float(width)/float(height), 0.1f, 10000.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } + + // Update instances + bgfx::setUniform(u_params, &u_paramsData, 3); + + if (reset) + { + bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write); + bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write); + bgfx::dispatch(0, initInstancesProgram, (32 * threadGroupUpdateSize) / 1024, 1, 1); + } + + 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::dispatch(0, updateInstancesProgram, u_paramsData.dispatchSize, 1, 1); + + bx::swap(currPositionBuffer0, currPositionBuffer1); + bx::swap(prevPositionBuffer0, prevPositionBuffer1); + + // Set vertex and fragment shaders. + bgfx::setProgram(particleProgram); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(vbh); + bgfx::setIndexBuffer(ibh); + bgfx::setInstanceDataBuffer(currPositionBuffer0, 0, u_paramsData.dispatchSize * threadGroupUpdateSize); + + // Set render states. + bgfx::setState(0 + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_ADD + | BGFX_STATE_DEPTH_TEST_ALWAYS + ); + + // Submit primitive for rendering to view 0. + bgfx::submit(0); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + } + + // Cleanup. + cameraDestroy(); + imguiDestroy(); + bgfx::destroyUniform(u_params); + bgfx::destroyDynamicVertexBuffer(currPositionBuffer0); + bgfx::destroyDynamicVertexBuffer(currPositionBuffer1); + bgfx::destroyDynamicVertexBuffer(prevPositionBuffer0); + bgfx::destroyDynamicVertexBuffer(prevPositionBuffer1); + bgfx::destroyProgram(updateInstancesProgram); + bgfx::destroyProgram(initInstancesProgram); + bgfx::destroyIndexBuffer(ibh); + bgfx::destroyVertexBuffer(vbh); + bgfx::destroyProgram(particleProgram); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; +} diff --git a/examples/24-nbody/screenshot.png b/examples/24-nbody/screenshot.png new file mode 100644 index 000000000..5212177f3 Binary files /dev/null and b/examples/24-nbody/screenshot.png differ diff --git a/examples/24-nbody/uniforms.sh b/examples/24-nbody/uniforms.sh new file mode 100644 index 000000000..e77698e20 --- /dev/null +++ b/examples/24-nbody/uniforms.sh @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +uniform vec4 u_params[3]; + +#define u_timeStep u_params[0].x +#define u_dispatchSize floatBitsToUint(u_params[0].y) +#define u_gravity u_params[0].z +#define u_damping u_params[0].w + +#define u_particleIntensity u_params[1].x +#define u_particleSize u_params[1].y +#define u_baseSeed floatBitsToUint(u_params[1].z) +#define u_particlePower u_params[1].w + +#define u_initialSpeed u_params[2].x +#define u_initialShape floatBitsToUint(u_params[2].y) +#define u_maxAcceleration u_params[2].z diff --git a/examples/24-nbody/varying.def.sc b/examples/24-nbody/varying.def.sc new file mode 100644 index 000000000..c2bead997 --- /dev/null +++ b/examples/24-nbody/varying.def.sc @@ -0,0 +1,4 @@ +vec2 a_position : POSITION; +vec4 i_data3 : TEXCOORD7; + +vec3 v_texCoord : TEXCOORD0 = vec3(0.0, 0.0, 0.0); diff --git a/examples/24-nbody/vs_particle.sc b/examples/24-nbody/vs_particle.sc new file mode 100644 index 000000000..329bcc497 --- /dev/null +++ b/examples/24-nbody/vs_particle.sc @@ -0,0 +1,23 @@ +$input a_position, i_data3 +$output v_texCoord + +/* + * Copyright 2014 Stanlo Slasinski. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "../common/common.sh" +#include "uniforms.sh" + +void main() +{ + vec3 eye = mul(u_view, vec4(i_data3.xyz, 1.0) ).xyz; + vec3 up = normalize(cross(eye, vec3(1.0, 0.0, 0.0) ) ); + vec3 right = normalize(cross(up, eye)); + float size = u_particleSize; + vec3 position = eye + size * right * a_position.x + size * up * a_position.y; + + v_texCoord.xy = a_position; + v_texCoord.z = i_data3.w; + gl_Position = mul(u_proj, vec4(position, 1.0) ); +} diff --git a/examples/makefile b/examples/makefile index d1ac5b744..dd33cb196 100644 --- a/examples/makefile +++ b/examples/makefile @@ -26,6 +26,7 @@ rebuild: # @make -s --no-print-directory rebuild -C 20-nanovg @make -s --no-print-directory rebuild -C 21-deferred @make -s --no-print-directory rebuild -C 23-vectordisplay + @make -s --no-print-directory rebuild -C 24-nbody @make -s --no-print-directory rebuild -C common/font @make -s --no-print-directory rebuild -C common/imgui @make -s --no-print-directory rebuild -C common/nanovg diff --git a/examples/runtime/shaders/dx11/cs_init_instances.bin b/examples/runtime/shaders/dx11/cs_init_instances.bin new file mode 100644 index 000000000..23b42a9c5 Binary files /dev/null and b/examples/runtime/shaders/dx11/cs_init_instances.bin differ diff --git a/examples/runtime/shaders/dx11/cs_update_instances.bin b/examples/runtime/shaders/dx11/cs_update_instances.bin new file mode 100644 index 000000000..8bc43b90a Binary files /dev/null and b/examples/runtime/shaders/dx11/cs_update_instances.bin differ diff --git a/examples/runtime/shaders/dx11/fs_particle.bin b/examples/runtime/shaders/dx11/fs_particle.bin new file mode 100644 index 000000000..f32c363f5 Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_particle.bin differ diff --git a/examples/runtime/shaders/dx11/vs_particle.bin b/examples/runtime/shaders/dx11/vs_particle.bin new file mode 100644 index 000000000..23d163e61 Binary files /dev/null and b/examples/runtime/shaders/dx11/vs_particle.bin differ diff --git a/examples/runtime/shaders/dx9/fs_particle.bin b/examples/runtime/shaders/dx9/fs_particle.bin new file mode 100644 index 000000000..979449435 Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_particle.bin differ diff --git a/examples/runtime/shaders/dx9/vs_particle.bin b/examples/runtime/shaders/dx9/vs_particle.bin new file mode 100644 index 000000000..9bd5ba1f1 Binary files /dev/null and b/examples/runtime/shaders/dx9/vs_particle.bin differ diff --git a/examples/runtime/shaders/gles/cs_init_instances.bin b/examples/runtime/shaders/gles/cs_init_instances.bin new file mode 100644 index 000000000..92cc0d8e8 Binary files /dev/null and b/examples/runtime/shaders/gles/cs_init_instances.bin differ diff --git a/examples/runtime/shaders/gles/cs_update_instances.bin b/examples/runtime/shaders/gles/cs_update_instances.bin new file mode 100644 index 000000000..bc46306f7 Binary files /dev/null and b/examples/runtime/shaders/gles/cs_update_instances.bin differ diff --git a/examples/runtime/shaders/gles/fs_particle.bin b/examples/runtime/shaders/gles/fs_particle.bin new file mode 100644 index 000000000..a35ea3a58 Binary files /dev/null and b/examples/runtime/shaders/gles/fs_particle.bin differ diff --git a/examples/runtime/shaders/gles/vs_particle.bin b/examples/runtime/shaders/gles/vs_particle.bin new file mode 100644 index 000000000..586ce9774 Binary files /dev/null and b/examples/runtime/shaders/gles/vs_particle.bin differ diff --git a/examples/runtime/shaders/glsl/cs_init_instances.bin b/examples/runtime/shaders/glsl/cs_init_instances.bin new file mode 100644 index 000000000..b8ea84ad3 Binary files /dev/null and b/examples/runtime/shaders/glsl/cs_init_instances.bin differ diff --git a/examples/runtime/shaders/glsl/cs_update_instances.bin b/examples/runtime/shaders/glsl/cs_update_instances.bin new file mode 100644 index 000000000..075db87eb Binary files /dev/null and b/examples/runtime/shaders/glsl/cs_update_instances.bin differ diff --git a/examples/runtime/shaders/glsl/fs_particle.bin b/examples/runtime/shaders/glsl/fs_particle.bin new file mode 100644 index 000000000..0140c3d89 Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_particle.bin differ diff --git a/examples/runtime/shaders/glsl/vs_particle.bin b/examples/runtime/shaders/glsl/vs_particle.bin new file mode 100644 index 000000000..39f9df50d Binary files /dev/null and b/examples/runtime/shaders/glsl/vs_particle.bin differ diff --git a/include/bgfx.h b/include/bgfx.h index d3d490b18..2d99a411b 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -14,7 +14,7 @@ /// #define BGFX_HANDLE(_name) \ struct _name { uint16_t idx; }; \ - inline bool isValid(_name _handle) { return bgfx::invalidHandle != _handle.idx; } + inline bool isValid(_name _handle) { return bgfx::invalidHandle != _handle.idx; } #define BGFX_INVALID_HANDLE { bgfx::invalidHandle } diff --git a/include/bgfxdefines.h b/include/bgfxdefines.h index 8c1666b8c..cbdca2774 100644 --- a/include/bgfxdefines.h +++ b/include/bgfxdefines.h @@ -198,6 +198,7 @@ #define BGFX_BUFFER_COMPUTE_NONE UINT8_C(0x00) #define BGFX_BUFFER_COMPUTE_READ UINT8_C(0x01) #define BGFX_BUFFER_COMPUTE_WRITE UINT8_C(0x02) +#define BGFX_BUFFER_COMPUTE_READ_WRITE (BGFX_BUFFER_COMPUTE_READ | BGFX_BUFFER_COMPUTE_WRITE) /// #define BGFX_TEXTURE_NONE UINT32_C(0x00000000) diff --git a/scripts/genie.lua b/scripts/genie.lua index 03b93e82a..10a79502f 100644 --- a/scripts/genie.lua +++ b/scripts/genie.lua @@ -310,6 +310,7 @@ exampleProject("20-nanovg") exampleProject("21-deferred") exampleProject("22-windows") exampleProject("23-vectordisplay") +exampleProject("24-nbody") if _OPTIONS["with-shared-lib"] then group "libs" diff --git a/scripts/shader.mk b/scripts/shader.mk index 2aa09a305..588c56a7c 100644 --- a/scripts/shader.mk +++ b/scripts/shader.mk @@ -26,7 +26,7 @@ else ifeq ($(TARGET), 1) VS_FLAGS=--platform windows -p vs_4_0 -O 3 FS_FLAGS=--platform windows -p ps_4_0 -O 3 -CS_FLAGS=--platform windows -p cs_5_0 -O 3 +CS_FLAGS=--platform windows -p cs_5_0 -O 1 SHADER_PATH=shaders/dx11 else ifeq ($(TARGET), 2) diff --git a/src/renderdoc.cpp b/src/renderdoc.cpp index c487eb1e6..ccf75b926 100644 --- a/src/renderdoc.cpp +++ b/src/renderdoc.cpp @@ -5,7 +5,7 @@ #include "bgfx_p.h" -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX) +#if BGFX_CONFIG_DEBUG_PIX && !BGFX_CONFIG_RENDERER_OPENGLES && (BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX) # if BX_PLATFORM_WINDOWS # include # endif // BX_PLATFORM_WINDOWS diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 4d360d8cb..b467375c6 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -40,6 +40,17 @@ namespace bgfx }; BX_STATIC_ASSERT(BX_COUNTOF(s_primInfo) == BX_COUNTOF(s_primName)+1); + union Zero + { + ID3D11Buffer* m_buffer[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11UnorderedAccessView* m_uav[D3D11_PS_CS_UAV_REGISTER_COUNT]; + ID3D11ShaderResourceView* m_srv[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11SamplerState* m_sampler[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + uint32_t m_zero[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + }; + + static Zero s_zero; + static const uint32_t s_checkMsaa[] = { 0, @@ -3161,13 +3172,14 @@ namespace bgfx { wasCompute = true; - ID3D11ShaderResourceView* srv[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; - deviceCtx->VSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, srv); - deviceCtx->PSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, srv); + deviceCtx->IASetVertexBuffers(0, 2, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero); + deviceCtx->IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0); - ID3D11SamplerState* sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; - deviceCtx->VSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, sampler); - deviceCtx->PSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, sampler); + deviceCtx->VSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, s_zero.m_srv); + deviceCtx->PSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, s_zero.m_srv); + + deviceCtx->VSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, s_zero.m_sampler); + deviceCtx->PSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, s_zero.m_sampler); } const RenderCompute& compute = renderItem.compute;