Commit 48b3587f by Chris Forbes

Implement indirect draws

Bug: b/118619338 Test: dEQP-VK.draw.* Change-Id: I282c0f1e8f44b0bec2318ab901ec511413bff11d Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27888Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 4aa9bf12
...@@ -268,20 +268,22 @@ void CommandBuffer::ExecutionState::bindAttachments() ...@@ -268,20 +268,22 @@ void CommandBuffer::ExecutionState::bindAttachments()
} }
} }
struct Draw : public CommandBuffer::Command struct DrawBase : public CommandBuffer::Command
{ {
Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) int bytesPerIndex(CommandBuffer::ExecutionState const& executionState)
: vertexCount(vertexCount), instanceCount(instanceCount), firstVertex(firstVertex), firstInstance(firstInstance)
{ {
return executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4;
} }
void play(CommandBuffer::ExecutionState& executionState) override void draw(CommandBuffer::ExecutionState& executionState, bool indexed,
uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
{ {
GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>( GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(
executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]); executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]);
sw::Context context = pipeline->getContext(); sw::Context context = pipeline->getContext();
executionState.bindVertexInputs(context, firstVertex, firstInstance);
executionState.bindVertexInputs(context, vertexOffset, firstInstance);
const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS]; const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS];
for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++) for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
...@@ -290,6 +292,16 @@ struct Draw : public CommandBuffer::Command ...@@ -290,6 +292,16 @@ struct Draw : public CommandBuffer::Command
} }
context.pushConstants = executionState.pushConstants; context.pushConstants = executionState.pushConstants;
auto drawType = context.drawType;
if (indexed)
{
context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
drawType = static_cast<sw::DrawType>(executionState.indexType == VK_INDEX_TYPE_UINT16
? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32));
}
executionState.renderer->setContext(context); executionState.renderer->setContext(context);
executionState.renderer->setScissor(pipeline->getScissor()); executionState.renderer->setScissor(pipeline->getScissor());
...@@ -298,14 +310,27 @@ struct Draw : public CommandBuffer::Command ...@@ -298,14 +310,27 @@ struct Draw : public CommandBuffer::Command
executionState.bindAttachments(); executionState.bindAttachments();
const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount); const uint32_t primitiveCount = pipeline->computePrimitiveCount(count);
for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++) for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
{ {
executionState.renderer->setInstanceID(instance); executionState.renderer->setInstanceID(instance);
executionState.renderer->draw(context.drawType, primitiveCount); executionState.renderer->draw(drawType, primitiveCount);
executionState.renderer->advanceInstanceAttributes(); executionState.renderer->advanceInstanceAttributes();
} }
} }
};
struct Draw : public DrawBase
{
Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
: vertexCount(vertexCount), instanceCount(instanceCount), firstVertex(firstVertex), firstInstance(firstInstance)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
draw(executionState, false, vertexCount, instanceCount, 0, firstVertex, firstInstance);
}
uint32_t vertexCount; uint32_t vertexCount;
uint32_t instanceCount; uint32_t instanceCount;
...@@ -313,7 +338,7 @@ struct Draw : public CommandBuffer::Command ...@@ -313,7 +338,7 @@ struct Draw : public CommandBuffer::Command
uint32_t firstInstance; uint32_t firstInstance;
}; };
struct DrawIndexed : public CommandBuffer::Command struct DrawIndexed : public DrawBase
{ {
DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
: indexCount(indexCount), instanceCount(instanceCount), firstIndex(firstIndex), vertexOffset(vertexOffset), firstInstance(firstInstance) : indexCount(indexCount), instanceCount(instanceCount), firstIndex(firstIndex), vertexOffset(vertexOffset), firstInstance(firstInstance)
...@@ -322,48 +347,58 @@ struct DrawIndexed : public CommandBuffer::Command ...@@ -322,48 +347,58 @@ struct DrawIndexed : public CommandBuffer::Command
void play(CommandBuffer::ExecutionState& executionState) override void play(CommandBuffer::ExecutionState& executionState) override
{ {
GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>( draw(executionState, true, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]); }
sw::Context context = pipeline->getContext();
executionState.bindVertexInputs(context, vertexOffset, firstInstance); uint32_t indexCount;
uint32_t instanceCount;
uint32_t firstIndex;
int32_t vertexOffset;
uint32_t firstInstance;
};
const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS]; struct DrawIndirect : public DrawBase
for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++) {
DrawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
: buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
{ {
context.descriptorSets[i] = reinterpret_cast<vk::DescriptorSet*>(boundDescriptorSets[i]);
} }
context.pushConstants = executionState.pushConstants; void play(CommandBuffer::ExecutionState& executionState) override
{
context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer( for (auto drawId = 0u; drawId < drawCount; drawId++)
executionState.indexBufferBinding.offset + firstIndex * (executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4)); {
auto cmd = reinterpret_cast<VkDrawIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
executionState.renderer->setContext(context); draw(executionState, false, cmd->vertexCount, cmd->instanceCount, 0, cmd->firstVertex, cmd->firstInstance);
executionState.renderer->setScissor(pipeline->getScissor()); }
executionState.renderer->setViewport(pipeline->getViewport()); }
executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
executionState.bindAttachments(); VkBuffer buffer;
VkDeviceSize offset;
uint32_t drawCount;
uint32_t stride;
};
auto drawType = executionState.indexType == VK_INDEX_TYPE_UINT16 struct DrawIndexedIndirect : public DrawBase
? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32); {
DrawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
: buffer(buffer), offset(offset), drawCount(drawCount), stride(stride)
{
}
const uint32_t primitiveCount = pipeline->computePrimitiveCount(indexCount); void play(CommandBuffer::ExecutionState& executionState) override
for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
{ {
executionState.renderer->setInstanceID(instance); for (auto drawId = 0u; drawId < drawCount; drawId++)
executionState.renderer->draw(static_cast<sw::DrawType>(drawType), primitiveCount); {
executionState.renderer->advanceInstanceAttributes(); auto cmd = reinterpret_cast<VkDrawIndexedIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset + drawId * stride));
draw(executionState, true, cmd->indexCount, cmd->instanceCount, cmd->firstIndex, cmd->vertexOffset, cmd->firstInstance);
} }
} }
uint32_t indexCount; VkBuffer buffer;
uint32_t instanceCount; VkDeviceSize offset;
uint32_t firstIndex; uint32_t drawCount;
int32_t vertexOffset; uint32_t stride;
uint32_t firstInstance;
}; };
struct ImageToImageCopy : public CommandBuffer::Command struct ImageToImageCopy : public CommandBuffer::Command
...@@ -1110,12 +1145,12 @@ void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uin ...@@ -1110,12 +1145,12 @@ void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uin
void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride) void CommandBuffer::drawIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
{ {
UNIMPLEMENTED("drawIndirect"); addCommand<DrawIndirect>(buffer, offset, drawCount, stride);
} }
void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride) void CommandBuffer::drawIndexedIndirect(VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
{ {
UNIMPLEMENTED("drawIndexedIndirect"); addCommand<DrawIndexedIndirect>(buffer, offset, drawCount, stride);
} }
void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState) void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment