Add startInst argument to drawInstanced

This commit is contained in:
Jack Andersen 2018-11-04 21:24:38 -10:00
parent 3b4d7abae6
commit b6d40fde97
5 changed files with 48 additions and 38 deletions

View File

@ -28,8 +28,8 @@ struct IGraphicsCommandQueue
virtual void draw(size_t start, size_t count)=0; virtual void draw(size_t start, size_t count)=0;
virtual void drawIndexed(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 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)=0; virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount, size_t startInst=0)=0;
virtual void resolveBindTexture(const ObjToken<ITextureR>& texture, const SWindowRect& rect, virtual void resolveBindTexture(const ObjToken<ITextureR>& texture, const SWindowRect& rect,
bool tlOrigin, int bindIdx, bool color, bool depth, bool clearDepth=false)=0; bool tlOrigin, int bindIdx, bool color, bool depth, bool clearDepth=false)=0;

View File

@ -1171,14 +1171,14 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
m_deferredCtx->DrawIndexed(count, start, 0); 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, void _resolveBindTexture(ID3D11DeviceContext1* ctx, const D3D11TextureR* tex, const SWindowRect& rect,

View File

@ -1298,6 +1298,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
size_t start; size_t start;
size_t count; size_t count;
size_t instCount; size_t instCount;
size_t startInst;
}; };
}; };
ObjToken<IShaderDataBinding> binding; ObjToken<IShaderDataBinding> binding;
@ -1432,7 +1433,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
static void RenderingWorker(GLCommandQueue* self) static void RenderingWorker(GLCommandQueue* self)
{ {
#if _WIN32 #if _WIN32
std::string thrName = WCSTMBS(APP->getFriendlyName().data()) + " GL Rendering Thread"; std::string thrName = WCSTMBS(APP->getFriendlyName().data()) + " Render";
#else #else
std::string thrName = std::string(APP->getFriendlyName()) + " Render"; std::string thrName = std::string(APP->getFriendlyName()) + " Render";
#endif #endif
@ -1555,11 +1556,18 @@ struct GLCommandQueue : IGraphicsCommandQueue
reinterpret_cast<void*>(cmd.start * 4)); reinterpret_cast<void*>(cmd.start * 4));
break; break;
case Command::Op::DrawInstances: 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; break;
case Command::Op::DrawInstancesIndexed: case Command::Op::DrawInstancesIndexed:
glDrawElementsInstanced(currentPrim, cmd.count, GL_UNSIGNED_INT, if (cmd.startInst)
reinterpret_cast<void*>(cmd.start * 4), cmd.instCount); glDrawElementsInstancedBaseInstance(currentPrim, cmd.count, GL_UNSIGNED_INT,
reinterpret_cast<void*>(cmd.start * 4), cmd.instCount, cmd.startInst);
else
glDrawElementsInstanced(currentPrim, cmd.count, GL_UNSIGNED_INT,
reinterpret_cast<void*>(cmd.start * 4), cmd.instCount);
break; break;
case Command::Op::ResolveBindTexture: case Command::Op::ResolveBindTexture:
{ {
@ -1777,22 +1785,24 @@ struct GLCommandQueue : IGraphicsCommandQueue
cmds.back().count = count; 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<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::Op::DrawInstances); cmds.emplace_back(Command::Op::DrawInstances);
cmds.back().start = start; cmds.back().start = start;
cmds.back().count = count; cmds.back().count = count;
cmds.back().instCount = instCount; 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<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::Op::DrawInstancesIndexed); cmds.emplace_back(Command::Op::DrawInstancesIndexed);
cmds.back().start = start; cmds.back().start = start;
cmds.back().count = count; cmds.back().count = count;
cmds.back().instCount = instCount; cmds.back().instCount = instCount;
cmds.back().startInst = startInst;
} }
void resolveBindTexture(const ObjToken<ITextureR>& texture, const SWindowRect& rect, bool tlOrigin, void resolveBindTexture(const ObjToken<ITextureR>& texture, const SWindowRect& rect, bool tlOrigin,

View File

@ -826,8 +826,8 @@ protected:
virtual void draw(MetalCommandQueue& q, size_t start, size_t count); virtual void draw(MetalCommandQueue& q, size_t start, size_t count);
virtual void drawIndexed(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 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); virtual void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst);
void setup(MetalContext* ctx, void setup(MetalContext* ctx,
NSUInteger targetSamples, NSUInteger targetSamples,
@ -983,8 +983,8 @@ class MetalTessellationShaderPipeline : public MetalShaderPipeline
void draw(MetalCommandQueue& q, size_t start, size_t count); void draw(MetalCommandQueue& q, size_t start, size_t count);
void drawIndexed(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 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); void drawInstancesIndexed(MetalCommandQueue& q, size_t start, size_t count, size_t instCount, size_t startInst);
public: public:
id<MTLComputePipelineState> m_computeState; id<MTLComputePipelineState> m_computeState;
@ -1346,14 +1346,14 @@ struct MetalCommandQueue : IGraphicsCommandQueue
m_boundData->m_pipeline.cast<MetalShaderPipeline>()->drawIndexed(*this, start, count); m_boundData->m_pipeline.cast<MetalShaderPipeline>()->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<MetalShaderPipeline>()->drawInstances(*this, start, count, instCount); m_boundData->m_pipeline.cast<MetalShaderPipeline>()->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<MetalShaderPipeline>()->drawInstancesIndexed(*this, start, count, instCount); m_boundData->m_pipeline.cast<MetalShaderPipeline>()->drawInstancesIndexed(*this, start, count, instCount, startInst);
} }
void _resolveBindTexture(MetalTextureR* tex, const SWindowRect& rect, bool tlOrigin, 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]; 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 [q.m_enc drawPrimitives:m_drawPrim
vertexStart:start + q.m_boundData->m_baseVert vertexStart:start + q.m_boundData->m_baseVert
vertexCount:count vertexCount:count
instanceCount:instCount 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 [q.m_enc drawIndexedPrimitives:m_drawPrim
indexCount:count indexCount:count
@ -1672,7 +1672,7 @@ void MetalShaderPipeline::drawInstancesIndexed(MetalCommandQueue& q, size_t star
indexBufferOffset:start*4 indexBufferOffset:start*4
instanceCount:instCount instanceCount:instCount
baseVertex:q.m_boundData->m_baseVert 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) 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]; 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.dispatchTessKernel(m_computeState, start, count, m_patchSize);
[q.m_enc drawPatches:m_patchSize [q.m_enc drawPatches:m_patchSize
@ -1710,10 +1710,10 @@ void MetalTessellationShaderPipeline::drawInstances(MetalCommandQueue& q, size_t
patchIndexBuffer:nullptr patchIndexBuffer:nullptr
patchIndexBufferOffset:0 patchIndexBufferOffset:0
instanceCount:instCount 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.dispatchTessKernel(m_computeState, start, count, m_patchSize);
[q.m_enc drawIndexedPatches: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) controlPointIndexBuffer:GetBufferGPUResource(q.m_boundData->m_ibuf, q.m_fillBuf)
controlPointIndexBufferOffset:start*4 controlPointIndexBufferOffset:start*4
instanceCount:instCount instanceCount:instCount
baseInstance:0]; baseInstance:startInst];
} }
MetalDataFactory::Context::Context(MetalDataFactory& parent __BooTraceArgs) MetalDataFactory::Context::Context(MetalDataFactory& parent __BooTraceArgs)

View File

@ -1276,6 +1276,9 @@ public:
VkDeviceSize sizeForGPU(VulkanContext* ctx, VkDeviceSize offset) VkDeviceSize sizeForGPU(VulkanContext* ctx, VkDeviceSize offset)
{ {
m_bufferInfo.offset = offset;
offset += m_sz;
if (m_use == BufferUse::Uniform) if (m_use == BufferUse::Uniform)
{ {
size_t minOffset = std::max(VkDeviceSize(256), size_t minOffset = std::max(VkDeviceSize(256),
@ -1283,9 +1286,6 @@ public:
offset = (offset + minOffset - 1) & ~(minOffset - 1); offset = (offset + minOffset - 1) & ~(minOffset - 1);
} }
m_bufferInfo.offset = offset;
offset += m_sz;
return offset; return offset;
} }
@ -1329,15 +1329,15 @@ public:
{ {
for (int i=0 ; i<2 ; ++i) for (int i=0 ; i<2 ; ++i)
{ {
m_bufferInfo[i].offset = offset;
offset += m_cpuSz;
if (m_use == BufferUse::Uniform) if (m_use == BufferUse::Uniform)
{ {
size_t minOffset = std::max(VkDeviceSize(256), size_t minOffset = std::max(VkDeviceSize(256),
ctx->m_gpuProps.limits.minUniformBufferOffsetAlignment); ctx->m_gpuProps.limits.minUniformBufferOffsetAlignment);
offset = (offset + minOffset - 1) & ~(minOffset - 1); offset = (offset + minOffset - 1) & ~(minOffset - 1);
} }
m_bufferInfo[i].offset = offset;
offset += m_cpuSz;
} }
return offset; return offset;
@ -3060,14 +3060,14 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
vk::CmdDrawIndexed(m_cmdBufs[m_fillBuf], count, 1, start, 0, 0); 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<ITextureR> m_resolveDispSource; boo::ObjToken<ITextureR> m_resolveDispSource;