Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Closed-loop FBO operation, practical application

  1. #1
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    21

    Closed-loop FBO operation, practical application

    Hello,

    I was wondering whether there's any 100% answer on the closed-loop FBO operations.

    Some people say that closed-loop FBO operations don't work at all, while others say that it is possible as long as the read/write operations are done on different textures (texture attachments).

    I tried experimenting with differed shading using single FBO. However, while rendering the pre-shading maps was done just fine, the shading rendering produced some strange results (random I should say). This was done using read of textures used in texture attachments 0-3, outputting into texture from the attachment 4, without any extra FBO operations except for calling step-related glDrawBuffers operation in order to enable specific texture outputs. The shading process is actually disabled for testing purposes, it simply outputs unchanged values from the input color map.

    Is there any other step that needs to be done in order to allow that (assuming the question to the 1st question is "yes")?

    I've read about the texture barrier, but there are very little actual application examples. Also, I believe it is not applicable to OGL 3.2 (I can switch to 4.5, but so far I had no reason to). I would like to avoid using 2 FBOs with the same textures for ping-ponging, altho it might be the only solution with decent performance.

    The result:
    Click image for larger version. 

Name:	OpenGLClosedLoopFBO.jpg 
Views:	13 
Size:	19.9 KB 
ID:	2519

  2. #2
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,924
    What is a "closed-loop FBO operation"? Google says nothing about this term, so it's unclear who the hypothetical "some people" and "others" are who talk about them.

    If you're talking about FBO feedback loops (ie: rendering to an attached image while reading from it), that is well-covered. Under standard GL 3.x rules, you cannot read from any image that is attached to the framebuffer, period. Under NV/ARB_texture_barrier/OpenGL 4.5, things are more relaxed.

    Of course, NV_texture_barrier is widely implemented, so you probably already have this capability.

  3. #3
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    21
    Yeah that's exactly it. Closed-loop = feedback operation.

    If you're talking about FBO feedback loops (ie: rendering to an attached image while reading from it), that is well-covered. Under standard GL 3.x rules, you cannot read from any image that is attached to the framebuffer, period. Under NV/ARB_texture_barrier/OpenGL 4.5, things are more relaxed.
    The page that you provided mentions "Similarly, if you wrote to an image, then want to read the data you wrote, you can issue the barrier instead of having to detach the image. You can use Write Masks or Draw Buffer state to prevent writing while you are reading.". This complements your comment about OpenGL 4.5 being more relaxed.

    I am actually using drawBuffers(n, buffs) function between each operation, enabling different texture attachments for each step of my render. I was under the impression that it, by itself, would block writing to the texture I'm reading from (not that I'm doing it). However, since it results in random output, even with OpenGL 4.5 used I was wondering whether there's something else needed.

    I need to do a lot more research on NV_texture_barrier before I figure out how to use it, so I would like to avoid it for now.

    Of course, NV_texture_barrier is widely implemented, so you probably already have this capability.
    Thanks for the link.

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,467
    Quote Originally Posted by CaptainSnugglebottom View Post
    I am actually using drawBuffers(n, buffs) function between each operation, enabling different texture attachments for each step of my render. I was under the impression that it, by itself, would block writing to the texture I'm reading from (not that I'm doing it).
    The draw buffer state and write masks prevent the texture from being modified, but the pixels are still deemed to have been modified so far as the memory model is concerned. The implementation is free to discard any cached data for those pixels in all attached textures regardless of draw buffer state and write masks, so reading may yield garbage.

  5. #5
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,924
    Quote Originally Posted by CaptainSnugglebottom View Post
    I am actually using drawBuffers(n, buffs) function between each operation, enabling different texture attachments for each step of my render. I was under the impression that it, by itself, would block writing to the texture I'm reading from (not that I'm doing it). However, since it results in random output, even with OpenGL 4.5 used I was wondering whether there's something else needed.
    Well, there's no way to know what's really going on from just a description, but as stated in the wiki page:

    Quote Originally Posted by Wiki
    All that it takes to trigger undefined fetches is for the image to be attached, even if you are not rendering to it. So the draw buffers state for the framebuffer is irrelevant. If it is attached to the FBO currently being rendered to, and you try to read from it, you get undefined behavior. Similarly, using Write Masks will also not prevent undefined behavior.
    This remains unchanged even with 4.5:

    Quote Originally Posted by Wiki
    Despite this relaxation of the rules, undefined behavior is still triggered whenever a shader attempts to read from texels written by a prior rendering call (so long as the texture remains a render target).
    Visibility of previously written data cannot be achieved unless you actually detach the images/change which FBO is currently being rendered to, or issue a texture barrier.

  6. #6
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    612
    Look to https://www.khronos.org/registry/Ope...re_barrier.txt .

    Another thing that can give similar functionality (but not using FBOs) is to use and abuse https://www.khronos.org/registry/Ope...load_store.txt

  7. #7
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    21
    Visibility of previously written data cannot be achieved unless you actually detach the images/change which FBO is currently being rendered to, or issue a texture barrier.
    Can glTextureBarrier() be used for the entire image? The wiki page only provides example regarding piece-wise rendering. Should it be called before each draw call, or just before the step (so before first draw call after the shader program has been changed)? Nevermind, it is mentioned, just lower....

    How is glTextureBarrier() doing when it comes to performance, is it an improvement compared to FBO binding/unbinding?


    Thanks.

  8. #8
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,924
    How is glTextureBarrier() doing when it comes to performance, is it an improvement compared to FBO binding/unbinding?
    If it wasn't cheaper than changing the FBO, why would they bother adding it?

  9. #9
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    21
    If it wasn't cheaper than changing the FBO, why would they bother adding it?
    I wasn't even sure if I needed it. Now that I know I do, I wonder about its performance.

  10. #10
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    612
    glTextureBarrier is essentially a cache flush; So essentially that means all render caches are flushed to video memory and the texture caches are invalidated.

    Also note that doing glTextureBarrier() means that any given draw call must NOT have any overlapping pixels and if two draw calls overlap in screen space, then a glTextureBarrier needs to be between them.

    If one wants to have one's fragment shader read from the surface of a framebuffer -at- the location of its invocation, I (personally) prefer to use GL_ARB_shader_image_load_store together with GL_ARB_fragment_shader_interlock, but that can have negative consequences as well (on some platforms, lossless color buffer compression is disabled on a surface if one access the surface through GL_ARB_shader_image_load_store and the interlock forces ordering in screen space which can be ungood too for performance).

    There is also, for GLES, the extension GL_EXT_shader_framebuffer_fetch. If you are using Mesa with Intel hardware, one can enable this in GL (with a different extension name) if one is willing to hack the driver.

Posting Permissions

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