Using Bindless Textures With Framebuffer Objects Causes Artifacts

I have implemented abstract rendering api on top of opengl with extensions such as bindless textures however I see weird behaviour while rendering. If i will resize texture (Bindless textures cannot be resized so I am deleting handle & texture and then recreating and attaching it to a framebuffer again) only after some clear or draw command to that FBO (Before new frame) then i am getting weird artifacts on screen. There’s more to it. If i recreate FBO itself and attach resized texture to it, then it works fine. However if I add third render pass in the middle (post process in my case) and use resulted texture in shader to draw on screen then artifacts appear again. (glFlush and glFinish does not fix the problem)
So rendering pass looks like this:

Render scene in first FBO
Use result texture and render into second FBO
Use result texture and render into default FBO

I am setting texture as resident when requesting handle, and it stays like that forever until deleted or resized. These artifacts do not appear when im not using bindless textures. Also if i will download pixels with glReadPixels or glGetTexSubImage2D or such functions even only one pixel after resizing then everything works Fine. I am using AMD GPU. My thoughts are that there is a bug in implementation. Cannot find any good debugger except RenderDoc, however, it does not support bindless textures.

Here is the texture with artifacts I am getting on screen:


This is just an UV coords rendered on screen.

OS: Win 10
GPU: RX 580

Ok. So I gather that you’re rendering to textures via an FBO and making those textures resident so they can be accessed bindlessly in the shader in subsequent passes.

Assuming you’re updating the FBO attachments properly, this does sound like a possible driver bug.

I would just do this. It works, and it may be cheaper anyway.

Some drivers track all queued rendering work via the framebuffer container. On some drivers, reconfiguring an FBO will trigger a full pipeline flush. I have no idea what AMD drivers do here though.

That works if I wont do post process (The third pass in the middle), if I do this then artifacts are still coming up. And if i call glReadPixels after resize everything works just fine, and thats bad as a workaround as it synchronizes cpu/gpu.

I did more investigation and looks like if FBO has only 1 color attachment then texture gets corrupt if more then nothing happens.

EDIT: I have solved the issue with a hacky way. I delayed resize of a framebuffer (meaning resize of its attachments) till next frame’s first bind call

Good deal. Glad you got it figured out.

I wonder if before your workaround there was some shader code executing, assuming the old res after the render targets had been resized…

I doubt that, i tried glFinish and even Sleep functions on CPU side. But even if there was some shader code executing, it still should not have affected FBO cause I was recreating FBO and its textures as well. This is some weird bug, in summary corruption was happening when I was creating FBO with only 1 color attachment (Renderbuffers do not matter) after some draw call, But… (This sounds like too much hassle!) if I draw something after resize, in old or new FBO only, it works, if i I glClear old or new FBO’s depth/stencil (not color) buffer (It actually has none) it works o_0, and also if I call glReadPixels or other texture download functions. The part about working with only New and Old FBO and no other sounds strange I checked everything and they have 0 connection. Note that i was resizing fbo only once and not every frame.

Very strange. Thanks for following up with what you found! I bet you’ll save someone else trouble down-the-road on AMD drivers.