Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Implementing a 2-element orded list in an image buffer

  1. #1
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130

    Implementing a 2-element orded list in an image buffer

    Hi,

    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:

    Given:
    - 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

    Algorithm:
    - 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?

    Thanks,
    Fred

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by fred_em View Post
    I want my whole algorithm code block to be executed in an atomic way, as a whole.
    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.
    Quote Originally Posted by fred_em View Post
    How can I do this in my fragment shader code? Shall I use a memoryBarrier() here?
    A memory barrier simply forces memory operations which were initiated prior to the barrier to complete before any subsequent memory operations are initiated.

  3. #3
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,184
    Quote Originally Posted by fred_em View Post
    Algorithm:
    Code :
    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.
    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.
    Last edited by Dark Photon; 06-19-2013 at 04:50 PM.

  4. #4
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130
    Quote Originally Posted by Dark Photon View Post
    What are you trying to do (big picture that is, not per-fragment)? Per-fragment you're obviously just keeping the 2 lowest values.
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •