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)
angle::Result ContextVk::setupDraw(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
GLint firstVertexOrInvalid,
GLsizei vertexOrIndexCount,
GLsizei instanceCount,
gl::DrawElementsType indexTypeOrNone,
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
DirtyBits dirtyBitMask,
vk::CommandBuffer **commandBufferOut)
......@@ -479,8 +479,10 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
// Must be called before the command buffer is started. Can call finish.
if (context->getStateCache().hasAnyActiveClientAttrib())
{
ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertex, vertexOrIndexCount,
instanceCount, indexTypeOrNone, indices));
ASSERT(firstVertexOrInvalid != -1);
ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertexOrInvalid,
vertexOrIndexCount, instanceCount,
indexTypeOrInvalid, indices));
mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
}
......@@ -517,7 +519,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
// Update transform feedback offsets on every draw call.
if (mState.isTransformFeedbackActiveUnpaused())
{
mXfbBaseVertex = firstVertex;
ASSERT(firstVertexOrInvalid != -1);
mXfbBaseVertex = firstVertexOrInvalid;
invalidateGraphicsDriverUniforms();
}
......@@ -580,6 +583,28 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
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,
gl::PrimitiveMode mode,
GLint firstVertex,
......@@ -1477,8 +1502,20 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
gl::PrimitiveMode mode,
const void *indirect)
{
ANGLE_VK_UNREACHABLE(this);
return angle::Result::Stop;
if (mode == gl::PrimitiveMode::LineLoop)
{
// 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,
......
......@@ -369,7 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
angle::Result setupDraw(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
GLint firstVertexOrInvalid,
GLsizei vertexOrIndexCount,
GLsizei instanceCount,
gl::DrawElementsType indexTypeOrInvalid,
......@@ -383,6 +383,12 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
gl::DrawElementsType indexType,
const void *indices,
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,
gl::PrimitiveMode mode,
GLint firstVertex,
......
......@@ -213,6 +213,13 @@ void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer)
params->firstVertex, params->firstInstance);
break;
}
case CommandID::DrawIndirect:
{
const DrawIndirectParams *params =
getParamPtr<DrawIndirectParams>(currentCommand);
vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, 1, 0);
break;
}
case CommandID::EndQuery:
{
const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
......
......@@ -51,6 +51,7 @@ enum class CommandID : uint16_t
DrawIndexedInstancedBaseVertexBaseInstance,
DrawInstanced,
DrawInstancedBaseInstance,
DrawIndirect,
EndQuery,
ExecutionBarrier,
FillBuffer,
......@@ -238,6 +239,13 @@ struct DispatchParams
};
VERIFY_4_BYTE_ALIGNMENT(DispatchParams)
struct DrawIndirectParams
{
VkBuffer buffer;
VkDeviceSize offset;
};
VERIFY_4_BYTE_ALIGNMENT(DrawIndirectParams)
struct DispatchIndirectParams
{
VkBuffer buffer;
......@@ -476,6 +484,10 @@ class SecondaryCommandBuffer final : angle::NonCopyable
uint32_t firstVertex,
uint32_t firstInstance);
void drawIndirect(const Buffer &buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride);
void endQuery(VkQueryPool queryPool, uint32_t query);
void executionBarrier(VkPipelineStageFlags stageMask);
......@@ -943,6 +955,20 @@ ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t ver
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)
{
EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
......
......@@ -634,7 +634,13 @@
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
// 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:
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