From b6d40fde97a4d2cafd4dd15bb8300cd62154484a Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 4 Nov 2018 21:24:38 -1000 Subject: [PATCH] Add startInst argument to drawInstanced --- .../boo/graphicsdev/IGraphicsCommandQueue.hpp | 4 +-- lib/graphicsdev/D3D11.cpp | 8 ++--- lib/graphicsdev/GL.cpp | 22 +++++++++---- lib/graphicsdev/Metal.mm | 32 +++++++++---------- lib/graphicsdev/Vulkan.cpp | 20 ++++++------ 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/include/boo/graphicsdev/IGraphicsCommandQueue.hpp b/include/boo/graphicsdev/IGraphicsCommandQueue.hpp index faede64..79a70e0 100644 --- a/include/boo/graphicsdev/IGraphicsCommandQueue.hpp +++ b/include/boo/graphicsdev/IGraphicsCommandQueue.hpp @@ -28,8 +28,8 @@ struct IGraphicsCommandQueue virtual void draw(size_t start, size_t count)=0; virtual void drawIndexed(size_t start, size_t count)=0; - virtual void drawInstances(size_t start, size_t count, size_t instCount)=0; - virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0; + virtual void drawInstances(size_t start, size_t count, size_t instCount, size_t startInst=0)=0; + virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst=0)=0; virtual void resolveBindTexture(const ObjToken& texture, const SWindowRect& rect, bool tlOrigin, int bindIdx, bool color, bool depth, bool clearDepth=false)=0; diff --git a/lib/graphicsdev/D3D11.cpp b/lib/graphicsdev/D3D11.cpp index dd6d90b..8a315c9 100644 --- a/lib/graphicsdev/D3D11.cpp +++ b/lib/graphicsdev/D3D11.cpp @@ -1171,14 +1171,14 @@ struct D3D11CommandQueue : IGraphicsCommandQueue m_deferredCtx->DrawIndexed(count, start, 0); } - void drawInstances(size_t start, size_t count, size_t instCount) + void drawInstances(size_t start, size_t count, size_t instCount, size_t startInst) { - m_deferredCtx->DrawInstanced(count, instCount, start, 0); + m_deferredCtx->DrawInstanced(count, instCount, start, startInst); } - void drawInstancesIndexed(size_t start, size_t count, size_t instCount) + void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst) { - m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0); + m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, startInst); } void _resolveBindTexture(ID3D11DeviceContext1* ctx, const D3D11TextureR* tex, const SWindowRect& rect, diff --git a/lib/graphicsdev/GL.cpp b/lib/graphicsdev/GL.cpp index 367b7f3..afceecd 100644 --- a/lib/graphicsdev/GL.cpp +++ b/lib/graphicsdev/GL.cpp @@ -1298,6 +1298,7 @@ struct GLCommandQueue : IGraphicsCommandQueue size_t start; size_t count; size_t instCount; + size_t startInst; }; }; ObjToken binding; @@ -1432,7 +1433,7 @@ struct GLCommandQueue : IGraphicsCommandQueue static void RenderingWorker(GLCommandQueue* self) { #if _WIN32 - std::string thrName = WCSTMBS(APP->getFriendlyName().data()) + " GL Rendering Thread"; + std::string thrName = WCSTMBS(APP->getFriendlyName().data()) + " Render"; #else std::string thrName = std::string(APP->getFriendlyName()) + " Render"; #endif @@ -1555,11 +1556,18 @@ struct GLCommandQueue : IGraphicsCommandQueue reinterpret_cast(cmd.start * 4)); break; case Command::Op::DrawInstances: - glDrawArraysInstanced(currentPrim, cmd.start, cmd.count, cmd.instCount); + if (cmd.startInst) + glDrawArraysInstancedBaseInstance(currentPrim, cmd.start, cmd.count, cmd.instCount, cmd.startInst); + else + glDrawArraysInstanced(currentPrim, cmd.start, cmd.count, cmd.instCount); break; case Command::Op::DrawInstancesIndexed: - glDrawElementsInstanced(currentPrim, cmd.count, GL_UNSIGNED_INT, - reinterpret_cast(cmd.start * 4), cmd.instCount); + if (cmd.startInst) + glDrawElementsInstancedBaseInstance(currentPrim, cmd.count, GL_UNSIGNED_INT, + reinterpret_cast(cmd.start * 4), cmd.instCount, cmd.startInst); + else + glDrawElementsInstanced(currentPrim, cmd.count, GL_UNSIGNED_INT, + reinterpret_cast(cmd.start * 4), cmd.instCount); break; case Command::Op::ResolveBindTexture: { @@ -1777,22 +1785,24 @@ struct GLCommandQueue : IGraphicsCommandQueue cmds.back().count = count; } - void drawInstances(size_t start, size_t count, size_t instCount) + void drawInstances(size_t start, size_t count, size_t instCount, size_t startInst) { std::vector& cmds = m_cmdBufs[m_fillBuf]; cmds.emplace_back(Command::Op::DrawInstances); cmds.back().start = start; cmds.back().count = count; cmds.back().instCount = instCount; + cmds.back().startInst = startInst; } - void drawInstancesIndexed(size_t start, size_t count, size_t instCount) + void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst) { std::vector& cmds = m_cmdBufs[m_fillBuf]; cmds.emplace_back(Command::Op::DrawInstancesIndexed); cmds.back().start = start; cmds.back().count = count; cmds.back().instCount = instCount; + cmds.back().startInst = startInst; } void resolveBindTexture(const ObjToken& texture, const SWindowRect& rect, bool tlOrigin, diff --git a/lib/graphicsdev/Metal.mm b/lib/graphicsdev/Metal.mm index 402ebfa..3e6dac4 100644 --- a/lib/graphicsdev/Metal.mm +++ b/lib/graphicsdev/Metal.mm @@ -826,8 +826,8 @@ protected: virtual void draw(MetalCommandQueue& q, size_t start, size_t count); virtual void drawIndexed(MetalCommandQueue& q, size_t start, size_t count); - virtual void drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount); - virtual void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount); + virtual void drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst); + virtual void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst); void setup(MetalContext* ctx, NSUInteger targetSamples, @@ -983,8 +983,8 @@ class MetalTessellationShaderPipeline : public MetalShaderPipeline void draw(MetalCommandQueue& q, size_t start, size_t count); void drawIndexed(MetalCommandQueue& q, size_t start, size_t count); - void drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount); - void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount); + void drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst); + void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst); public: id m_computeState; @@ -1346,14 +1346,14 @@ struct MetalCommandQueue : IGraphicsCommandQueue m_boundData->m_pipeline.cast()->drawIndexed(*this, start, count); } - void drawInstances(size_t start, size_t count, size_t instCount) + void drawInstances(size_t start, size_t count, size_t instCount, size_t startInst) { - m_boundData->m_pipeline.cast()->drawInstances(*this, start, count, instCount); + m_boundData->m_pipeline.cast()->drawInstances(*this, start, count, instCount, startInst); } - void drawInstancesIndexed(size_t start, size_t count, size_t instCount) + void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst) { - m_boundData->m_pipeline.cast()->drawInstancesIndexed(*this, start, count, instCount); + m_boundData->m_pipeline.cast()->drawInstancesIndexed(*this, start, count, instCount, startInst); } void _resolveBindTexture(MetalTextureR* tex, const SWindowRect& rect, bool tlOrigin, @@ -1654,16 +1654,16 @@ void MetalShaderPipeline::drawIndexed(MetalCommandQueue& q, size_t start, size_t baseInstance:0]; } -void MetalShaderPipeline::drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount) +void MetalShaderPipeline::drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst) { [q.m_enc drawPrimitives:m_drawPrim vertexStart:start + q.m_boundData->m_baseVert vertexCount:count instanceCount:instCount - baseInstance:q.m_boundData->m_baseInst]; + baseInstance:startInst + q.m_boundData->m_baseInst]; } -void MetalShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount) +void MetalShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst) { [q.m_enc drawIndexedPrimitives:m_drawPrim indexCount:count @@ -1672,7 +1672,7 @@ void MetalShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t star indexBufferOffset:start*4 instanceCount:instCount baseVertex:q.m_boundData->m_baseVert - baseInstance:q.m_boundData->m_baseInst]; + baseInstance:startInst + q.m_boundData->m_baseInst]; } void MetalTessellationShaderPipeline::draw(MetalCommandQueue& q, size_t start, size_t count) @@ -1701,7 +1701,7 @@ void MetalTessellationShaderPipeline::drawIndexed(MetalCommandQueue& q, size_t s baseInstance:0]; } -void MetalTessellationShaderPipeline::drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount) +void MetalTessellationShaderPipeline::drawInstances(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst) { q.dispatchTessKernel(m_computeState, start, count, m_patchSize); [q.m_enc drawPatches:m_patchSize @@ -1710,10 +1710,10 @@ void MetalTessellationShaderPipeline::drawInstances(MetalCommandQueue& q, size_t patchIndexBuffer:nullptr patchIndexBufferOffset:0 instanceCount:instCount - baseInstance:0]; + baseInstance:startInst]; } -void MetalTessellationShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount) +void MetalTessellationShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst) { q.dispatchTessKernel(m_computeState, start, count, m_patchSize); [q.m_enc drawIndexedPatches:m_patchSize @@ -1724,7 +1724,7 @@ void MetalTessellationShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, controlPointIndexBuffer:GetBufferGPUResource(q.m_boundData->m_ibuf, q.m_fillBuf) controlPointIndexBufferOffset:start*4 instanceCount:instCount - baseInstance:0]; + baseInstance:startInst]; } MetalDataFactory::Context::Context(MetalDataFactory& parent __BooTraceArgs) diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 1e484d7..7f74419 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -1276,6 +1276,9 @@ public: VkDeviceSize sizeForGPU(VulkanContext* ctx, VkDeviceSize offset) { + m_bufferInfo.offset = offset; + offset += m_sz; + if (m_use == BufferUse::Uniform) { size_t minOffset = std::max(VkDeviceSize(256), @@ -1283,9 +1286,6 @@ public: offset = (offset + minOffset - 1) & ~(minOffset - 1); } - m_bufferInfo.offset = offset; - offset += m_sz; - return offset; } @@ -1329,15 +1329,15 @@ public: { for (int i=0 ; i<2 ; ++i) { + m_bufferInfo[i].offset = offset; + offset += m_cpuSz; + if (m_use == BufferUse::Uniform) { size_t minOffset = std::max(VkDeviceSize(256), ctx->m_gpuProps.limits.minUniformBufferOffsetAlignment); offset = (offset + minOffset - 1) & ~(minOffset - 1); } - - m_bufferInfo[i].offset = offset; - offset += m_cpuSz; } return offset; @@ -3060,14 +3060,14 @@ struct VulkanCommandQueue : IGraphicsCommandQueue vk::CmdDrawIndexed(m_cmdBufs[m_fillBuf], count, 1, start, 0, 0); } - void drawInstances(size_t start, size_t count, size_t instCount) + void drawInstances(size_t start, size_t count, size_t instCount, size_t startInst) { - vk::CmdDraw(m_cmdBufs[m_fillBuf], count, instCount, start, 0); + vk::CmdDraw(m_cmdBufs[m_fillBuf], count, instCount, start, startInst); } - void drawInstancesIndexed(size_t start, size_t count, size_t instCount) + void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst) { - vk::CmdDrawIndexed(m_cmdBufs[m_fillBuf], count, instCount, start, 0, 0); + vk::CmdDrawIndexed(m_cmdBufs[m_fillBuf], count, instCount, start, 0, startInst); } boo::ObjToken m_resolveDispSource;