opengltexturesfbo

Texture used as FBO color attachment and sampler2D of a shader program at the same time


I have created an FBO and have a texture bound as its color attachment, and I have multiple shader programs that do some post processing on the texture, everything works great, but it does not make sense to me that the texture can be used as the input(sampler2D) as well as the output of the shaders at the same time.

Following are the steps I have taken:

  1. Create an FBO fboA.
  2. Create a texture textureA, and bind it as color attachment of fboA.
  3. Call glBindFrameBuffer to bind fboA to the framebuffer target.
  4. Call glUseProgram to use shader program shaderA.
  5. Call glDrawArrays to draw something (eventually drawn on textureA because fboA is currently bound).
  6. Call glUseProgram to use shader program shaderB which has a sampler2D uniform in the fragment shader.
  7. Bind textureA as sampler2D uniform of shader program shaderB.
  8. In the fragment shader, textureA is used to set the fragColor.

What I am confused about is the last two steps, where textureA is used as the input of the fragment shader, still it is bound to the current framebuffer. This appears to me that the fragment shader is reading from and writing to the same piece of memory, isn't this some kind of undefined behaviors, why it still works correctly?


Solution

  • isn't this some kind of undefined behaviors, why it still works correctly?

    Because "undefined behavior" does not preclude the possibility that the behavior may appear to "work correctly". UB means anything can happen, including the thing you actually wanted to happen.

    Of course, it might suddenly stop "working" tomorrow. Or when you take your code to a different GPU. Or if you start rendering more stuff. Or if you breath on your computer really hard.

    Undefined behavior is undefined.

    If you want to make it well-defined, then you need to use texture barrier functionality and abide by its rules: no more than one read/modify/write per-fragment between barriers, or just read from and write to non-overlapping sets of fragments.