diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-10-19 18:41:13 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-10-19 18:41:13 +0000 |
| commit | f6181c0d90eb7a6135353113ea153942df276bdc (patch) | |
| tree | 64da0ba73c1761b4ef61e82c60b4977e9439eb51 /Graphics/GraphicsEngineVulkan | |
| parent | Added convenience constructor to LayoutElement struct (diff) | |
| download | DiligentCore-f6181c0d90eb7a6135353113ea153942df276bdc.tar.gz DiligentCore-f6181c0d90eb7a6135353113ea153942df276bdc.zip | |
Reworked Draw and DispatchCompute commands (Updated API version to 240033)
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h | 16 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp | 168 |
2 files changed, 119 insertions, 65 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 08e4fcc2..9bcbb869 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -100,9 +100,13 @@ public: ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final; - virtual void Draw( DrawAttribs &DrawAttribs )override final; + virtual void Draw (const DrawAttribs& Attribs)override final; + virtual void DrawIndexed (const DrawIndexedAttribs& Attribs)override final; + virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; + virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; - virtual void DispatchCompute( const DispatchComputeAttribs& DispatchAttrs )override final; + virtual void DispatchCompute(const DispatchComputeAttribs& Attribs)override final; + virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)override final; virtual void ClearDepthStencil(ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, @@ -255,7 +259,7 @@ public: private: void TransitionRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); - inline void CommitRenderPassAndFramebuffer(bool VerifyStates); + __forceinline void CommitRenderPassAndFramebuffer(bool VerifyStates); void CommitVkVertexBuffers(); void CommitViewports(); void CommitScissorRects(); @@ -273,7 +277,7 @@ private: const char* OperationName); - inline void EnsureVkCmdBuffer() + __forceinline void EnsureVkCmdBuffer() { // Make sure that the number of commands in the context is at least one, // so that the context cannot be disposed by Flush() @@ -320,6 +324,10 @@ private: Uint32 DstBufferOffset, Uint32 DstBufferRowStrideInTexels); + __forceinline void PrepareForDraw(DRAW_FLAGS Flags); + __forceinline void PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE IndexType); + __forceinline BufferVkImpl* PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode); + __forceinline void PrepareForDispatchCompute(); void DvpLogRenderPass_PSOMismatch(); diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 52ea7a5a..385bf07a 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -393,38 +393,22 @@ namespace Diligent LOG_ERROR_MESSAGE(ss.str()); } - void DeviceContextVkImpl::Draw( DrawAttribs& drawAttribs ) + void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags) { #ifdef DEVELOPMENT - if ((drawAttribs.Flags & DRAW_FLAG_VERIFY_DRAW_ATTRIBS) != 0 && !DvpVerifyDrawArguments(drawAttribs)) - return; - - if ((drawAttribs.Flags & DRAW_FLAG_VERIFY_RENDER_TARGETS) != 0) + if ((Flags & DRAW_FLAG_VERIFY_RENDER_TARGETS) != 0) DvpVerifyRenderTargets(); #endif EnsureVkCmdBuffer(); - const bool VerifyStates = (drawAttribs.Flags & DRAW_FLAG_VERIFY_STATES) != 0; - if ( drawAttribs.IsIndexed ) - { -#ifdef DEVELOPMENT - if (VerifyStates) - { - DvpVerifyBufferState(*m_pIndexBuffer, RESOURCE_STATE_INDEX_BUFFER, "Indexed draw call (DeviceContextVkImpl::Draw)"); - } -#endif - DEV_CHECK_ERR(drawAttribs.IndexType == VT_UINT16 || drawAttribs.IndexType == VT_UINT32, "Unsupported index format. Only R16_UINT and R32_UINT are allowed."); - VkIndexType vkIndexType = drawAttribs.IndexType == VT_UINT16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; - m_CommandBuffer.BindIndexBuffer(m_pIndexBuffer->GetVkBuffer(), m_IndexDataStartOffset + m_pIndexBuffer->GetDynamicOffset(m_ContextId, this), vkIndexType); - } - if (!m_State.CommittedVBsUpToDate && m_pPipelineState->GetNumBufferSlotsUsed() > 0) { CommitVkVertexBuffers(); } + #ifdef DEVELOPMENT - if (VerifyStates) + if ((Flags & DRAW_FLAG_VERIFY_STATES) != 0) { for (Uint32 slot = 0; slot < m_NumVertexStreams; ++slot ) { @@ -448,14 +432,6 @@ namespace Diligent #endif #endif - auto* pIndirectDrawAttribsVk = ValidatedCast<BufferVkImpl>(drawAttribs.pIndirectDrawAttribs); - if (pIndirectDrawAttribsVk != nullptr) - { - // Buffer memory barries must be executed outside of render pass - TransitionOrVerifyBufferState(*pIndirectDrawAttribsVk, drawAttribs.IndirectAttribsBufferStateTransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, - VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect draw (DeviceContextVkImpl::Draw)"); - } - #ifdef DEVELOPMENT if (m_pPipelineState->GetVkRenderPass() != m_RenderPass) { @@ -463,38 +439,95 @@ namespace Diligent } #endif - CommitRenderPassAndFramebuffer(VerifyStates); + CommitRenderPassAndFramebuffer((Flags & DRAW_FLAG_VERIFY_STATES) != 0); + } + + BufferVkImpl* DeviceContextVkImpl::PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode) + { + DEV_CHECK_ERR(pAttribsBuffer, "Indirect draw attribs buffer must not be null"); + auto* pIndirectDrawAttribsVk = ValidatedCast<BufferVkImpl>(pAttribsBuffer); - if (pIndirectDrawAttribsVk != nullptr) - { #ifdef DEVELOPMENT - if (pIndirectDrawAttribsVk->GetDesc().Usage == USAGE_DYNAMIC) - pIndirectDrawAttribsVk->DvpVerifyDynamicAllocation(this); + if (pIndirectDrawAttribsVk->GetDesc().Usage == USAGE_DYNAMIC) + pIndirectDrawAttribsVk->DvpVerifyDynamicAllocation(this); #endif - if ( drawAttribs.IsIndexed ) - m_CommandBuffer.DrawIndexedIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + drawAttribs.IndirectDrawArgsOffset, 1, 0); - else - m_CommandBuffer.DrawIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + drawAttribs.IndirectDrawArgsOffset, 1, 0); - } - else + // Buffer memory barries must be executed outside of render pass + TransitionOrVerifyBufferState(*pIndirectDrawAttribsVk, TransitonMode, RESOURCE_STATE_INDIRECT_ARGUMENT, + VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect draw (DeviceContextVkImpl::Draw)"); + return pIndirectDrawAttribsVk; + } + + void DeviceContextVkImpl::PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE IndexType) + { + PrepareForDraw(Flags); + +#ifdef DEVELOPMENT + if ((Flags & DRAW_FLAG_VERIFY_STATES) != 0) { - if ( drawAttribs.IsIndexed ) - m_CommandBuffer.DrawIndexed(drawAttribs.NumIndices, drawAttribs.NumInstances, drawAttribs.FirstIndexLocation, drawAttribs.BaseVertex, drawAttribs.FirstInstanceLocation); - else - m_CommandBuffer.Draw(drawAttribs.NumVertices, drawAttribs.NumInstances, drawAttribs.StartVertexLocation, drawAttribs.FirstInstanceLocation ); + DvpVerifyBufferState(*m_pIndexBuffer, RESOURCE_STATE_INDEX_BUFFER, "Indexed draw call (DeviceContextVkImpl::Draw)"); } +#endif + DEV_CHECK_ERR(IndexType == VT_UINT16 || IndexType == VT_UINT32, "Unsupported index format. Only R16_UINT and R32_UINT are allowed."); + VkIndexType vkIndexType = IndexType == VT_UINT16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; + m_CommandBuffer.BindIndexBuffer(m_pIndexBuffer->GetVkBuffer(), m_IndexDataStartOffset + m_pIndexBuffer->GetDynamicOffset(m_ContextId, this), vkIndexType); + } + + void DeviceContextVkImpl::Draw(const DrawAttribs& Attribs) + { + if (!DvpVerifyDrawArguments(Attribs)) + return; + + PrepareForDraw(Attribs.Flags); + m_CommandBuffer.Draw(Attribs.NumVertices, Attribs.NumInstances, Attribs.StartVertexLocation, Attribs.FirstInstanceLocation ); ++m_State.NumCommands; } - void DeviceContextVkImpl::DispatchCompute( const DispatchComputeAttribs& DispatchAttrs ) + void DeviceContextVkImpl::DrawIndexed(const DrawIndexedAttribs& Attribs) { -#ifdef DEVELOPMENT - if (!DvpVerifyDispatchArguments(DispatchAttrs)) + if (!DvpVerifyDrawIndexedArguments(Attribs)) return; -#endif + PrepareForIndexedDraw(Attribs.Flags, Attribs.IndexType); + + m_CommandBuffer.DrawIndexed(Attribs.NumIndices, Attribs.NumInstances, Attribs.FirstIndexLocation, Attribs.BaseVertex, Attribs.FirstInstanceLocation); + ++m_State.NumCommands; + } + + void DeviceContextVkImpl::DrawIndirect(const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) + { + if (!DvpVerifyDrawIndirectArguments(Attribs, pAttribsBuffer)) + return; + + // We must prepare indirect draw attribs buffer first because state transitions must + // be performed outside of render pass, and PrepareForDraw commits render pass + BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode); + + PrepareForDraw(Attribs.Flags); + + m_CommandBuffer.DrawIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + Attribs.IndirectDrawArgsOffset, 1, 0); + ++m_State.NumCommands; + } + + void DeviceContextVkImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) + { + if (!DvpVerifyDrawIndexedIndirectArguments(Attribs, pAttribsBuffer)) + return; + + // We must prepare indirect draw attribs buffer first because state transitions must + // be performed outside of render pass, and PrepareForDraw commits render pass + BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode); + + PrepareForIndexedDraw(Attribs.Flags, Attribs.IndexType); + + m_CommandBuffer.DrawIndexedIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + Attribs.IndirectDrawArgsOffset, 1, 0); + ++m_State.NumCommands; + } + + + void DeviceContextVkImpl::PrepareForDispatchCompute() + { EnsureVkCmdBuffer(); // Dispatch commands must be executed outside of render pass @@ -512,28 +545,41 @@ namespace Diligent } #endif #endif + } - if (DispatchAttrs.pIndirectDispatchAttribs != nullptr) - { - auto *pBufferVk = ValidatedCast<BufferVkImpl>(DispatchAttrs.pIndirectDispatchAttribs); + void DeviceContextVkImpl::DispatchCompute(const DispatchComputeAttribs& Attribs) + { + if (!DvpVerifyDispatchArguments(Attribs)) + return; + + PrepareForDispatchCompute(); + m_CommandBuffer.Dispatch(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ); + ++m_State.NumCommands; + } + + void DeviceContextVkImpl::DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) + { + if (!DvpVerifyDispatchIndirectArguments(Attribs, pAttribsBuffer)) + return; + + PrepareForDispatchCompute(); + + auto* pBufferVk = ValidatedCast<BufferVkImpl>(pAttribsBuffer); #ifdef DEVELOPMENT - if (pBufferVk->GetDesc().Usage == USAGE_DYNAMIC) - pBufferVk->DvpVerifyDynamicAllocation(this); + if (pBufferVk->GetDesc().Usage == USAGE_DYNAMIC) + pBufferVk->DvpVerifyDynamicAllocation(this); #endif - // Buffer memory barries must be executed outside of render pass - TransitionOrVerifyBufferState(*pBufferVk, DispatchAttrs.IndirectAttribsBufferStateTransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, - VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect dispatch (DeviceContextVkImpl::DispatchCompute)"); - - m_CommandBuffer.DispatchIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + DispatchAttrs.DispatchArgsByteOffset); - } - else - m_CommandBuffer.Dispatch(DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ); + // Buffer memory barries must be executed outside of render pass + TransitionOrVerifyBufferState(*pBufferVk, Attribs.IndirectAttribsBufferStateTransitionMode, RESOURCE_STATE_INDIRECT_ARGUMENT, + VK_ACCESS_INDIRECT_COMMAND_READ_BIT, "Indirect dispatch (DeviceContextVkImpl::DispatchCompute)"); + m_CommandBuffer.DispatchIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + Attribs.DispatchArgsByteOffset); ++m_State.NumCommands; } + void DeviceContextVkImpl::ClearDepthStencil(ITextureView* pView, CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, float fDepth, @@ -1030,7 +1076,7 @@ namespace Diligent } } - inline void DeviceContextVkImpl::CommitRenderPassAndFramebuffer(bool VerifyStates) + void DeviceContextVkImpl::CommitRenderPassAndFramebuffer(bool VerifyStates) { const auto& CmdBufferState = m_CommandBuffer.GetState(); if (CmdBufferState.Framebuffer != m_Framebuffer) |
