Image Load/Store: barrier() and memoryBarrier()

The memoryBarrier() suite of functions controls the ordering of writes from shaders. The barrier() function, usable only from tessellation control/compute shaders, effectively halts the invocation until all other shaders in the same patch/work group have reached that barrier.

Both tessellation control and compute shaders have ways to communicate through local memory (patch and shared variables, respectively). The effects of the barrier() function should also ensure that all of the appropriate invocations have written to any non-local memory via images and such. Thus, if you run out of local memory, you could use an image as some workspace for these shaders.

What is unclear to me is this: do you still need the memoryBarrier() call to ensure ordering, even though you know that all of the shader invocations of interest executed up to that point already? I think you do, but I’m still trying to parse the spec on this stuff.

even though you know that all of the shader invocations of interest executed up to that point already

How do you know this without a memoryBarrier? I thought that was the only way of knowning that all invocations had reached a certain point.

As I understand it, [var]memoryBarrier[/var] has nothing to do with the execution of other invocations. It’s all about the ordering of stores for later loading. It ensures that stores written before that point will be visible to other invocations afterwards. [var]memoryBarrier[/var] is about memory and caches; it stops until all writes performed by a particular invocation have flushed. It says nothing about what other invocations are doing or where they’ve executed to.

It doesn’t do what [var]barrier[/var] does, which is ensure that all parallel invocations (within a work group/patch) have reached a certain point in the execution. That’s why [var]barrier[/var] is listed under “Shader Invocation Control Functions”, while [var]memoryBarrier[/var] is listed under “Shader Memory Control Functions”.

barrier() only ensures that the instructions before finished, while memoryBarrier() deals with write-to-read and write-to-write hazards, so yes, if you want to use image load/store for inter-thread communication you need memory barriers too.

So if I want a state change early in the shader code to effect the logic in all invocations I need


write state change to image
memoryBarrier();
barrier();
read image state change data

Yes. But of course, barrier only works in Compute Shaders and Tessellation Control Shaders.

Otherwise, the only ways you can guarantee that the data is around is either using a separate rendering invocation with a proper glMemoryBarrier, or a shader invocation that is dependent on the shader invocation that wrote the state.

Thanks for the info