Implementing a 2-element orded list in an image buffer


I need to implement an ordered list of 2 elements for use in a fragment shader.
My 2 elements are ivec4’s, no int/uint.
For this I need to do the following:


  • new = value calculated in current fragment shader
  • old[0] and [1] identify the read/write value reference in the image buffer location 0 and 1


  • if (new < old[0]) then write old[0] into old[1], write new into old[0]
  • else if (new < old[1]) then write new into old[1]

I want my whole algorithm code block to be executed in an atomic way, as a whole.
How can I do this in my fragment shader code? Shall I use a memoryBarrier() here?


GLSL doesn’t have mutexes. You could presumably simulate one using an atomic counter and a busy-wait loop, but performance will degrade rapidly in the presence of contention.

A memory barrier simply forces memory operations which were initiated prior to the barrier to complete before any subsequent memory operations are initiated.


if (new < old[0]) then 
  old[0] => old[1], new ==> old[0]
else if (new < old[1]) then 
  new ==> old[1]

I want my whole algorithm code block to be executed in an atomic way, as a whole.[/QUOTE]

What are you trying to do (big picture that is, not per-fragment)? Per-fragment you’re obviously just keeping the 2 lowest values.

If every fragment has their own unique old[0] and old[1], You could try: read old[0…1]; compute new old[0…1]; mem barrier; write old[0…1]. But don’t know whether that’d be fast.

Another possibility is to ping-pong back and forth between two images (or image slices). Bind the buffer with the input old[0…1] as input. Bind the buffer with the output old[0…1] as output (as 1…2 MRTs on gl_FragData[0…1] for instance), and have the frag shader do similarly to before (read old[0…1]; compute new old[0…1]; write to gl_FragData[0…1]). No memory barrier sync required and likely to pipeline well.

Thanks for your reply.
For the stuff I am interested in, I think I’m running into the general limitation of atomics for this problem. Basically, I would like to read a couple of uints (or vec4’s, that really is what I want ultimately), do some stuff, then write these values back, all in an atomic fashion.
I wish GPU hardware and GLSL could provide “shader transactions” to atomically execute a block of code.

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