PDA

View Full Version : Bind a depth/stencil texture as image



nostalgic
02-03-2017, 10:29 AM
Hello everybody,

in my application, I need to update depth values of some pixels as a post-process, but I fail to accomplish this. Some details:

- The scene is rendered into 2D multisample textures attached to an FBO
- The attached textures have the formats GL_RGB8 and GL_DEPTH32F_STENCIL8
- Yes, the 32F depth is crucial for terrain rendering, even with inverted depth
- I have a list of ivec2s identifying texels in the depth/stencil texture to update
- I recalculate depth values (no changes to stencil) in a compute shader and wanted to write them back per sample with imageStore(tex, texel, sampleID, newDepth)
- Turns out you cannot bind a combined depth/stencil image format as an image, it's not a supported format
- I cannot separate the textures into GL_DEPTH_COMPONENT32F and GL_STENCIL_INDEX8 either, because FBOs don't support GL_DEPTH_ATTACHMENT and GL_STENCIL_ATTACHMENT simultaneously

So, how can I change the depth values of some samples of some texels in a GL_DEPTH32F_STENCIL8 multisample texture? I thought about writing the new values to a second texture and then blitting, but neither did I test yet if this would actually work (blitting only depth, not stencil) nor am I enthusiastic about blitting a full-HD texture with possibly 8 samples each frame. Is there any way I can bind the depth component of the depth/stencil texture as a r32f image?

If all else fails, I could replace the compute shader by a fragment shader, enforce per-sample shading, discard all texels that don't need any update and write the remaining samples to the framebuffer. Sounds more performant than blitting, but still much less performant than just touching the (few) texels that actually need an update.

Target OpenGL version is 4.5 and Nvidia systems, so vendor-specific extensions or formats would also be a solution, if you know any.

Regards,
nostalgic

Dark Photon
02-03-2017, 06:29 PM
If all else fails, I could replace the compute shader by a fragment shader, enforce per-sample shading, discard all texels that don't need any update and write the remaining samples to the framebuffer. Sounds more performant than blitting, but still much less performant than just touching the (few) texels that actually need an update.

Have you considered rendering your list of texels as POINT primitives on top of a FBO bound with your depth-stencil texture? You could enable depth writes, disable stencil writes, and (with a simple GLSL frag shader) just update the specific texels you're interested in -- no need to discard.

nostalgic
02-04-2017, 12:58 PM
Thank you, you are right. Rendering the individual texels as points sounds better than the full-screen quad.

nostalgic
02-24-2017, 02:35 AM
One final note, since this post might be found by someone else having a similar idea: It is not even possible to bind depth buffers without stencil as images, let alone write to them.