AnsweredAssumed Answered

System hang with glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0)

Question asked by cybernoid on Nov 9, 2015

I have a compute shader that is writing a list of vertices out that are then rendered as GL_POINTS.  It work's on other vendors hardware so far but for some reason not on the Radeon 5870 with latest drivers.


If I remove the call to glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0) after the compute shader dispatch call  it stops hanging the whole system but does not render the points.


I am using glDrawArraysIndirect(GL_POINTS, 0) to draw the points as the count is output from the compute shader using an atomic that is mapped into the indirect draw buffer.  The vertices are output by the compute shader into an SSBO using the atomic to build up the point list.  The SSBO is then bound via a VAO as vertex buffer for the indirect point draw.


If I change glDrawArraysIndirect(GL_POINTS, 0) to glDrawArrays(GL_POINTS, 0, SomePointCount) to manually guess the point count it starts drawing them fine.  I use glMemoryBarrier(GL_ALL_BARRIER_BITS) after the compute shader currently for sanity.


The vertex format is:


struct Vertex


  float position[3];

  uint32_t colour;



When the vertex buffer is mapped as a SSBO to the compute shader it uses writeonly std430.



I tracked it down more to find the instanceCount in the indirectdraw buffer has gone crazy large, the vertex count that is written by the compute shader is correct however.  So I guess somehow the compute shader is stomping on the instanceCount when it is atomically updating the vertexCount for the indirect draw?  The relevant CS snippets are:


layout(std430, binding = 0) writeonly buffer VertexBuffer


  Vertex vertices[];



layout(binding = 0) uniform atomic_uint VertexCount;



uint vertexIndex = atomicCounterIncrement(VertexCount);

vertices[vertexIndex] = vertex;


I tried both:


glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffers.indirectDraw);




glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, buffers.indirectDraw, 0, sizeof(GLuint));


and there was no difference in behaviour which is strange as surely the latter may prevent the stomping of the instanceCount as it's the second uint in the indirectdraw structure which should be off the end of the bound buffer range...





I've tried to manually reset the offending corruption of the instanceCount in the drawindirect data with:


glClearNamedBufferSubData(buffers.command, GL_R32UI, sizeof(GLuint) * 1, sizeof(GLuint) * 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &one);


But it still doesn't appear to change the corrupted instance count value of 0xf915f767





I can now do glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0) and it doesn't hang the system but still corrupts the instanceCount.  I suspect it was the draw with corrupted instanceCount that was causing the hang not glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0) after a few frames maybe.


If I do glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0) then and _only_ then will glClearNamedBufferSubData() work to manually reset the corrupted instanceCount for the indirect draw but obviously this isn't ideal...