Commit 7c8e276c by Courtney Goeltzenleuchter Committed by Commit Bot

Vulkan: Add support for DrawArraysIndirect

Add partial support for DrawArraysIndirect. This supports all primitives types except lineloop. Test: dEQP.GLES31/functional_draw_indirect_* Bug: angleproject:3564 Change-Id: I065417a848390070c9f116db6fd3f90c12fb3886 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1811873Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
parent 70d79b76
...@@ -460,10 +460,10 @@ angle::Result ContextVk::finish(const gl::Context *context) ...@@ -460,10 +460,10 @@ angle::Result ContextVk::finish(const gl::Context *context)
angle::Result ContextVk::setupDraw(const gl::Context *context, angle::Result ContextVk::setupDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint firstVertex, GLint firstVertexOrInvalid,
GLsizei vertexOrIndexCount, GLsizei vertexOrIndexCount,
GLsizei instanceCount, GLsizei instanceCount,
gl::DrawElementsType indexTypeOrNone, gl::DrawElementsType indexTypeOrInvalid,
const void *indices, const void *indices,
DirtyBits dirtyBitMask, DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut) vk::CommandBuffer **commandBufferOut)
...@@ -479,8 +479,10 @@ angle::Result ContextVk::setupDraw(const gl::Context *context, ...@@ -479,8 +479,10 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
// Must be called before the command buffer is started. Can call finish. // Must be called before the command buffer is started. Can call finish.
if (context->getStateCache().hasAnyActiveClientAttrib()) if (context->getStateCache().hasAnyActiveClientAttrib())
{ {
ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertex, vertexOrIndexCount, ASSERT(firstVertexOrInvalid != -1);
instanceCount, indexTypeOrNone, indices)); ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertexOrInvalid,
vertexOrIndexCount, instanceCount,
indexTypeOrInvalid, indices));
mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
} }
...@@ -517,7 +519,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context, ...@@ -517,7 +519,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
// Update transform feedback offsets on every draw call. // Update transform feedback offsets on every draw call.
if (mState.isTransformFeedbackActiveUnpaused()) if (mState.isTransformFeedbackActiveUnpaused())
{ {
mXfbBaseVertex = firstVertex; ASSERT(firstVertexOrInvalid != -1);
mXfbBaseVertex = firstVertexOrInvalid;
invalidateGraphicsDriverUniforms(); invalidateGraphicsDriverUniforms();
} }
...@@ -580,6 +583,28 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context, ...@@ -580,6 +583,28 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
mIndexedDirtyBitsMask, commandBufferOut); mIndexedDirtyBitsMask, commandBufferOut);
} }
angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut,
vk::Buffer **indirectBufferOut)
{
ASSERT(mode != gl::PrimitiveMode::LineLoop);
gl::Buffer *indirectBuffer = mState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
ASSERT(indirectBuffer);
vk::BufferHelper &buffer = vk::GetImpl(indirectBuffer)->getBuffer();
*indirectBufferOut = const_cast<vk::Buffer *>(&buffer.getBuffer());
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
buffer.onRead(this, framebuffer, VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
ANGLE_TRY(setupDraw(context, mode, -1, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr,
dirtyBitMask, commandBufferOut));
return angle::Result::Continue;
}
angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context, angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint firstVertex, GLint firstVertex,
...@@ -1477,8 +1502,20 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context, ...@@ -1477,8 +1502,20 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
const void *indirect) const void *indirect)
{ {
ANGLE_VK_UNREACHABLE(this); if (mode == gl::PrimitiveMode::LineLoop)
return angle::Result::Stop; {
// TODO - http://anglebug.com/3564
ANGLE_VK_UNREACHABLE(this);
return angle::Result::Stop;
}
vk::CommandBuffer *commandBuffer = nullptr;
vk::Buffer *buffer = nullptr;
ANGLE_TRY(setupIndirectDraw(context, mode, mNonIndexedDirtyBitsMask, &commandBuffer, &buffer));
commandBuffer->drawIndirect(*buffer, reinterpret_cast<VkDeviceSize>(indirect), 1, 0);
return angle::Result::Continue;
} }
angle::Result ContextVk::drawElementsIndirect(const gl::Context *context, angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
......
...@@ -369,7 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -369,7 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
angle::Result setupDraw(const gl::Context *context, angle::Result setupDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint firstVertex, GLint firstVertexOrInvalid,
GLsizei vertexOrIndexCount, GLsizei vertexOrIndexCount,
GLsizei instanceCount, GLsizei instanceCount,
gl::DrawElementsType indexTypeOrInvalid, gl::DrawElementsType indexTypeOrInvalid,
...@@ -383,6 +383,12 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -383,6 +383,12 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
gl::DrawElementsType indexType, gl::DrawElementsType indexType,
const void *indices, const void *indices,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
angle::Result setupIndirectDraw(const gl::Context *context,
gl::PrimitiveMode mode,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut,
vk::Buffer **indirectBufferOut);
angle::Result setupLineLoopDraw(const gl::Context *context, angle::Result setupLineLoopDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint firstVertex, GLint firstVertex,
......
...@@ -213,6 +213,13 @@ void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer) ...@@ -213,6 +213,13 @@ void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer)
params->firstVertex, params->firstInstance); params->firstVertex, params->firstInstance);
break; break;
} }
case CommandID::DrawIndirect:
{
const DrawIndirectParams *params =
getParamPtr<DrawIndirectParams>(currentCommand);
vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, 1, 0);
break;
}
case CommandID::EndQuery: case CommandID::EndQuery:
{ {
const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand); const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
......
...@@ -51,6 +51,7 @@ enum class CommandID : uint16_t ...@@ -51,6 +51,7 @@ enum class CommandID : uint16_t
DrawIndexedInstancedBaseVertexBaseInstance, DrawIndexedInstancedBaseVertexBaseInstance,
DrawInstanced, DrawInstanced,
DrawInstancedBaseInstance, DrawInstancedBaseInstance,
DrawIndirect,
EndQuery, EndQuery,
ExecutionBarrier, ExecutionBarrier,
FillBuffer, FillBuffer,
...@@ -238,6 +239,13 @@ struct DispatchParams ...@@ -238,6 +239,13 @@ struct DispatchParams
}; };
VERIFY_4_BYTE_ALIGNMENT(DispatchParams) VERIFY_4_BYTE_ALIGNMENT(DispatchParams)
struct DrawIndirectParams
{
VkBuffer buffer;
VkDeviceSize offset;
};
VERIFY_4_BYTE_ALIGNMENT(DrawIndirectParams)
struct DispatchIndirectParams struct DispatchIndirectParams
{ {
VkBuffer buffer; VkBuffer buffer;
...@@ -476,6 +484,10 @@ class SecondaryCommandBuffer final : angle::NonCopyable ...@@ -476,6 +484,10 @@ class SecondaryCommandBuffer final : angle::NonCopyable
uint32_t firstVertex, uint32_t firstVertex,
uint32_t firstInstance); uint32_t firstInstance);
void drawIndirect(const Buffer &buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride);
void endQuery(VkQueryPool queryPool, uint32_t query); void endQuery(VkQueryPool queryPool, uint32_t query);
void executionBarrier(VkPipelineStageFlags stageMask); void executionBarrier(VkPipelineStageFlags stageMask);
...@@ -943,6 +955,20 @@ ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t ver ...@@ -943,6 +955,20 @@ ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t ver
paramStruct->firstInstance = firstInstance; paramStruct->firstInstance = firstInstance;
} }
ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect);
paramStruct->buffer = buffer.getHandle();
paramStruct->offset = offset;
// OpenGL ES doesn't have a way to specify a drawCount or stride, throw assert if something
// changes.
ASSERT(drawCount == 1);
}
ANGLE_INLINE void SecondaryCommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query) ANGLE_INLINE void SecondaryCommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
{ {
EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery); EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
......
...@@ -634,7 +634,13 @@ ...@@ -634,7 +634,13 @@
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL 3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
// Indirect draw: // Indirect draw:
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.* = SKIP 3564 VULKAN : dEQP-GLES31.functional.draw_indirect.draw_arrays_indirect.line_loop.* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.draw_elements_indirect.* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.instancing.draw_elements* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.compute_interop.separate.drawelements* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.compute_interop.combined.drawelements* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.compute_interop.large.drawelements* = SKIP
3564 VULKAN : dEQP-GLES31.functional.draw_indirect.random.* = SKIP
// Tessellation geometry interaction: // Tessellation geometry interaction:
3572 VULKAN : dEQP-GLES31.functional.tessellation_geometry_interaction.* = FAIL 3572 VULKAN : dEQP-GLES31.functional.tessellation_geometry_interaction.* = FAIL
......
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