Saving & Restoring Depth Buffer to/from PBO

Hello,

what i basically want to do is saving and restoring my depth buffer.

My first (very stupid) approach for testing my algorithm was: copying the depth buffer via readpixels to RAM and afterwards write it back to the depthbuffer via Drawpixels.

Now as you all can imagine this is pretty slow with increasing viewport size (pixels).

so i thought: yeah, why copying the stuff to the cpu, lets leave it on the graphics card.

Yeah so i initialized a PBO and did all that with PBO (code follows).
My algorithm still works, but it is as slow as before, so no real performance boost although I am using PBOs.

Code:

initializing PBO:

glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, window_wwindow_hsizeof(float), 0 , GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,0);

Read from Depth Buffer:

glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glReadPixels(0,0,window_w,window_h,GL_DEPTH_COMPONENT, GL_FLOAT, (GLvoid*)0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

Write it back:

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glDrawPixels(window_w, window_h, GL_DEPTH_COMPONENT,GL_FLOAT, (GLvoid*)0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

So my question is:
Why is there no performance boost?
Am I forgetting something?

Thanks in advance for all your replies!

GL_FLOAT is unlikely the native format of your depthbuffer data…in worst case the driver reads the data back to sysmem, converts it into float and then uploads it into the PBO again.

Try
GL_DEPTH_STENCIL_EXT as format and GL_UNSIGNED_INT_24_8_EXT as type.

thx for your reply,

I changed it, but it doesn’t seem to have much effect, it is still slow, but faster…

Try GL_STATIC_DRAW for the PBO.
Additionally post your graphics card type and driver version.
How many milliseconds do glReadPixels() glDrawPixels() take for your framebuffer? How large is the framebuffer?
Consider using ARB_timer_query for the timing.

ok:

no difference in times between dynamic draw and static draw

Graphics card: GeFroce GTX 285
Driver version: 8.17.12.6099 (from 16.10.2010)

I probably need to mention that I am doing this restoring several times per frame, not only once.
at the scene i am testing now i do it 9 times 4 read and 5 draw

for 800*600 it takes about 0.04 seconds per frame

I still need to figure out how to use ARB_timer_query.

I’ve seen this kind of insanity before in commercial apps. People trying to optimise by savings the scene to ram then restoring it later, failing to realise doing this is very very expensive.

You are better off just drawing the scene again, you can always disable writing to the colour buffer.

It’s all about screenspace csg, I need 2 Depth Buffers or it simply just won’t work!

times in milliseconds:

READ: on 800600 4 - 7.5 ms
WRITE: on 800
600 4 - 6.5 ms

there were rarely execution times of ~ 10ms for read and write.

It seems to me that GL_DYNAMIC_COPY would be more appropriate for buffer usage as you want the GPU to read AND write to it.

By the way, are you doing CSG with concave shapes? If you can decompose your CSG “brushes” as convex shapes, you can do many operations with just 1 depth, 1 stencil, multiple passes and no copy.

concave objects can also occur :smiley:
unfortunately decomposing them is rather tricky.

Nevertheless please show me a link to this algorithm.

Yeah, using buffers with good performance can be pretty tricky. Among many other issues, binding’s expensive, and it may be in CPU memory… or may be in GPU memory… you just don’t know and you can’t control it. Argg… Can’t comment on the PBO thing other than that…

…but I would have tried two other options before buffer objects even occurred to me. First, use glBlitFramebuffer with DEPTH_BUFFER_BIT to copy from the depth buffer in one framebuffer to the depthbuffer in another. That target FBO could have a depth buffer that points to either a depth texture or a depth renderbuffer. Assuming std depth buffer format, use DEPTH24_STENCIL8 for the internal format.

Alternatively, use glCopyTexSubImage2D to copy the depth buffer into a depth texture.

Both of those should stay on the GPU (AFAIK).

There’s some information about that on OpenCSG’s website: http://www.opencsg.org/

glBlitFramebuffer works just perfect! thx alot for all your help!