Framebuffer not bliting depth buffer

Hi,

I have a framebuffer I use for storing the color and depth buffer after drawing the environment of my simulation (the camera moving seldom, it’s better to blit it if possible).

Problem is, the depth is not blited, therefor when i draw the mobile elements, well, no depth buffer. Tried playing with multisample, with glDepthMask, with GL_DEPTH_COMPONENT precision, no change.

Blitting to buffer after each camera displacement :


glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, BackupFBO);
glBlitFramebuffer(0, 0, currentWindowWidth, currentWindowHeight,
		0, 0, currentWindowWidth, currentWindowHeight, 
		GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

Blitting from buffer when no movement:


glBindFramebuffer(GL_READ_FRAMEBUFFER, BackupFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, currentWindowWidth, currentWindowHeight,
		0, 0, currentWindowWidth, currentWindowHeight, 
		GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

Framebuffer creation :


glGenRenderbuffers(1, &BackupFBO_colorRBO);
glBindRenderbuffer(GL_RENDERBUFFER, theatreBackupFBO_colorRBO);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, openGLFSAASamples, GL_RGBA, 1920, 1080);

glGenRenderbuffers(1, &BackupFBO_depthRBO);
glBindRenderbuffer(GL_RENDERBUFFER, theatreBackupFBO_depthRBO);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, openGLFSAASamples, GL_DEPTH_COMPONENT32, 1920, 1080);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

glGenFramebuffers(1, &BackupFBO);
glBindFramebuffer(GL_FRAMEBUFFER, BackupFBO);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, BackupFBO_colorRBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, BackupFBO_depthRBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Something I missed ?
depthbuffer is active all along, the code path is exactly the same in both cases…
I’ve got no clue.

edit : forgot an essential part … Firepro v5800, latest drivers, win7 64.

This looks correct. Are there any errors anywhere during blitting? Have you had a try with framebuffer textures instead of renderbuffers? BTW, why renderbuffers anyway?

oops, didn’t check for errors, since colors where correctly blited, I assumed it was Ok :frowning: Can only tell you tomorrow, since I’m back home.

I didn’t try with textures instead of renderbuffers.

I went for renderbuffers as it seemed to me more appropriate, and supported for a longer time than texture, especially considering the multisample necessity.

AMD have had a driver bug for some time when blitting depth and colour buffers in one call. Do them separately !
Are you using Radeons?

I’m using a FirePro v5800 (based on a Radeon 5770), with the latest FirePro drivers (september I think)

I’ll try them separatly then and let you know (tomorrow, here it’s 9 pm already), thx for the input.

Is there any reason to prefer textures to renderbuffers and vice versa ?

Is there any reason to prefer textures to renderbuffers and vice versa

Not really. AMD did have a bug some time ago with depth stencil textures and renderbuffers were the only available alternative.
Renderbuffers are better supported on mobile devices from what I gather.

Doing it in two copies of one buffer doesn’t work.
It’s as if i didn’t do the GL_DEPTH_BUFFER_BIT copy.

Ok there is an error : GL_INVALID_OPERATION.

Ok, let’s proceed step by step.
I don’t have the error if i remove the depth mask bit.
I have the error without multisampled renderbuffers.


GL_INVALID_OPERATION is generated if mask contains any of the GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and filter is not GL_NEAREST. 

not the case, i’m using GL_NEAREST.


GL_INVALID_OPERATION is generated if mask contains GL_DEPTH_BUFFER_BIT or GL_DEPTH_BUFFER_BIT and the source and destination depth and stencil formats do not match. 

I tried several things here : D24_S8 at window creation and renderbuffer depth_component24, or D32_S0 and renderbuffer depth_component32, or the same two but with renderbuffer depth_component. None works better.


GL_INVALID_OPERATION is generated if filter is GL_LINEAR and the read buffer contains integer data. 

Not the case.


GL_INVALID_OPERATION is generated if the value of GL_SAMPLES for the read and draw buffers is not identical. 

They are identical. Plus colors get copied anyway.


GL_INVALID_OPERATION is generated if GL_SAMPLE_BUFFERS for both read and draw buffers greater than zero and the dimensions of the source and destination rectangles is not identical. 

It’s the same size. Plus colors get copied anyway.


GL_INVALID_FRAMEBUFFER_OPERATION is generated if the objects bound to GL_DRAW_FRAMEBUFFER_BINDING or GL_READ_FRAMEBUFFER_BINDING are not framebuffer complete.

They are framebuffer complete.


GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT and any of the following conditions hold: 

The read buffer contains fixed-point or floating-point values and any draw buffer contains neither fixed-point nor floating-point values.

The read buffer contains unsigned integer values and any draw buffer does not contain unsigned integer values.

The read buffer contains signed integer values and any draw buffer does not contain signed integer values.

Colors get copied anyway.

Any ideas ?

My drivers :


Driver Packaging Version	8.85.7.2-110901a1-125182C	
Provider	ATI Technologies Inc.	
2D Driver Version	8.01.01.1152	
2D Driver File Path	/REGISTRY/MACHINE/SYSTEM/ControlSet001/Control/CLASS/{4D36E968-E325-11CE-BFC1-08002BE10318}/0000	
Direct3D Version	7.14.10.0833	
OpenGL Version	6.14.10.10792	
Catalyst Pro Control Center Version	2011.0901.2230.38549	


After checking my code, it looks like I have to work around AMD drivers when blitting FBOs.


procedure TFramebuffer.BlitDepthStencil(SrcbufferID,DstbufferID: integer);
begin
    glBindFramebuffer( GL_READ_FRAMEBUFFER, FrameBuffers [SrcbufferID].FBid );
    glReadBuffer(GL_NONE);
    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, FrameBuffers [DstbufferID].FBid);
    glDrawBuffer(GL_NONE);
    //AMD cat 10.7 driver bug? Cant combine depth and stencil blits   //VendorATI
    glBlitFramebuffer( 0, 0, FrameBuffers [SrcbufferID].Width, FrameBuffers [SrcbufferID].Height, 0, 0, FrameBuffers [DstbufferID].Width, FrameBuffers [DstbufferID].Height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
    glBlitFramebuffer( 0, 0, FrameBuffers [SrcbufferID].Width, FrameBuffers [SrcbufferID].Height, 0, 0, FrameBuffers [DstbufferID].Width, FrameBuffers [DstbufferID].Height, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
//    glBlitFramebuffer( 0, 0, FrameBuffers [SrcbufferID].Width, FrameBuffers [SrcbufferID].Height, 0, 0, FrameBuffers [DstbufferID].Width, FrameBuffers [DstbufferID].Height, GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer (GL_FRAMEBUFFER, 0);
end;

So it looks like I break down the number of blits into three calls.
The first blits only the colour attachments, the second and third are dealt with by the code above, which blits the depth and then blits the stencil.

Maybe i should add a stencil renderbuffer to be sure i have a frambuffer that mirrors my default framebuffer completely ?

Why are you setting your glDrawBuffer and glReadBuffer like that ?

Ok the glDraw/glRead buffer things doesn’t help.
I’ll try textures instead of renderbuffers, who knows …

Just tested on a quadro fx3800 (based on a GTX260), and the depth buffer is copied, but performances are awefull (its slower to blit than actually draw).

So it looks like driver troubles.

What driver are you using? In my case its 285.62 on a GF540GT M and i’ve never had any trouble with blitting.

Still, you can’t confirm that something works on an AMD board with NVidia board! :slight_smile:

Yup, but at least my code is correct for the nVidia.

The only thing i’m not sure of is :
GL_INVALID_OPERATION is generated if mask contains GL_DEPTH_BUFFER_BIT or GL_DEPTH_BUFFER_BIT and the source and destination depth and stencil formats do not match.

I’m not creating the window myself (I use SFML), so i’m not sure how it creates the context exactly.

I think

GL_INVALID_OPERATION is generated if mask contains GL_DEPTH_BUFFER_BIT or GL_DEPTH_BUFFER_BIT and the source and destination depth and stencil formats do not match.

is meant to read:

GL_INVALID_OPERATION is generated if mask contains GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and the source and destination depth and stencil formats do not match.

How many bits are you requesting for depth + stencil, and how many are you actually getting? A common format for default framebuffer is 24 bit depth, 8 bit stencil interleaved although I’m not sure how you query if it’s actually using an interleaved format or separate buffers - and also querying the default framebuffer bit depths using the technique specified in the core profile spec was buggy on drivers when I last checked. I guess for best performance when blitting an interleaved depth/stencil buffer, like when clearing, both the depth + stencil buffers should probably be copied at the same time for best performance.

That was the bug. I got the thing to work. just changed my depth renderbuffer from DEPTH_COMPONENT to GL_DEPTH24_STENCIL8.

It should be more obvious, you see it nowhere on the framebuffer pages, they only explain what theory should do.

you find a quick note about practice in the image format page :

Legacy Note: The original GL_EXT_framebuffer_object defined stencil-only image formats that had no depth component. No drivers ever supported these, and they were abandoned in favor of combined depth/stencil buffers in the 3.0 core and the ARB version of the FBO extension. Do not use them, even if your implementation does not support GL_EXT_packed_depth_stencil.

Seriously, one shouldn’t have so much trouble finding this information.

Anyway, working now, thanks for everything ppl :slight_smile:

Why are you setting your glDrawBuffer and glReadBuffer like that ?

Do you mean these?
glReadBuffer(GL_NONE);
glDrawBuffer(GL_NONE);

…because I’m not using the colour attachments.
Granted, it may be overkill for a routine which only blits from one FBO to another…

Try using GL_DEPTH24_STENCIL8 as your renderbuffer format. When blitting stencil or depth values, the corresponding pixel formats of source and destination MUST match. You might argue that the depthbuffer actually had the same format, but obviously, GL_DEPTH_COMPONENT24 and GL_DEPTh24_STENCIL8 are seen as completely different formats.

Btw, beware not to include GL_STENCIL_BIT in your mask. AMD has/had a bug where when you do this, the blitted depthvalues get screwed up. I don’t know if they fixed that yet.