# How do I copy the depth buffer to CPU memory in Direct3D 9?

I have code in OpenGL that uses glReadPixels to copy the depth buffer to a CPU memory buffer:

glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, dbuf);


How do I achieve the same in Direct3D?

I have looked at a similar question which gives a solution for copying the color buffer. I've tried to write similar code to copy the depth buffer:

IDirect3DSurface9* d3dSurface;
d3dDevice->GetDepthStencilSurface(&d3dSurface);

D3DSURFACE_DESC d3dSurfaceDesc;
d3dSurface->GetDesc(&d3dSurfaceDesc);

IDirect3DSurface9* d3dOffSurface;
d3dDevice->CreateOffscreenPlainSurface(
d3dSurfaceDesc.Width,
d3dSurfaceDesc.Height,
D3DFMT_D32F_LOCKABLE,
D3DPOOL_SCRATCH,
&d3dOffSurface,
NULL
);

// FAILS: D3DERR_INVALIDCALL
d3dOffSurface,
NULL,
NULL,
d3dSurface,
NULL,
NULL,
D3DX_FILTER_NONE,
0
);

// Copy from offscreen surface to CPU memory ...


The code fails on the call to D3DXLoadSurfaceFromSurface. It returns the error value D3DERR_INVALIDCALL.

So, is something wrong with my code? How can I copy the depth buffer contents?

• as i remember it ( dx9 is not my expertise ) you have to write it manualy, since it was protected by the drivers... – Tordin Aug 2 '13 at 9:57
• @Tordin: I'm a DirectX newbie. Any pointers on how I can copy it manually? :) – Ashwin Nanjappa Aug 2 '13 at 10:00
• I think you had to write it yourself, so when you are writing models you had to write to a specific buffer to store depth in. – Tordin Aug 2 '13 at 10:02
• @Tordin: A MSDN page on Vista display drivers seems to imply that drivers have to support copying depth buffer: msdn.microsoft.com/en-us/library/windows/hardware/ff540530.aspx – Ashwin Nanjappa Aug 5 '13 at 4:18
• Are you sure you don't mean GPU instead of CPU? – dot_Sp0T Jun 8 '17 at 10:51

Per the documentation, you can acquire a reference to the depth-stencil surface for the device (if one exists for that device) by calling GetDepthStencilSurface. If the method returns successfully, you can lock the bits of the resulting surface using the LockRect method of the surface interface.
This gives you a locked rectangle with the bits of the surface accessible via the pBits member. You will need to use the Pitch as well as surface format information obtained from GetDesc to interpret the bits correctly.