Depth Buffer Access

Rayne

Newcomer
Hello,

I'm trying to read the depth buffer in a Direct3D 8 application.

According to the documentation, this is only possible with the D3DLOCK_D16_LOCKABLE format.

The problem is that the application uses a D3DFMT_D24S8 format (and i cannot change it, because it creates serious artifacts during the rendering).

I have been trying several tricks like CopyRect from the Depth Buffer surface to a new surface, LockRect with different flags, creating the Depth Buffer as a texture with D3DUSAGE_DEPTHSTENCIL, ...

I wanted to create my own fake version of AO, but i guess that without reading the z values that i need, it's going to be impossible.

Does anybody know a trick to read the Z values from D3D8 ? Maybe with a shader that uses the depth buffer in a texture stage, and writes the Z values to a new texture with render target flags. Did anybody success to this in the past ?

Thank you very much !
 
You can't sample depth buffers in DX8 pixel shaders. But you can output depth values to a color render target texture from the pixel shader like you usually do with DX9 hardware that does not have depth buffer sampling support. Unfortunately DX8 does not support floating point render targets (and cannot sample floating point textures either), so you have to pack the depth value to a A8R8G8B8 texture (this will waste some instruction slots, but should be doable on PS 1.4 at least).
 
I just need to copy the depth buffer to the system memory. I will post process the info with the CPU.

An user told me that there was a function to copy directly from a (non-lockable) Z buffer surface to a color surface, but he was not sure not sure whether current drivers still support it or not. If somebody can remember it. It would be great.

I can't rewrite all the shaders, because this is part of my BR2 Patch (it's a hook between the game & the D3D8.dll).

Is it possible to copy the depth buffer or to access to the Z buffer samples from Direct3D9 ? Because i could try to write a Direct3D8 to Direct3D9 wrapper for the game only.

Thank you :)
 
D3D8 has CopyRects, D3D9 has StrechRect and D3D10 has CopySubresourceRegion. None of which does format conversions that you want. You could output Z from a shader as sebbbi suggested, but as you figured out that would be hard for what you're doing.
You can sample from Z buffer due to driver tricks, but this will get you PCF and not just depth values. You might have some luck with gather/fetch4 which I think is exposed through a special fourCC format...
 
Ok,

I found a 'partial' solution:

IDirect3DTexture8 *depthStencil_Texture;
m_pIDirect3DDevice8->CreateTexture(width, height, 1, D3DUSAGE_DEPTHSTENCIL, ((D3DFORMAT) MAKEFOURCC('I','N','T','Z')), D3DPOOL_DEFAULT, &depthStencil_Texture);

IDirect3DSurface8 *depthStencil_Surface;
depthStencil_Texture->GetSurfaceLevel(0, &depthStencil_Surface);

m_pIDirect3DDevice8->SetRenderTarget(renderTarget, depthStencil);

// Do the normal render of the game ....

At the end of the rendering (when the game calls to the ::present() method), i do this:

m_pIDirect3DDevice8->SetTexture(0, depthStencil_Texture);

& i set a D3DFMT_A8R8G8B8 new render target, and a pixel shader that does a 'texld r0, t0'.

At the end i have a render target with the INTZ values, and i can post process it later with the CPU or with my CUDA code.

But, there is a huge problem -> MultiSampling does NOT work ! :cry:

I need to turn off MultiSampling to bind the 'depthStencil_Surface' with my 'renderTarget' :cry:

So, atm, this works, but, it's useless for my project, because i lose the FSAA.

Also, i still dunno how to convert the INTZ values, but, at least i can read them.

Any tip ?
 
Last edited by a moderator:
Sorry for the thread bump, I'm just wondering if anyone knows if INTZ and/or RAWZ are available on Intel GMA chipsets?

There really isn't much information about these formats on the web.
 
Back
Top