Skip to main content
1 of 2
Maximus Minimus
  • 20.2k
  • 2
  • 40
  • 69

The old DirectX SDK outlines a method for being able to do this, but it does require that you use Direct3D 9 Ex rather than just plain-old Direct 3D 9. Since 9 Ex is only available on Vista+ this may not suit your requirements.

It's covered in the section titled Feature Summary (Direct3D 9 for Windows Vista) and I'll quote it in full:

Reading Depth/Stencil Buffers

Use IDirect3DDevice9::UpdateSurface to read or write depth/stencil data from surfaces obtained from IDirect3DDevice9::CreateDepthStencilSurface or IDirect3DDevice9::GetDepthStencilSurface.

First, create a lockable, depth only or stencil only surface using IDirect3DDevice9::CreateOffscreenPlainSurface. Use one of the following formats:

  • D3DFMT_D16_LOCKABLE
  • D3DFMT_D32F_LOCKABLE
  • D3DFMT_D32_LOCKABLE
  • D3DFMT_S8_LOCKABLE

Second, transfer data between the depth/stencil buffer and the newly-created lockable depth or stencil surface. The transfer is performed using IDirect3DDevice9::UpdateSurface.

UpdateSurface will fail when both surfaces are a LOCKABLE format or both are non-lockable.

Transferring non-existent data will result in an error (for example, transferring from a non-lockable depth-only surface to a D3DFMT_S8_LOCKABLE surface).

The rest of the restrictions for IDirect3DDevice9::UpdateSurface still apply.

As @Adam suggests in his answer, you really should consider whether or not you actually need to read the depth buffer back to the CPU. That's not going to be a fast operation whichever way you do it.

I'd suggest that you give more detail about why you feel you need to do this, perhaps even making it a separate question; it may well be the case that whatever you're trying to achieve can be done without such a read-back.

Maximus Minimus
  • 20.2k
  • 2
  • 40
  • 69