diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-08-26 22:57:45 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-08-26 22:57:45 +0000 |
| commit | 9ae620ef8cb2e876af331c3c330d42f68ba2f76e (patch) | |
| tree | 4778f18d3fd95faea1de4a1873444fb022ae2e6e /Graphics | |
| parent | Updated readme (diff) | |
| download | DiligentCore-9ae620ef8cb2e876af331c3c330d42f68ba2f76e.tar.gz DiligentCore-9ae620ef8cb2e876af331c3c330d42f68ba2f76e.zip | |
Added draw/dispatch command argument validation
Removed DrawAttribs::IsIndirect
Diffstat (limited to 'Graphics')
6 files changed, 185 insertions, 183 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 8eb752d1..a1052c9b 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -141,6 +141,11 @@ protected: /// Clears all cached resources inline void ClearStateCache(); +#ifdef DEVELOPMENT + bool DvpVerifyDrawArguments(const DrawAttribs& drawAttribs); + bool DvpVerifyDispatchArguments(const DispatchComputeAttribs &DispatchAttrs); +#endif + /// Strong reference to the device. RefCntAutoPtr<IRenderDevice> m_pDevice; @@ -619,4 +624,70 @@ inline void DeviceContextBase<BaseInterface, BufferImplType, TextureViewImplType m_pBoundDepthStencil.Release(); } +#ifdef DEVELOPMENT +template<typename BaseInterface, typename BufferImplType, typename TextureViewImplType, typename PipelineStateImplType> +inline bool DeviceContextBase<BaseInterface, BufferImplType, TextureViewImplType, PipelineStateImplType> :: DvpVerifyDrawArguments(const DrawAttribs& drawAttribs) +{ + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound for a draw command"); + return false; + } + + if (m_pPipelineState->GetDesc().IsComputePipeline) + { + LOG_ERROR("Pipeline state bound for a draw command is a compute pipeline"); + return false; + } + + if (drawAttribs.NumIndices == 0) + { + LOG_WARNING_MESSAGE(drawAttribs.IsIndexed ? "Number of indices to draw is zero" : "Number of vertices to draw is zero"); + } + + if (drawAttribs.NumInstances == 0) + { + LOG_ERROR("Number of instances cannot be 0. Use 1 for a non-instanced draw command."); + return false; + } + + if (drawAttribs.IsIndexed && drawAttribs.IndexType != VT_UINT16 && drawAttribs.IndexType != VT_UINT32) + { + LOG_ERROR("For an indexed draw command IndexType must be VT_UINT16 or VT_UINT32"); + return false; + } + + return true; +} + +template<typename BaseInterface, typename BufferImplType, typename TextureViewImplType, typename PipelineStateImplType> +inline bool DeviceContextBase<BaseInterface, BufferImplType, TextureViewImplType, PipelineStateImplType> :: DvpVerifyDispatchArguments(const DispatchComputeAttribs &DispatchAttrs) +{ + if (!m_pPipelineState) + { + LOG_ERROR("No pipeline state is bound for a dispatch command"); + return false; + } + + if (!m_pPipelineState->GetDesc().IsComputePipeline) + { + LOG_ERROR("Pipeline state bound for a draw command is a graphics pipeline"); + return false; + } + + if (DispatchAttrs.ThreadGroupCountX == 0) + LOG_WARNING_MESSAGE("ThreadGroupCountX is zero"); + + if (DispatchAttrs.ThreadGroupCountY == 0) + LOG_WARNING_MESSAGE("ThreadGroupCountY is zero"); + + if (DispatchAttrs.ThreadGroupCountZ == 0) + LOG_WARNING_MESSAGE("ThreadGroupCountZ is zero"); + + return true; +} + +#endif + + } diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 72904ecd..ccbe8745 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -64,28 +64,24 @@ struct DrawAttribs /// For an indexed draw call, number of indices to draw Uint32 NumIndices; }; - /// For an indexed draw call, type of elements in the index buffer. - /// Allowed values: VT_UINT16 and VT_UINT32. Ignored if DrawAttribs::IsIndexed is False. - VALUE_TYPE IndexType = VT_UNDEFINED; /// Indicates if index buffer will be used to index input vertices Bool IsIndexed = False; + /// For an indexed draw call, type of elements in the index buffer. + /// Allowed values: VT_UINT16 and VT_UINT32. Ignored if DrawAttribs::IsIndexed is False. + VALUE_TYPE IndexType = VT_UNDEFINED; + /// Number of instances to draw. If more than one instance is specified, /// instanced draw call will be performed. Uint32 NumInstances = 1; - /// Indicates if indirect draw call will be performed. If set to True, - /// pIndirectDrawAttribs must contain valid pointer to the buffer, from which - /// draw attributes will be read. - Bool IsIndirect = False; - /// For indexed rendering, a constant which is added to each index before /// accessing the vertex buffer. Uint32 BaseVertex = 0; - /// For indirect rendering, offset from the beginning of the buffer to the - /// location of draw command attributes. Ignored if DrawAttribs::IsIndirect is False. + /// For indirect rendering, offset from the beginning of the buffer to the location + /// of draw command attributes. Ignored if DrawAttribs::pIndirectDrawAttribs is null. Uint32 IndirectDrawArgsOffset = 0; union @@ -103,7 +99,7 @@ struct DrawAttribs Uint32 FirstInstanceLocation = 0; /// For indirect rendering, pointer to the buffer, from which - /// draw attributes will be read. Ignored if DrawAttribs::IsIndirect is False. + /// draw attributes will be read. IBuffer* pIndirectDrawAttribs = nullptr; @@ -113,10 +109,9 @@ struct DrawAttribs /// Member | Default value /// ------------------------|-------------- /// NumVertices | 0 - /// IndexType | VT_UNDEFINED /// IsIndexed | False + /// IndexType | VT_UNDEFINED /// NumInstances | 1 - /// IsIndirect | False /// BaseVertex | 0 /// IndirectDrawArgsOffset | 0 /// StartVertexLocation | 0 diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 408e85ed..b8c84def 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -750,22 +750,11 @@ namespace Diligent m_bCommittedD3D11VBsUpToDate = true;
}
- void DeviceContextD3D11Impl::Draw( DrawAttribs &DrawAttribs )
+ void DeviceContextD3D11Impl::Draw( DrawAttribs &drawAttribs )
{
-#ifdef _DEBUG
- if (!m_pPipelineState)
- {
- LOG_ERROR("No pipeline state is bound");
+#ifdef DEVELOPMENT
+ if (!DvpVerifyDrawArguments(drawAttribs))
return;
- }
-#endif
-
-#ifdef _DEBUG
- if (m_pPipelineState->GetDesc().IsComputePipeline)
- {
- LOG_ERROR("No graphics pipeline state is bound");
- return;
- }
#endif
auto* pd3d11InputLayout = m_pPipelineState->GetD3D11InputLayout();
@@ -775,13 +764,13 @@ namespace Diligent CommitD3D11VertexBuffers(m_pPipelineState);
}
- if( DrawAttribs.IsIndexed )
+ if( drawAttribs.IsIndexed )
{
- if( m_CommittedIBFormat != DrawAttribs.IndexType )
+ if( m_CommittedIBFormat != drawAttribs.IndexType )
m_bCommittedD3D11IBUpToDate = false;
if(!m_bCommittedD3D11IBUpToDate)
{
- CommitD3D11IndexBuffer(DrawAttribs.IndexType);
+ CommitD3D11IndexBuffer(drawAttribs.IndexType);
}
}
@@ -800,47 +789,40 @@ namespace Diligent }
#endif
- if( DrawAttribs.IsIndirect )
+ auto* pIndirectDrawAttribsD3D11 = ValidatedCast<BufferD3D11Impl>(drawAttribs.pIndirectDrawAttribs);
+ if (pIndirectDrawAttribsD3D11 != nullptr)
{
- VERIFY( DrawAttribs.pIndirectDrawAttribs, "Indirect draw command attributes buffer is not set" );
- auto* pBufferD3D11 = static_cast<BufferD3D11Impl*>(DrawAttribs.pIndirectDrawAttribs);
- ID3D11Buffer* pd3d11ArgsBuff = pBufferD3D11 ? pBufferD3D11->m_pd3d11Buffer : nullptr;
- if( DrawAttribs.IsIndexed )
- m_pd3d11DeviceContext->DrawIndexedInstancedIndirect( pd3d11ArgsBuff, DrawAttribs.IndirectDrawArgsOffset );
+ ID3D11Buffer* pd3d11ArgsBuff = pIndirectDrawAttribsD3D11->m_pd3d11Buffer;
+ if( drawAttribs.IsIndexed )
+ m_pd3d11DeviceContext->DrawIndexedInstancedIndirect( pd3d11ArgsBuff, drawAttribs.IndirectDrawArgsOffset );
else
- m_pd3d11DeviceContext->DrawInstancedIndirect( pd3d11ArgsBuff, DrawAttribs.IndirectDrawArgsOffset );
+ m_pd3d11DeviceContext->DrawInstancedIndirect( pd3d11ArgsBuff, drawAttribs.IndirectDrawArgsOffset );
}
else
{
- if( DrawAttribs.NumInstances > 1 )
+ if( drawAttribs.NumInstances > 1 )
{
- if( DrawAttribs.IsIndexed )
- m_pd3d11DeviceContext->DrawIndexedInstanced( DrawAttribs.NumIndices, DrawAttribs.NumInstances, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation );
+ if( drawAttribs.IsIndexed )
+ m_pd3d11DeviceContext->DrawIndexedInstanced( drawAttribs.NumIndices, drawAttribs.NumInstances, drawAttribs.FirstIndexLocation, drawAttribs.BaseVertex, drawAttribs.FirstInstanceLocation );
else
- m_pd3d11DeviceContext->DrawInstanced( DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.StartVertexLocation, DrawAttribs.FirstInstanceLocation );
+ m_pd3d11DeviceContext->DrawInstanced( drawAttribs.NumVertices, drawAttribs.NumInstances, drawAttribs.StartVertexLocation, drawAttribs.FirstInstanceLocation );
}
else
{
- if( DrawAttribs.IsIndexed )
- m_pd3d11DeviceContext->DrawIndexed( DrawAttribs.NumIndices, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex );
+ if( drawAttribs.IsIndexed )
+ m_pd3d11DeviceContext->DrawIndexed( drawAttribs.NumIndices, drawAttribs.FirstIndexLocation, drawAttribs.BaseVertex );
else
- m_pd3d11DeviceContext->Draw( DrawAttribs.NumVertices, DrawAttribs.StartVertexLocation );
+ m_pd3d11DeviceContext->Draw( drawAttribs.NumVertices, drawAttribs.StartVertexLocation );
}
}
}
void DeviceContextD3D11Impl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs )
{
- if (!m_pPipelineState)
- {
- LOG_ERROR("No pipeline state is bound");
- return;
- }
- if (!m_pPipelineState->GetDesc().IsComputePipeline)
- {
- LOG_ERROR("No compute pipeline state is bound");
+#ifdef DEVELOPMENT
+ if (!DvpVerifyDispatchArguments(DispatchAttrs))
return;
- }
+#endif
if(m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance)
{
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 5f951a66..66477281 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -304,25 +304,17 @@ namespace Diligent m_bCommittedD3D12VBsUpToDate = !DynamicBufferPresent; } - void DeviceContextD3D12Impl::Draw( DrawAttribs& DrawAttribs ) + void DeviceContextD3D12Impl::Draw( DrawAttribs& drawAttribs ) { -#ifdef _DEBUG - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound"); - return; - } - if (m_pPipelineState->GetDesc().IsComputePipeline) - { - LOG_ERROR("No graphics pipeline state is bound"); +#ifdef DEVELOPMENT + if (!DvpVerifyDrawArguments(drawAttribs)) return; - } #endif auto &GraphCtx = RequestCmdContext()->AsGraphicsContext(); - if( DrawAttribs.IsIndexed ) + if( drawAttribs.IsIndexed ) { - if( m_CommittedIBFormat != DrawAttribs.IndexType ) + if( m_CommittedIBFormat != drawAttribs.IndexType ) m_bCommittedD3D12IBUpToDate = false; if(m_bCommittedD3D12IBUpToDate) @@ -332,7 +324,7 @@ namespace Diligent GraphCtx.TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_INDEX_BUFFER, true); } else - CommitD3D12IndexBuffer(DrawAttribs.IndexType); + CommitD3D12IndexBuffer(drawAttribs.IndexType); } if(m_bCommittedD3D12VBsUpToDate) @@ -355,44 +347,34 @@ namespace Diligent #endif - if( DrawAttribs.IsIndirect ) + auto *pIndirectDrawAttribsD3D12 = ValidatedCast<BufferD3D12Impl>(drawAttribs.pIndirectDrawAttribs); + if (pIndirectDrawAttribsD3D12 != nullptr) { - VERIFY(DrawAttribs.pIndirectDrawAttribs != nullptr, "Valid pIndirectDrawAttribs must be provided for indirect draw command"); - auto *pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(DrawAttribs.pIndirectDrawAttribs); - #ifdef DEVELOPMENT - if(pBufferD3D12->GetDesc().Usage == USAGE_DYNAMIC) - pBufferD3D12->DvpVerifyDynamicAllocation(m_ContextId); + if (pIndirectDrawAttribsD3D12->GetDesc().Usage == USAGE_DYNAMIC) + pIndirectDrawAttribsD3D12->DvpVerifyDynamicAllocation(m_ContextId); #endif - GraphCtx.TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); + GraphCtx.TransitionResource(pIndirectDrawAttribsD3D12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); size_t BuffDataStartByteOffset; - ID3D12Resource *pd3d12ArgsBuff = pBufferD3D12->GetD3D12Buffer(BuffDataStartByteOffset, m_ContextId); - GraphCtx.ExecuteIndirect(DrawAttribs.IsIndexed ? m_pDrawIndexedIndirectSignature : m_pDrawIndirectSignature, pd3d12ArgsBuff, DrawAttribs.IndirectDrawArgsOffset + BuffDataStartByteOffset); + ID3D12Resource *pd3d12ArgsBuff = pIndirectDrawAttribsD3D12->GetD3D12Buffer(BuffDataStartByteOffset, m_ContextId); + GraphCtx.ExecuteIndirect(drawAttribs.IsIndexed ? m_pDrawIndexedIndirectSignature : m_pDrawIndirectSignature, pd3d12ArgsBuff, drawAttribs.IndirectDrawArgsOffset + BuffDataStartByteOffset); } else { - if( DrawAttribs.IsIndexed ) - GraphCtx.DrawIndexed(DrawAttribs.NumIndices, DrawAttribs.NumInstances, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation); + if( drawAttribs.IsIndexed ) + GraphCtx.DrawIndexed(drawAttribs.NumIndices, drawAttribs.NumInstances, drawAttribs.FirstIndexLocation, drawAttribs.BaseVertex, drawAttribs.FirstInstanceLocation); else - GraphCtx.Draw(DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.StartVertexLocation, DrawAttribs.FirstInstanceLocation ); + GraphCtx.Draw(drawAttribs.NumVertices, drawAttribs.NumInstances, drawAttribs.StartVertexLocation, drawAttribs.FirstInstanceLocation ); } ++m_NumCommandsInCurCtx; } void DeviceContextD3D12Impl::DispatchCompute( const DispatchComputeAttribs& DispatchAttrs ) { -#ifdef _DEBUG - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound"); - return; - } - if (!m_pPipelineState->GetDesc().IsComputePipeline) - { - LOG_ERROR("No compute pipeline state is bound"); +#ifdef DEVELOPMENT + if (!DvpVerifyDispatchArguments(DispatchAttrs)) return; - } #endif auto& ComputeCtx = RequestCmdContext()->AsComputeContext(); diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index e00af85c..80af0fd0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -658,13 +658,12 @@ namespace Diligent #endif } - void DeviceContextGLImpl::Draw( DrawAttribs &DrawAttribs ) + void DeviceContextGLImpl::Draw( DrawAttribs &drawAttribs ) { - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound."); +#ifdef DEVELOPMENT + if (!DvpVerifyDrawArguments(drawAttribs)) return; - } +#endif auto *pRenderDeviceGL = m_pDevice.RawPtr<RenderDeviceGLImpl>(); auto CurrNativeGLContext = pRenderDeviceGL->m_GLContext.GetCurrentNativeGLContext(); @@ -672,7 +671,7 @@ namespace Diligent if(!m_bVAOIsUpToDate) { auto &VAOCache = pRenderDeviceGL->GetVAOCache(CurrNativeGLContext); - IBuffer *pIndexBuffer = DrawAttribs.IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; + IBuffer *pIndexBuffer = drawAttribs.IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; if(PipelineDesc.InputLayout.NumElements > 0 || pIndexBuffer != nullptr) { const auto& VAO = VAOCache.GetVAO( m_pPipelineState, pIndexBuffer, m_VertexStreams, m_NumVertexStreams, m_ContextState ); @@ -707,13 +706,13 @@ namespace Diligent } GLenum IndexType = 0; Uint32 FirstIndexByteOffset = 0; - if( DrawAttribs.IsIndexed ) + if( drawAttribs.IsIndexed ) { - IndexType = TypeToGLType( DrawAttribs.IndexType ); + IndexType = TypeToGLType( drawAttribs.IndexType ); VERIFY( IndexType == GL_UNSIGNED_BYTE || IndexType == GL_UNSIGNED_SHORT || IndexType == GL_UNSIGNED_INT, "Unsupported index type" ); VERIFY( m_pIndexBuffer, "Index Buffer is not bound to the pipeline" ); - FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( DrawAttribs.IndexType )) * DrawAttribs.FirstIndexLocation + m_IndexDataStartOffset; + FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( drawAttribs.IndexType )) * drawAttribs.FirstIndexLocation + m_IndexDataStartOffset; } // NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1 @@ -722,29 +721,24 @@ namespace Diligent // such cases is left to the application // http://www.opengl.org/wiki/Vertex_Rendering - if( DrawAttribs.IsIndirect ) + auto *pIndirectDrawAttribsGL = static_cast<BufferGLImpl*>(drawAttribs.pIndirectDrawAttribs); + if (pIndirectDrawAttribsGL != nullptr) { #if GL_ARB_draw_indirect // The indirect rendering functions take their data from the buffer currently bound to the // GL_DRAW_INDIRECT_BUFFER binding. Thus, any of indirect draw functions will fail if no buffer is // bound to that binding. - VERIFY( DrawAttribs.pIndirectDrawAttribs, "Indirect draw command attributes buffer is not set" ); - if( DrawAttribs.pIndirectDrawAttribs ) - { - auto *pBufferOGL = static_cast<BufferGLImpl*>(DrawAttribs.pIndirectDrawAttribs); - - pBufferOGL->BufferMemoryBarrier( - GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by - // Draw*Indirect and DispatchComputeIndirect commands after the barrier - // will reflect data written by shaders prior to the barrier.The buffer - // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER - // and DISPATCH_INDIRECT_BUFFER bindings. - m_ContextState); + pIndirectDrawAttribsGL->BufferMemoryBarrier( + GL_COMMAND_BARRIER_BIT,// Command data sourced from buffer objects by + // Draw*Indirect and DispatchComputeIndirect commands after the barrier + // will reflect data written by shaders prior to the barrier.The buffer + // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER + // and DISPATCH_INDIRECT_BUFFER bindings. + m_ContextState); - glBindBuffer( GL_DRAW_INDIRECT_BUFFER, pBufferOGL->m_GlBuffer ); - } + glBindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer ); - if( DrawAttribs.IsIndexed ) + if( drawAttribs.IsIndexed ) { //typedef struct { // GLuint count; @@ -753,7 +747,7 @@ namespace Diligent // GLuint baseVertex; // GLuint baseInstance; //} DrawElementsIndirectCommand; - glDrawElementsIndirect( GlTopology, IndexType, reinterpret_cast<const void*>( static_cast<size_t>(DrawAttribs.IndirectDrawArgsOffset) ) ); + glDrawElementsIndirect( GlTopology, IndexType, reinterpret_cast<const void*>( static_cast<size_t>(drawAttribs.IndirectDrawArgsOffset) ) ); // Note that on GLES 3.1, baseInstance is present but reserved and must be zero CHECK_GL_ERROR( "glDrawElementsIndirect() failed" ); } @@ -765,7 +759,7 @@ namespace Diligent // GLuint first; // GLuint baseInstance; //} DrawArraysIndirectCommand; - glDrawArraysIndirect( GlTopology, reinterpret_cast<const void*>( static_cast<size_t>(DrawAttribs.IndirectDrawArgsOffset) ) ); + glDrawArraysIndirect( GlTopology, reinterpret_cast<const void*>( static_cast<size_t>(drawAttribs.IndirectDrawArgsOffset) ) ); // Note that on GLES 3.1, baseInstance is present but reserved and must be zero CHECK_GL_ERROR( "glDrawArraysIndirect() failed" ); } @@ -777,44 +771,44 @@ namespace Diligent } else { - if( DrawAttribs.NumInstances > 1 ) + if( drawAttribs.NumInstances > 1 ) { - if( DrawAttribs.IsIndexed ) + if( drawAttribs.IsIndexed ) { - if( DrawAttribs.BaseVertex ) + if( drawAttribs.BaseVertex ) { - if( DrawAttribs.FirstInstanceLocation ) - glDrawElementsInstancedBaseVertexBaseInstance( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation ); + if( drawAttribs.FirstInstanceLocation ) + glDrawElementsInstancedBaseVertexBaseInstance( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), drawAttribs.NumInstances, drawAttribs.BaseVertex, drawAttribs.FirstInstanceLocation ); else - glDrawElementsInstancedBaseVertex( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.BaseVertex ); + glDrawElementsInstancedBaseVertex( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), drawAttribs.NumInstances, drawAttribs.BaseVertex ); } else { - if( DrawAttribs.FirstInstanceLocation ) - glDrawElementsInstancedBaseInstance( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances, DrawAttribs.FirstInstanceLocation ); + if( drawAttribs.FirstInstanceLocation ) + glDrawElementsInstancedBaseInstance( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), drawAttribs.NumInstances, drawAttribs.FirstInstanceLocation ); else - glDrawElementsInstanced( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.NumInstances ); + glDrawElementsInstanced( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), drawAttribs.NumInstances ); } } else { - if( DrawAttribs.FirstInstanceLocation ) - glDrawArraysInstancedBaseInstance( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices, DrawAttribs.NumInstances, DrawAttribs.FirstInstanceLocation ); + if( drawAttribs.FirstInstanceLocation ) + glDrawArraysInstancedBaseInstance( GlTopology, drawAttribs.StartVertexLocation, drawAttribs.NumVertices, drawAttribs.NumInstances, drawAttribs.FirstInstanceLocation ); else - glDrawArraysInstanced( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices, DrawAttribs.NumInstances ); + glDrawArraysInstanced( GlTopology, drawAttribs.StartVertexLocation, drawAttribs.NumVertices, drawAttribs.NumInstances ); } } else { - if( DrawAttribs.IsIndexed ) + if( drawAttribs.IsIndexed ) { - if( DrawAttribs.BaseVertex ) - glDrawElementsBaseVertex( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), DrawAttribs.BaseVertex ); + if( drawAttribs.BaseVertex ) + glDrawElementsBaseVertex( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), drawAttribs.BaseVertex ); else - glDrawElements( GlTopology, DrawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ) ); + glDrawElements( GlTopology, drawAttribs.NumIndices, IndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ) ); } else - glDrawArrays( GlTopology, DrawAttribs.StartVertexLocation, DrawAttribs.NumVertices ); + glDrawArrays( GlTopology, drawAttribs.StartVertexLocation, drawAttribs.NumVertices ); } CHECK_GL_ERROR( "OpenGL draw command failed" ); } @@ -829,6 +823,11 @@ namespace Diligent void DeviceContextGLImpl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) { +#ifdef DEVELOPMENT + if (!DvpVerifyDispatchArguments(DispatchAttrs)) + return; +#endif + #if GL_ARB_compute_shader if( DispatchAttrs.pIndirectDispatchAttribs ) { diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 16885c3d..c6746b1d 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -385,24 +385,16 @@ namespace Diligent LOG_ERROR_MESSAGE(ss.str()); } - void DeviceContextVkImpl::Draw( DrawAttribs &DrawAttribs ) + void DeviceContextVkImpl::Draw( DrawAttribs &drawAttribs ) { #ifdef DEVELOPMENT - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound"); + if (!DvpVerifyDrawArguments(drawAttribs)) return; - } - if (m_pPipelineState->GetDesc().IsComputePipeline) - { - LOG_ERROR("No graphics pipeline state is bound"); - return; - } #endif EnsureVkCmdBuffer(); - if ( DrawAttribs.IsIndexed ) + if ( drawAttribs.IsIndexed ) { #ifdef DEVELOPMENT if (m_pIndexBuffer == nullptr) @@ -416,8 +408,8 @@ namespace Diligent if (!pBuffVk->CheckAccessFlags(VK_ACCESS_INDEX_READ_BIT)) BufferMemoryBarrier(*pBuffVk, VK_ACCESS_INDEX_READ_BIT); - 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; + 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(pBuffVk->GetVkBuffer(), m_IndexDataStartOffset + pBuffVk->GetDynamicOffset(m_ContextId, this), vkIndexType); } @@ -437,21 +429,13 @@ namespace Diligent } #endif #endif - if ( DrawAttribs.IsIndirect ) - { -#ifdef DEVELOPMENT - if (DrawAttribs.pIndirectDrawAttribs == nullptr) - { - LOG_ERROR("Valid pIndirectDrawAttribs must be provided for indirect draw command"); - return; - } -#endif - auto *pBufferVk = ValidatedCast<BufferVkImpl>(DrawAttribs.pIndirectDrawAttribs); - + auto* pIndirectDrawAttribsVk = ValidatedCast<BufferVkImpl>(drawAttribs.pIndirectDrawAttribs); + if (pIndirectDrawAttribsVk != nullptr) + { // Buffer memory barries must be executed outside of render pass - if (!pBufferVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)) - BufferMemoryBarrier(*pBufferVk, VK_ACCESS_INDIRECT_COMMAND_READ_BIT); + if (!pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)) + BufferMemoryBarrier(*pIndirectDrawAttribsVk, VK_ACCESS_INDIRECT_COMMAND_READ_BIT); } #ifdef DEVELOPMENT @@ -463,29 +447,26 @@ namespace Diligent CommitRenderPassAndFramebuffer(); - if ( DrawAttribs.IsIndirect ) + if (pIndirectDrawAttribsVk != nullptr) { - if ( auto *pBufferVk = ValidatedCast<BufferVkImpl>(DrawAttribs.pIndirectDrawAttribs) ) - { #ifdef DEVELOPMENT - if (pBufferVk->GetDesc().Usage == USAGE_DYNAMIC) - pBufferVk->DvpVerifyDynamicAllocation(this); + if (pIndirectDrawAttribsVk->GetDesc().Usage == USAGE_DYNAMIC) + pIndirectDrawAttribsVk->DvpVerifyDynamicAllocation(this); #endif - if (!pBufferVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)) - BufferMemoryBarrier(*pBufferVk, VK_ACCESS_INDIRECT_COMMAND_READ_BIT); + if (!pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT)) + BufferMemoryBarrier(*pIndirectDrawAttribsVk, VK_ACCESS_INDIRECT_COMMAND_READ_BIT); - if ( DrawAttribs.IsIndexed ) - m_CommandBuffer.DrawIndexedIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + DrawAttribs.IndirectDrawArgsOffset, 1, 0); - else - m_CommandBuffer.DrawIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + DrawAttribs.IndirectDrawArgsOffset, 1, 0); - } + 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 { - if ( DrawAttribs.IsIndexed ) - m_CommandBuffer.DrawIndexed(DrawAttribs.NumIndices, DrawAttribs.NumInstances, DrawAttribs.FirstIndexLocation, DrawAttribs.BaseVertex, DrawAttribs.FirstInstanceLocation); + 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 ); + m_CommandBuffer.Draw(drawAttribs.NumVertices, drawAttribs.NumInstances, drawAttribs.StartVertexLocation, drawAttribs.FirstInstanceLocation ); } ++m_State.NumCommands; @@ -494,16 +475,8 @@ namespace Diligent void DeviceContextVkImpl::DispatchCompute( const DispatchComputeAttribs &DispatchAttrs ) { #ifdef DEVELOPMENT - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound"); + if (!DvpVerifyDispatchArguments(DispatchAttrs)) return; - } - if (!m_pPipelineState->GetDesc().IsComputePipeline) - { - LOG_ERROR("No compute pipeline state is bound"); - return; - } #endif EnsureVkCmdBuffer(); |
