summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-10-19 18:41:13 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-10-19 18:41:13 +0000
commitf6181c0d90eb7a6135353113ea153942df276bdc (patch)
tree64da0ba73c1761b4ef61e82c60b4977e9439eb51 /Graphics/GraphicsEngineOpenGL
parentAdded convenience constructor to LayoutElement struct (diff)
downloadDiligentCore-f6181c0d90eb7a6135353113ea153942df276bdc.tar.gz
DiligentCore-f6181c0d90eb7a6135353113ea153942df276bdc.zip
Reworked Draw and DispatchCompute commands (Updated API version to 240033)
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h13
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp323
2 files changed, 200 insertions, 136 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
index 917df61a..1cf1576b 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
@@ -83,9 +83,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,
@@ -170,6 +174,11 @@ protected:
GLContextState m_ContextState;
private:
+
+ __forceinline void PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenum& GlTopology);
+ __forceinline void PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset);
+ __forceinline void PrepareForIndirectDraw(IBuffer* pAttribsBuffer);
+ __forceinline void PostDraw();
Uint32 m_CommitedResourcesTentativeBarriers;
std::vector<class TextureBaseGL*> m_BoundWritableTextures;
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index aacf29cb..aed3eac0 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -603,13 +603,10 @@ namespace Diligent
#endif
}
- void DeviceContextGLImpl::Draw(DrawAttribs &drawAttribs)
+ void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenum& GlTopology)
{
#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
@@ -621,7 +618,7 @@ namespace Diligent
if (!m_ContextState.IsValidVAOBound())
{
auto& VAOCache = pRenderDeviceGL->GetVAOCache(CurrNativeGLContext);
- IBuffer* pIndexBuffer = drawAttribs.IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr;
+ IBuffer* pIndexBuffer = 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 );
@@ -637,7 +634,6 @@ namespace Diligent
}
}
- GLenum GlTopology;
auto Topology = PipelineDesc.PrimitiveTopology;
if (Topology >= PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST)
{
@@ -653,166 +649,225 @@ namespace Diligent
{
GlTopology = PrimitiveTopologyToGLTopology( Topology );
}
- GLenum IndexType = 0;
- Uint32 FirstIndexByteOffset = 0;
- if (drawAttribs.IsIndexed)
+ }
+
+ void DeviceContextGLImpl::PrepareForIndexedDraw(VALUE_TYPE IndexType, Uint32 FirstIndexLocation, GLenum& GLIndexType, Uint32& FirstIndexByteOffset)
+ {
+ GLIndexType = TypeToGLType( IndexType );
+ VERIFY( GLIndexType == GL_UNSIGNED_BYTE || GLIndexType == GL_UNSIGNED_SHORT || GLIndexType == GL_UNSIGNED_INT,
+ "Unsupported index type" );
+ VERIFY( m_pIndexBuffer, "Index Buffer is not bound to the pipeline" );
+ FirstIndexByteOffset = static_cast<Uint32>(GetValueSize( IndexType )) * FirstIndexLocation + m_IndexDataStartOffset;
+ }
+
+ void DeviceContextGLImpl::PostDraw()
+ {
+ // IMPORTANT: new pending memory barriers in the context must be set
+ // after all previous barriers have been executed.
+ // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required
+ // AFTER the actual draw/dispatch command is executed.
+ m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers );
+ m_CommitedResourcesTentativeBarriers = 0;
+ }
+
+ void DeviceContextGLImpl::Draw(const DrawAttribs& Attribs)
+ {
+ if (!DvpVerifyDrawArguments(Attribs))
+ return;
+
+ GLenum GlTopology;
+ PrepareForDraw(Attribs.Flags, false, GlTopology);
+
+ if (Attribs.NumInstances > 1)
+ {
+ if (Attribs.FirstInstanceLocation)
+ glDrawArraysInstancedBaseInstance(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances, Attribs.FirstInstanceLocation);
+ else
+ glDrawArraysInstanced(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices, Attribs.NumInstances);
+ }
+ else
{
- 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;
+ glDrawArrays(GlTopology, Attribs.StartVertexLocation, Attribs.NumVertices);
}
+ DEV_CHECK_GL_ERROR( "OpenGL draw command failed" );
+
+ PostDraw();
+ }
+
+ void DeviceContextGLImpl::DrawIndexed(const DrawIndexedAttribs& Attribs)
+ {
+ if (!DvpVerifyDrawIndexedArguments(Attribs))
+ return;
+
+ GLenum GlTopology;
+ PrepareForDraw(Attribs.Flags, true, GlTopology);
+ GLenum GLIndexType;
+ Uint32 FirstIndexByteOffset;
+ PrepareForIndexedDraw(Attribs.IndexType, Attribs.FirstIndexLocation, GLIndexType, FirstIndexByteOffset);
// NOTE: Base Vertex and Base Instance versions are not supported even in OpenGL ES 3.1
// This functionality can be emulated by adjusting stream offsets. This, however may cause
// errors in case instance data is read from the same stream as vertex data. Thus handling
// such cases is left to the application
- // http://www.opengl.org/wiki/Vertex_Rendering
- auto* pIndirectDrawAttribsGL = static_cast<BufferGLImpl*>(drawAttribs.pIndirectDrawAttribs);
- if (pIndirectDrawAttribsGL != nullptr)
+ if (Attribs.NumInstances > 1)
{
-#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.
- 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);
- constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO
- m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer, ResetVAO);
-
- if (drawAttribs.IsIndexed)
+ if (Attribs.BaseVertex > 0)
{
- //typedef struct {
- // GLuint count;
- // GLuint instanceCount;
- // GLuint firstIndex;
- // GLuint baseVertex;
- // GLuint baseInstance;
- //} DrawElementsIndirectCommand;
- 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
- DEV_CHECK_GL_ERROR( "glDrawElementsIndirect() failed" );
+ if (Attribs.FirstInstanceLocation)
+ glDrawElementsInstancedBaseVertexBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.BaseVertex, Attribs.FirstInstanceLocation);
+ else
+ glDrawElementsInstancedBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.BaseVertex);
}
else
{
- //typedef struct {
- // GLuint count;
- // GLuint instanceCount;
- // GLuint first;
- // GLuint baseInstance;
- //} DrawArraysIndirectCommand;
- 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
- DEV_CHECK_GL_ERROR( "glDrawArraysIndirect() failed" );
+ if (Attribs.FirstInstanceLocation)
+ glDrawElementsInstancedBaseInstance(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances, Attribs.FirstInstanceLocation);
+ else
+ glDrawElementsInstanced(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.NumInstances);
}
-
- m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO );
-#else
- LOG_ERROR_MESSAGE("Indirect rendering is not supported");
-#endif
}
else
{
- if (drawAttribs.NumInstances > 1)
- {
- if (drawAttribs.IsIndexed)
- {
- 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);
- else
- 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);
- else
- 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);
- else
- glDrawArraysInstanced(GlTopology, drawAttribs.StartVertexLocation, drawAttribs.NumVertices, drawAttribs.NumInstances);
- }
- }
+ if (Attribs.BaseVertex > 0)
+ glDrawElementsBaseVertex(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset) ), Attribs.BaseVertex);
else
- {
- if (drawAttribs.IsIndexed)
- {
- 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)));
- }
- else
- glDrawArrays(GlTopology, drawAttribs.StartVertexLocation, drawAttribs.NumVertices);
- }
- DEV_CHECK_GL_ERROR( "OpenGL draw command failed" );
+ glDrawElements(GlTopology, Attribs.NumIndices, GLIndexType, reinterpret_cast<GLvoid*>( static_cast<size_t>(FirstIndexByteOffset)));
}
+ DEV_CHECK_GL_ERROR( "OpenGL draw command failed" );
- // IMPORTANT: new pending memory barriers in the context must be set
- // after all previous barriers have been executed.
- // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required
- // AFTER the actual draw/dispatch command is executed.
- m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers );
- m_CommitedResourcesTentativeBarriers = 0;
+ PostDraw();
}
- void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& DispatchAttrs)
+ void DeviceContextGLImpl::PrepareForIndirectDraw(IBuffer* pAttribsBuffer)
{
-#ifdef DEVELOPMENT
- if (!DvpVerifyDispatchArguments(DispatchAttrs))
+#if GL_ARB_draw_indirect
+ auto* pIndirectDrawAttribsGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer);
+ // 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.
+ 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);
+ constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO
+ m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer, ResetVAO);
+#endif
+ }
+
+ void DeviceContextGLImpl::DrawIndirect(const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+ {
+ if (!DvpVerifyDrawIndirectArguments(Attribs, pAttribsBuffer))
+ return;
+
+#if GL_ARB_draw_indirect
+ GLenum GlTopology;
+ PrepareForDraw(Attribs.Flags, true, GlTopology);
+
+ // http://www.opengl.org/wiki/Vertex_Rendering
+ PrepareForIndirectDraw(pAttribsBuffer);
+
+ //typedef struct {
+ // GLuint count;
+ // GLuint instanceCount;
+ // GLuint first;
+ // GLuint baseInstance;
+ //} DrawArraysIndirectCommand;
+ glDrawArraysIndirect( GlTopology, reinterpret_cast<const void*>( static_cast<size_t>(Attribs.IndirectDrawArgsOffset) ) );
+ // Note that on GLES 3.1, baseInstance is present but reserved and must be zero
+ DEV_CHECK_GL_ERROR( "glDrawArraysIndirect() failed" );
+
+ constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO
+ m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO );
+
+ PostDraw();
+#else
+ LOG_ERROR_MESSAGE("Indirect rendering is not supported");
+#endif
+ }
+
+ void DeviceContextGLImpl::DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+ {
+ if (!DvpVerifyDrawIndexedIndirectArguments(Attribs, pAttribsBuffer))
return;
+
+#if GL_ARB_draw_indirect
+ GLenum GlTopology;
+ PrepareForDraw(Attribs.Flags, true, GlTopology);
+ GLenum GLIndexType;
+ Uint32 FirstIndexByteOffset;
+ PrepareForIndexedDraw(Attribs.IndexType, 0, GLIndexType, FirstIndexByteOffset);
+
+ // http://www.opengl.org/wiki/Vertex_Rendering
+ PrepareForIndirectDraw(pAttribsBuffer);
+
+ //typedef struct {
+ // GLuint count;
+ // GLuint instanceCount;
+ // GLuint firstIndex;
+ // GLuint baseVertex;
+ // GLuint baseInstance;
+ //} DrawElementsIndirectCommand;
+ glDrawElementsIndirect( GlTopology, GLIndexType, reinterpret_cast<const void*>( static_cast<size_t>(Attribs.IndirectDrawArgsOffset) ) );
+ // Note that on GLES 3.1, baseInstance is present but reserved and must be zero
+ DEV_CHECK_GL_ERROR( "glDrawElementsIndirect() failed" );
+
+ constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO
+ m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO );
+
+ PostDraw();
+#else
+ LOG_ERROR_MESSAGE("Indirect rendering is not supported");
#endif
+ }
+
+
+ void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& Attribs)
+ {
+ if (!DvpVerifyDispatchArguments(Attribs))
+ return;
#if GL_ARB_compute_shader
m_pPipelineState->CommitProgram(m_ContextState);
+ glDispatchCompute(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ);
+ CHECK_GL_ERROR("glDispatchCompute() failed");
- if (DispatchAttrs.pIndirectDispatchAttribs)
- {
- CHECK_DYNAMIC_TYPE( BufferGLImpl, DispatchAttrs.pIndirectDispatchAttribs );
- auto* pBufferGL = static_cast<BufferGLImpl*>(DispatchAttrs.pIndirectDispatchAttribs);
- pBufferGL->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);
+ PostDraw();
+#else
+ UNSUPPORTED("Compute shaders are not supported");
+#endif
+ }
+
+ void DeviceContextGLImpl::DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer)
+ {
+ if (!DvpVerifyDispatchIndirectArguments(Attribs, pAttribsBuffer))
+ return;
- constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO
- m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO);
- CHECK_GL_ERROR( "Failed to bind a buffer for dispatch indirect command" );
+#if GL_ARB_compute_shader
+ m_pPipelineState->CommitProgram(m_ContextState);
- glDispatchComputeIndirect(DispatchAttrs.DispatchArgsByteOffset);
- CHECK_GL_ERROR("glDispatchComputeIndirect() failed");
+ auto* pBufferGL = ValidatedCast<BufferGLImpl>(pAttribsBuffer);
+ pBufferGL->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);
- m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO);
- }
- else
- {
- glDispatchCompute(DispatchAttrs.ThreadGroupCountX, DispatchAttrs.ThreadGroupCountY, DispatchAttrs.ThreadGroupCountZ);
- CHECK_GL_ERROR("glDispatchCompute() failed");
- }
+ constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO
+ m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO);
+ CHECK_GL_ERROR( "Failed to bind a buffer for dispatch indirect command" );
- // IMPORTANT: new pending memory barriers in the context must be set
- // after all previous barriers have been executed.
- // m_CommitedResourcesTentativeBarriers contains memory barriers that will be required
- // AFTER the actual draw/dispatch command is executed.
- m_ContextState.SetPendingMemoryBarriers( m_CommitedResourcesTentativeBarriers );
- m_CommitedResourcesTentativeBarriers = 0;
+ glDispatchComputeIndirect(Attribs.DispatchArgsByteOffset);
+ CHECK_GL_ERROR("glDispatchComputeIndirect() failed");
+
+ m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO);
+
+ PostDraw();
#else
UNSUPPORTED("Compute shaders are not supported");
#endif