PDA

View Full Version : Feedback loop using FBO and texture, a valid case?



jeinor
12-01-2011, 04:18 AM
Hi there,

I read about FBO and render-to-texture here: http://www.opengl.org/wiki/Framebuffer_Object. (http://www.opengl.org/wiki/Framebuffer_Object) Under the section "Feedback Loops" it is stated that "If you do try to read and write to the same image, you get undefined results. Meaning it may do what you want, the sampler may get old data, the sampler may get half old and half new data, or it may get garbage data. Any of these are possible.". This is also what I have gathered from other posts on these forums and elsewhere.

However, I have a case where I think it logically would be okay to write and sample the same texture, but I would like to know what you experts think.

As I see it, the problem is that the GPU does things in parallel, and if you sample and then render you're not sure if you get a texel with the original value, or if another calculation have (almost) stored a new value there. But what if my texture is exactly the same size as the screen size all the time, and I only read the texel I am currently setting the color for?

For example, in one pass, I render the full scene to a texture. In the next pass, I render the full scene again to the same texture, but I also sample the texture to perform some blending with of the old color value and the new color value. For every one pixel, there's an exact mapping to one texel.

Would this be a valid case to use a feedback loop with FBOs? As far as I can figure, it wont be possible to get any half-written values from the texture? Am I missing something?

Thanks in advance!

EDIT: The reason I want to do this is I want to be able to read a value placed in the texture by one triangle when I render the next triangle on top of the previous triangle. This is not possible by blitting or ping-pong techniques, as those only makes it possible to read the value from the very last rendered triangle (the final top triangle).

zeoverlord
12-01-2011, 06:20 AM
The example mentioned on that page is using a framebuffer texture to render to the same framebuffer which can lead to a race condition in which you can never be sure in which order pixels will be rendered, there is also an issue of cashing where the texture cashe may not update properly if you use the same textel to read and write to.
regular blending should not be affected though, so use that if you can.

However what you want to do is pretty much impossible unless you use a really slow ping pong technique or find another way of working around the problem, maybe using transform feedback and the geometry shader, or raycasting.
It really depends on what your trying to do.

BionicBytes
12-01-2011, 06:37 AM
For example, in one pass, I render the full scene to a texture. In the next pass, I render the full scene again to the same texture, but I also sample the texture to perform some blending with of the old color value and the new color value. For every one pixel, there's an exact mapping to one texel.

I think you are over complicating it.
Rad/write from the same tetxure is pretty much forbidden in the general case. The solution you need is much simpler. Simply copy the framebuffer (attachments) to a separate attachment or framebuffer before you start the second pass.
The copy operation is quick if you use framebuffer blit.

charliejay
12-01-2011, 06:49 AM
If you can use and/or specify hardware that supports them, then GL_ARB_shader_atomic_counters and/or more likely GL_ARB_shader_image_load_store will probably let you do what you want.

Not sure about GL_ARB_shader_atomic_counters off the top of my head, but GL_ARB_shader_image_load_store gives you a means to tell the hardware that it should force all writes to complete to a sufficient degree that any reads will get the newly written value, from the programmer's point of view.

The OpenGL spec does say that the result of commands should be as if they were executed sequentially, but there are a lot of qualifications to that.

jeinor
12-01-2011, 07:04 AM
The example mentioned on that page is using a framebuffer texture to render to the same framebuffer which can lead to a race condition in which you can never be sure in which order pixels will be rendered, there is also an issue of cashing where the texture cashe may not update properly if you use the same textel to read and write to.
regular blending should not be affected though, so use that if you can.
Ah, I see. Didn't know about those caches. Thanks.


I think you are over complicating it.
Rad/write from the same tetxure is pretty much forbidden in the general case. The solution you need is much simpler. Simply copy the framebuffer (attachments) to a separate attachment or framebuffer before you start the second pass.
The copy operation is quick if you use framebuffer blit.
If you read the text I wrote under EDIT, you can see that I'm unfortunately not over-complicating.


If you can use and/or specify hardware that supports them, then GL_ARB_shader_atomic_counters and/or more likely GL_ARB_shader_image_load_store will probably let you do what you want.
Thanks for the tip, will check that out. I probably can't use those extensions as our targets probably won't have them, but still interesting.

jeinor
12-01-2011, 07:56 AM
What do you think of this extension, posted to me in another thread I asked a very similar (but not so thorough) question: http://www.opengl.org/registry/specs/NV/texture_barrier.txt. (http://www.opengl.org/registry/specs/NV/texture_barrier.txt) That might help to solve my problem, right?

(If you want to read the other thread, it's here: http://www.gamedev.net/topic/521407-fbo---feedback-loop--npot-textures/. (http://www.gamedev.net/topic/521407-fbo---feedback-loop--npot-textures/) I didn't start it though, just borrowed it.)

jeinor
12-01-2011, 10:12 AM
I got some tip in the other thread (no, it's no good to have kind of the same discussion in two threads, but I'm afraid I can't help that now).

Anyway, I found this link: http://www.opengl.org/wiki/GLSL_:_common_mistakes#Sampling_and_Rendering_to_t he_Same_Texture, "You still don't get to read and write to the same location in a texture at the same time unless there is only a single read and write of each texel, and the read is in the fragment shader invocation that writes the same texel.".

If I only read the texel ONCE and write it ONCE, I should be okay even without extensions? As far as I can see, that's exactly what I want to do? Or do they mean once as in once even though I put glBegin() and glEnd() between the different rendered primitives?

Alfonse Reinheart
12-01-2011, 10:16 AM
If I only read the texel ONCE and write it ONCE, I should be okay even without extensions?

No. Context is important. And the line you're quoting is talking about the texture_barrier extension. Without that extension, doing what you suggest guarantees nothing.

jeinor
12-02-2011, 12:43 AM
Ok, I give in :) Thanks for making it clear.