1
\$\begingroup\$

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
D3DXLoadSurfaceFromSurface(
  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?

\$\endgroup\$
5
  • \$\begingroup\$ as i remember it ( dx9 is not my expertise ) you have to write it manualy, since it was protected by the drivers... \$\endgroup\$
    – Tordin
    Commented Aug 2, 2013 at 9:57
  • \$\begingroup\$ @Tordin: I'm a DirectX newbie. Any pointers on how I can copy it manually? :) \$\endgroup\$ Commented Aug 2, 2013 at 10:00
  • \$\begingroup\$ 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. \$\endgroup\$
    – Tordin
    Commented Aug 2, 2013 at 10:02
  • \$\begingroup\$ @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 \$\endgroup\$ Commented Aug 5, 2013 at 4:18
  • \$\begingroup\$ Are you sure you don't mean GPU instead of CPU? \$\endgroup\$
    – dot_Sp0T
    Commented Jun 8, 2017 at 10:51

2 Answers 2

2
\$\begingroup\$

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.

I don't know why you are trying to use the surface-copying routines as you are, but I don't believe they are necessary.

\$\endgroup\$
0
\$\begingroup\$

For the sake of completeness, the copy is necessary because in general you cannot lock the depth buffer. As far as I know you need your depth buffer to use a lockable format to be able to copy the contained data directly into your own containers. D24S8 for example is a format which prevents locking the depth buffer. (I am not allowed to add comments, so as an answer ...)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .