PDA

View Full Version : Shader Storage Buffers and atomic_uint



ceebee
09-13-2012, 08:45 PM
I'm trying to go through all of the new OpenGL 4.3 additions. I have looking at shader storage buffers and compute shaders. I gotten a lot to work. However I would like to use the atomic_uint with a shader storage buffer. I was trying to use the example from Mike Bailey: http://web.engr.oregonstate.edu/~mjb/sig12/compute.shader.1pp.pdf. But I'm getting a compile error in my compute shader at this line:

layout( std140, binding=7 ) buffer { atomic_uint bounceCount };

It seems the compiler really wants a name after the buffer keyword. If I put one there it then gives me a new error about specifying a layout for the atomic_uint.

Any thoughts would be appreciated. The basic idea is that I should be able to bind an atomic to a GL_ATOMIC_COUNTER_BUFFER to set value and then read them using:


glBindBuffer( GL_SHADER_STORAGE_BUFFER, countBuffer );
GLuint *ptr = (GLuint *) glMapBuffer( GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY );

But since I can't compile the compute shader I'm stuck.

If anyone has and idea please let me know.

Thank you,

Craig

Alfonse Reinheart
09-13-2012, 09:54 PM
It seems the compiler really wants a name after the buffer keyword.

GLSL isn't C; the name of a uniform block is not optional. Even if you don't plan to use it from the API because you're using in-shader binding, you still need to name it.


If I put one there it then gives me a new error about specifying a layout for the atomic_uint.

Atomic counters are like image and sampler types: you cannot put them in interface blocks. They're opaque types (GLSL 4.3 section 4.1.7), which are expressly forbidden from going in those kinds of constructs.

ceebee
09-14-2012, 06:52 AM
Thanks

I figure that you needed a name for the uniform block. I think I was thrown off by the 4.3 Notes from SigGraph (http://web.engr.oregonstate.edu/~mjb...shader.1pp.pdf (https://docs.google.com/viewer?url=http%3A%2F%2Fweb.engr.oregonstate.edu%2 F~mjb%2Fsig12%2Fcompute.shader.1pp.pdf)): Which I will now assume is wrong.

Other Useful Stuff – Getting Information Back Out


Another example would be to count the number of fragments drawn so we know when all
particles are outside the viewing volume, and can stop animating:

Application Program:

glGenBuffers( 1, &particleBuffer);
glBindBufferBase( GL_ATOMIC_COUNTER_BUFFER, 8, particleBuffer);
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);


GLuint zero = 0;
glBufferSubData(GL_ATOMIC_COUNTER_BUFFER,
glBufferSubData(GL ATOMIC COUNTER BUFFER, 0, sizeof(GLuint), &zero);

Fragment Shader:

layout( std140, binding=8 ) buffer { atomic_uint particleCount };
...
atomicCounterIncrement( particleCount );
...

Application Program:

glBindBuffer( GL_SHADER_STORAGE_BUFFER, particleBuffer );
GLuint *ptr = (GLuint *) glMapBuffer( GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY );
GLuint particleCount = ptr[ 0 ];
glUnmapBuffer( GL_SHADER_STORAGE_BUFFER );


If( particleCount == 0 ) DoAnimate = false; // stop animating

Alfonse Reinheart
09-14-2012, 08:36 AM
It's likely the author simply got carried away with shader storage buffers, since his atomic binding OpenGL code is exactly what you would use if `particleCount` were properly declared as a `uniform`.

ceebee
09-14-2012, 02:40 PM
Yes. I spent some time reading the 4.3 spec and things are a lot clearer now. Thank you for your help.

Craig