summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-08-26 22:57:45 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-08-26 22:57:45 +0000
commit9ae620ef8cb2e876af331c3c330d42f68ba2f76e (patch)
tree4778f18d3fd95faea1de4a1873444fb022ae2e6e /Graphics
parentUpdated readme (diff)
downloadDiligentCore-9ae620ef8cb2e876af331c3c330d42f68ba2f76e.tar.gz
DiligentCore-9ae620ef8cb2e876af331c3c330d42f68ba2f76e.zip
Added draw/dispatch command argument validation
Removed DrawAttribs::IsIndirect
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.h71
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h21
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp62
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp54
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp87
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp73
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();