imageAtomicMin(), memoryBarrier() and coherent uniform qualifier


I have a shader that pokes into a framebuffer-sized image (uimage2D) when rendering fragments.
Eg. everytime a fragment shader invocation is run, the following happens:

uniform uimage2D myimage;

uint val = compute some value;
imageAtomicMin(myimage, ivec2(gl_FragCoord.xy),                val);
imageAtomicMin(myimage, ivec2(gl_FragCoord.xy) + ivec2(-1, 0), val);
imageAtomicMin(myimage, ivec2(gl_FragCoord.xy) + ivec2( 1, 0), val);
imageAtomicMin(myimage, ivec2(gl_FragCoord.xy) + ivec2( 0, 1), val);
imageAtomicMin(myimage, ivec2(gl_FragCoord.xy) + ivec2( 0,-1), val);

Basically a value is written into myimage (well, a min() is performed) with regards to the current fragment location, as well as for the 4 neighbor locations (above, underneath, and on the left and right sides).

Note that another fragment of the same triangle primitive might write at a location currently being written to by the current fragment shader invocation. Concurrency may also happen between fragment shader invocations related to 2 different triangle primitives.

I have two questions regarding my logic:

  • should I declare myimage as coherent?
  • should I issue a memoryBarrier() prior to calling imageAtomicMin?


For this particular case you neither need coherent image, nor memoryBarrier. Here’s why:

  • coherent is needed only if your other shader invocations might rely on the value written by your current shader invocation. It isn’t the case here, as you don’t use the return value of the atomic op, and the image operations are executed out-of-order in between shader invocations no matter what you do (though here out-of-order execution is no issue as atomicMin is commutative).
  • memoryBarrier only orders the memory operations within the current shader invocation, but your shader never accesses the same memory address multiple times in the same shader invocation so it’s unnecessary to use it.

Thanks for your reply. This makes sense.

One last question, if my shader has to perform multiple atomicMin’s at the same memory location, but without ever having the need to read any old value back (uint oldValue = atomicMin(…)), do I need to call memoryBarrier() in between two consecutive atomicMin’s? I guess the answer is no again, here.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.