ATI Z Buffer problems

Started by
10 comments, last by weasalmongler 17 years, 6 months ago
Hi everyone, I was wondering if you could help me with a problem that has just come up. I've been developing a game on my NVIDIA hardware, and everything works fine, but a friend recently tested and noticed that essentially, the depth buffer appears to be switched off on his ATI hardware. I decided to run it through the reference rasterizer and the problem came up, so it's more likely a problem with the nvidia drivers being too lenient rather than a problem with ATI's drivers. I've put checks in to every state change that takes place and it doesn't throw any errors. I also believe that I am creating the Z buffer in a pretty standard way, so I don't believe this can be the problem. I've posted some of my Z buffer creation code in case the cause is there.


d3dpp.Windowed               = !m_bFullscreen;
d3dpp.EnableAutoDepthStencil = FALSE;
d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferWidth        = m_iWidth;
d3dpp.BackBufferHeight       = m_iHeight;
d3dpp.BackBufferFormat       = D3DFMT_X8R8G8B8;
d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

//Create Reference Rasterizer
if( FAILED( m_lpD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, m_hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_lpD3D9Device ) ) )
{
	MessageBox(NULL,"Cannot Create DirectX 9 Device!", "ERROR",MB_OK|MB_ICONEXCLAMATION);
	return false;
}


//Create the depth buffer
IDirect3DSurface9* pSurface;

m_lpD3D9Device->CreateDepthStencilSurface(m_iWidth,m_iHeight,D3DFMT_D24X8, d3dpp.MultiSampleType, 0, false, &pSurface, NULL);

m_lpD3D9Device->SetDepthStencilSurface( pSurface );

Can anybody think of any other reasons why this would be failing? I've been pulling my hair out over this one. Thanks in advance.
Advertisement
d3dpp.EnableAutoDepthStencil = FALSE;

Without anymore code, I going to guess that this might be the problem.

Edit: You may also want to make sure you're clearing the Z Buffer or set RenderState.ZBufferEnable(whatever the C++ equivalent is) to true.
I don't create it with an automatic depth stencil buffer, I attach my own in the little bit under where I create the device. I have also tried creating it with the automatic depth stencil buffer, but I get the same results.

Thanks though.
A long shot, but a good idea even if this isn't your problem:
Make sure you call CheckDepthStencilMatch to make sure the framebuffer format and depthstencil format match. There are sometimes issues with specific pairs that might make them compatible or incompatible on different hardware.

Also, are you certain z-buffering is turned off? Could this be some other issue that only looks similar?
You could make sure all the default renderstates are as you expect them (ZFunc, ZWriteEnable, etc), though that sounds unlikely.
Make sure your znear is not set to 0.0f

Other than that, I can't think of much else that might disable the z-buffer.

Anyways, hope this helps.
Sirob Yes.» - status: Work-O-Rama.
Hi,

I tried adding the check function into the startup code, and it didn't throw any errors, so I don't think that is the problem.

I've already made sure that the states are set up correctly initially, there are all definately initialized to the correct thing. I thought it might have been a problem with z-writing and other state switching stuff, but I have tried removing all calls that change the z buffer state after the initial set up, but the z buffer still appears to not be working, leading me to believe that the states are being switched ok or aren't being set correctly the first time.

I'm not really sure how to go about finding the error. Is there a way of querying DirectX to find the last error generated by any function?

Thanks.
Quote:Original post by weasalmongler
I'm not really sure how to go about finding the error. Is there a way of querying DirectX to find the last error generated by any function?
Nope. If you're using the debug runtimes, D3D will spit out errors to the debug output, or you can check the return value of every function.

As for the problem, have you tried using another format other than D3DFMT_D24X8? Such as D3DFMT_D24S8? Although that shouldn't really cause any issues...
Yup, I've tried D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D16, and I believe those are the only variants that my card supports. I'm pretty sure I'm running the debug runtimes and they aren't showing anything in the console. It's very strange.

Thanks.
Quote:Original post by weasalmongler
Yup, I've tried D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D16, and I believe those are the only variants that my card supports. I'm pretty sure I'm running the debug runtimes and they aren't showing anything in the console. It's very strange.

Thanks.
Are you getting any debug output from D3D? Like, "Selected REF device" or whatever?
If not, you might need to upgrade your SDK, since your SDK version needs to be at least as new as the runtime version.

What SDK are you using?
I've just realized that I'm way back on December 2005 for the DirectX SDK. I'm downloading the latest version now (500MB :( ), maybe this will get it working properly. I'll see what this yields. Where is the information supposed to appear? The command window?

Thanks.
Some more thoughts in addition to what the others have said (particularly Steve's comments about SDK versions and debug spew - you should always get some '(INFO)' spew even if you don't get errors):

- are you remembering to specify D3DCLEAR_ZBUFFER when you IDirect3DDevice9::Clear()?

- is the Z value you fill the depth buffer with during IDirect3DDevice9::Clear() anything other than 1.0?

- as was touched on earlier, is your projection matrix 'sane'? i.e. near clip plane shouldn't be 0 (the greater the better), and the distance/ratio between near and far shouldn't be so massive it bunches almost all the Z resolution up into the tiny range nearest the camera.

- D3DRS_CULLMODE being set to NONE or being inside-out can look surprisingly similar to some [non-sorted-ness] Z buffer artifacts.

- Do you call IDirect3DDevice9::SetViewport() anywhere?, if so, are the MinZ and MaxZ anything other than 0.0 and 1.0 respectively?

- If you're using shaders, be certain that the Z and the W from the output position of your vertex shader is correct (different hardware can do subtley different things when it comes to interpolation and depth buffering).

- Have you tried letting D3D 'auto' create the depth-stencil to see if that works. That should tell you whether it's something you're missing or doing in the wrong place with respect to set up or whether it's something later like render state.

- Put a call to IDirect3DDevice9::GetDepthStencilSurface() immediately before your Draw* call and see what it returns i.e. do you get an error, or do you get an S_OK - and does the pointer returned tally with the pointer of the surface you set earlier.

- PIX for Windows is a great tool. That will let you see what the contents of the depth buffer look like, and give you a nice flattened view of the exact order of calls that you don't always see in your own code (e.g. you PIX it and notice that the SetDepthStencilSurface() is happening after the draw call, etc).

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

This topic is closed to new replies.

Advertisement