diff --git a/examples/48-drawindirect/drawindirect.cpp b/examples/48-drawindirect/drawindirect.cpp index 92151f94e..47a4a504e 100644 --- a/examples/48-drawindirect/drawindirect.cpp +++ b/examples/48-drawindirect/drawindirect.cpp @@ -181,6 +181,21 @@ public: bgfx::makeRef(s_multiMeshIndices, sizeof(s_multiMeshIndices) ) ); + // Dynamic index buffer (with padding) + m_dibhPad = bgfx::createDynamicIndexBuffer(64); + m_dibh = bgfx::createDynamicIndexBuffer( + bgfx::makeRef(s_multiMeshIndices, sizeof(s_multiMeshIndices) ) + ); + m_indexBufferType = 0; + + // Dynamic vertex buffer (with padding) + m_dvbhPad = bgfx::createDynamicVertexBuffer(32, PosColorVertex::ms_layout); + m_dvbh = bgfx::createDynamicVertexBuffer( + bgfx::makeRef(s_multiMeshVertices, sizeof(s_multiMeshVertices) ) + , PosColorVertex::ms_layout + ); + m_vertexBufferType = 0; + // Create program from shaders. m_program = loadProgram("vs_instancing", "fs_instancing"); // These are reused from 05-instancing @@ -261,6 +276,10 @@ public: // Cleanup. bgfx::destroy(m_ibh); + bgfx::destroy(m_dibh); + bgfx::destroy(m_dibhPad); + bgfx::destroy(m_dvbh); + bgfx::destroy(m_dvbhPad); bgfx::destroy(m_vbh); bgfx::destroy(m_program); @@ -347,6 +366,14 @@ public: ImGui::Text("Grid Side Size:"); ImGui::SliderInt("##size", (int32_t*)&m_sideSize, 1, kMaxSideSize); + ImGui::Text("Vertex Buffer:"); + const char* vbItems[] = { "Static", "Dynamic (non-zero base)", "Transient" }; + ImGui::Combo("##vbtype", &m_vertexBufferType, vbItems, BX_COUNTOF(vbItems) ); + + ImGui::Text("Index Buffer:"); + const char* ibItems[] = { "Static", "Dynamic (non-zero base)", "Transient" }; + ImGui::Combo("##ibtype", &m_indexBufferType, ibItems, BX_COUNTOF(ibItems) ); + ImGui::BeginDisabled(!indirectCountSupported); ImGui::Checkbox("Indirect Count", &m_useIndirectCount); ImGui::EndDisabled(); @@ -398,6 +425,21 @@ public: bgfx::setUniform(u_drawParams, ud); + bgfx::TransientIndexBuffer tib; + if (2 == m_indexBufferType) + { + bgfx::allocTransientIndexBuffer(&tib, BX_COUNTOF(s_multiMeshIndices) ); + bx::memCopy(tib.data, s_multiMeshIndices, sizeof(s_multiMeshIndices) ); + } + + switch (m_indexBufferType) + { + default: + case 0: bgfx::setIndexBuffer(m_ibh); break; // Static - base 0. + case 1: bgfx::setIndexBuffer(m_dibh); break; // Dynamic - non-zero pool base. + case 2: bgfx::setIndexBuffer(&tib); break; // Transient - non-zero per-frame base. + } + bgfx::setBuffer(0, m_objectListBuffer, bgfx::Access::Read); bgfx::setBuffer(1, m_indirectBuffer, bgfx::Access::Write); bgfx::setBuffer(2, m_instanceBuffer, bgfx::Access::Write); @@ -414,10 +456,28 @@ public: bgfx::dispatch(0, m_indirectProgram, uint32_t(numToDraw/64 + 1), 1, 1); } - // Submit our 1 draw call - // Set vertex and index buffer. - bgfx::setIndexBuffer(m_ibh); - bgfx::setVertexBuffer(0, m_vbh); + // Submit our 1 draw call. Re-bind the same index buffer for the draw. + switch (m_indexBufferType) + { + default: + case 0: bgfx::setIndexBuffer(m_ibh); break; + case 1: bgfx::setIndexBuffer(m_dibh); break; + case 2: bgfx::setIndexBuffer(&tib); break; + } + + bgfx::TransientVertexBuffer tvb; + switch (m_vertexBufferType) + { + default: + case 0: bgfx::setVertexBuffer(0, m_vbh); break; // Static - base 0. + case 1: bgfx::setVertexBuffer(0, m_dvbh); break; // Dynamic - non-zero pool base. + case 2: // Transient - non-zero per-frame base. + bgfx::allocTransientVertexBuffer(&tvb, BX_COUNTOF(s_multiMeshVertices), PosColorVertex::ms_layout); + bx::memCopy(tvb.data, s_multiMeshVertices, sizeof(s_multiMeshVertices) ); + bgfx::setVertexBuffer(0, &tvb); + break; + } + bgfx::setInstanceDataBuffer(m_instanceBuffer, 0, numToDraw); // Set render states. @@ -463,6 +523,12 @@ public: bgfx::VertexBufferHandle m_vbh; bgfx::IndexBufferHandle m_ibh; + bgfx::DynamicIndexBufferHandle m_dibhPad; + bgfx::DynamicIndexBufferHandle m_dibh; + bgfx::DynamicVertexBufferHandle m_dvbhPad; + bgfx::DynamicVertexBufferHandle m_dvbh; + int32_t m_indexBufferType; + int32_t m_vertexBufferType; bgfx::ProgramHandle m_program; bgfx::ProgramHandle m_indirectProgram; bgfx::ProgramHandle m_indirectCountProgram; diff --git a/examples/runtime/shaders/dxbc/cs_drawindirect.bin b/examples/runtime/shaders/dxbc/cs_drawindirect.bin index 5df326d70..d3f62e55f 100755 Binary files a/examples/runtime/shaders/dxbc/cs_drawindirect.bin and b/examples/runtime/shaders/dxbc/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/dxbc/cs_drawindirect_count.bin b/examples/runtime/shaders/dxbc/cs_drawindirect_count.bin index 33deac008..d5650ad52 100644 Binary files a/examples/runtime/shaders/dxbc/cs_drawindirect_count.bin and b/examples/runtime/shaders/dxbc/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/dxil/cs_drawindirect.bin b/examples/runtime/shaders/dxil/cs_drawindirect.bin index e3eb53132..6c182aa49 100644 Binary files a/examples/runtime/shaders/dxil/cs_drawindirect.bin and b/examples/runtime/shaders/dxil/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/dxil/cs_drawindirect_count.bin b/examples/runtime/shaders/dxil/cs_drawindirect_count.bin index dadaf624b..97a1fb961 100644 Binary files a/examples/runtime/shaders/dxil/cs_drawindirect_count.bin and b/examples/runtime/shaders/dxil/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/essl/cs_drawindirect.bin b/examples/runtime/shaders/essl/cs_drawindirect.bin index 832f57406..e83dde192 100755 Binary files a/examples/runtime/shaders/essl/cs_drawindirect.bin and b/examples/runtime/shaders/essl/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/essl/cs_drawindirect_count.bin b/examples/runtime/shaders/essl/cs_drawindirect_count.bin index 93f66172b..2840c90e8 100644 Binary files a/examples/runtime/shaders/essl/cs_drawindirect_count.bin and b/examples/runtime/shaders/essl/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/glsl/cs_drawindirect.bin b/examples/runtime/shaders/glsl/cs_drawindirect.bin index be4db3aa6..7c75743cb 100755 Binary files a/examples/runtime/shaders/glsl/cs_drawindirect.bin and b/examples/runtime/shaders/glsl/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/glsl/cs_drawindirect_count.bin b/examples/runtime/shaders/glsl/cs_drawindirect_count.bin index 91c44b053..0c6bbf4b9 100644 Binary files a/examples/runtime/shaders/glsl/cs_drawindirect_count.bin and b/examples/runtime/shaders/glsl/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/metal/cs_drawindirect.bin b/examples/runtime/shaders/metal/cs_drawindirect.bin index 43ea8d1aa..a66390b63 100755 Binary files a/examples/runtime/shaders/metal/cs_drawindirect.bin and b/examples/runtime/shaders/metal/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/metal/cs_drawindirect_count.bin b/examples/runtime/shaders/metal/cs_drawindirect_count.bin index c2e26ea86..1a7d69aca 100644 Binary files a/examples/runtime/shaders/metal/cs_drawindirect_count.bin and b/examples/runtime/shaders/metal/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/spirv/cs_drawindirect.bin b/examples/runtime/shaders/spirv/cs_drawindirect.bin index 7564aa1cb..66cee23b3 100755 Binary files a/examples/runtime/shaders/spirv/cs_drawindirect.bin and b/examples/runtime/shaders/spirv/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/spirv/cs_drawindirect_count.bin b/examples/runtime/shaders/spirv/cs_drawindirect_count.bin index e225be9da..90f0cf67b 100644 Binary files a/examples/runtime/shaders/spirv/cs_drawindirect_count.bin and b/examples/runtime/shaders/spirv/cs_drawindirect_count.bin differ diff --git a/examples/runtime/shaders/wgsl/cs_drawindirect.bin b/examples/runtime/shaders/wgsl/cs_drawindirect.bin index 4d08559fb..1d331343d 100644 Binary files a/examples/runtime/shaders/wgsl/cs_drawindirect.bin and b/examples/runtime/shaders/wgsl/cs_drawindirect.bin differ diff --git a/examples/runtime/shaders/wgsl/cs_drawindirect_count.bin b/examples/runtime/shaders/wgsl/cs_drawindirect_count.bin index 6538b24ec..76ba277b6 100644 Binary files a/examples/runtime/shaders/wgsl/cs_drawindirect_count.bin and b/examples/runtime/shaders/wgsl/cs_drawindirect_count.bin differ diff --git a/src/bgfx.cpp b/src/bgfx.cpp index a46d25ab1..92201b990 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1257,6 +1257,7 @@ namespace bgfx "u_invModelView", "u_modelViewProj", "u_alphaRef4", + "bgfx_indirectArgBase", }; const char* getPredefinedUniformName(PredefinedUniform::Enum _enum) @@ -1626,6 +1627,7 @@ namespace bgfx m_compute.m_startMatrix = m_draw.m_startMatrix; m_compute.m_numMatrices = m_draw.m_numMatrices; + m_compute.m_startIndex = m_draw.m_startIndex; m_compute.m_numX = bx::max(_numX, 1u); m_compute.m_numY = bx::max(_numY, 1u); m_compute.m_numZ = bx::max(_numZ, 1u); diff --git a/src/bgfx_compute.sh b/src/bgfx_compute.sh index 99d1ac422..e9c8fab4e 100644 --- a/src/bgfx_compute.sh +++ b/src/bgfx_compute.sh @@ -316,6 +316,8 @@ __IMAGE_IMPL_ATOMIC(uint, x, uvec4, xxxx) ) \ _buffer[(_offset)*2+0] = uvec4(_numVertices, _numInstances, _startVertex, _startInstance) +uniform vec4 bgfx_indirectArgBase; + #define drawIndexedIndirect( \ _buffer \ , _offset \ @@ -325,7 +327,7 @@ __IMAGE_IMPL_ATOMIC(uint, x, uvec4, xxxx) , _startVertex \ , _startInstance \ ) \ - _buffer[(_offset)*2+0] = uvec4(_numIndices, _numInstances, _startIndex, _startVertex); \ + _buffer[(_offset)*2+0] = uvec4(_numIndices, _numInstances, floatBitsToUint(bgfx_indirectArgBase.x) + uint(_startIndex), _startVertex); \ _buffer[(_offset)*2+1] = uvec4(_startInstance, 0u, 0u, 0u) #endif // __cplusplus diff --git a/src/bgfx_p.h b/src/bgfx_p.h index ec46641f0..86e2539c1 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -978,6 +978,8 @@ namespace bgfx InvModelView, ModelViewProj, AlphaRef, + IndirectArgBase, + Count }; @@ -2161,11 +2163,13 @@ namespace bgfx m_startIndirect = 0; m_numIndirect = UINT32_MAX; m_bindIdx = 0; + m_startIndex = 0; } uint32_t m_uniformBegin; uint32_t m_uniformEnd; uint32_t m_startMatrix; + uint32_t m_startIndex; IndirectBufferHandle m_indirectBuffer; uint32_t m_numX; diff --git a/src/renderer.h b/src/renderer.h index 784b13569..81cbcfbfb 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -316,6 +316,17 @@ namespace bgfx } break; + case PredefinedUniform::IndirectArgBase: + { + const float base[4] = { bx::bitsToFloat(_draw.m_startIndex), 0.0f, 0.0f, 0.0f }; + _renderer->setShaderUniform4f(flags + , predefined.m_loc + , base + , 1 + ); + } + break; + default: BX_ASSERT(false, "predefined %d not handled", predefined.m_type); break; diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 9eaae3500..70b70155d 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -357,6 +357,7 @@ namespace bgfx { namespace wgpu static const char* s_adapterType[] = { + /* WGPUAdapterType starts from 1 */ NULL, "DiscreteGPU", "IntegratedGPU", "CPU", diff --git a/src/renderer_webgpu.h b/src/renderer_webgpu.h index dabb0eff9..5683d733b 100644 --- a/src/renderer_webgpu.h +++ b/src/renderer_webgpu.h @@ -224,8 +224,8 @@ WGPU_IMPORT_FUNC(false, RenderPassEncoderEndOcclusionQuery); \ WGPU_IGNORE_____(false, RenderPassEncoderExecuteBundles); \ WGPU_IMPORT_FUNC(false, RenderPassEncoderInsertDebugMarker); \ - WGPU_IMPORT_FUNC(false, RenderPassEncoderMultiDrawIndexedIndirect); \ - WGPU_IMPORT_FUNC(false, RenderPassEncoderMultiDrawIndirect); \ + WGPU_IGNORE_____(false, RenderPassEncoderMultiDrawIndexedIndirect); \ + WGPU_IGNORE_____(false, RenderPassEncoderMultiDrawIndirect); \ WGPU_IGNORE_____(false, RenderPassEncoderPixelLocalStorageBarrier); \ WGPU_IMPORT_FUNC(false, RenderPassEncoderPopDebugGroup); \ WGPU_IMPORT_FUNC(false, RenderPassEncoderPushDebugGroup); \