Sign in to follow this  
weasalmongler

ATI Z Buffer problems

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
Quote:
Original post by weasalmongler
I'll see what this yields. Where is the information supposed to appear? The command window?


It depends on what debugger/IDE you're using, but it appears in the "Output" window in MS Visual Studio (the "command" window is for talking to the Visual Studio IDE without needing to go through the menus and to access things that don't appear on the menus).

In the Output window for the "Vertices" SDK sample using the debug runtimes for example I see:

Quote:
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
D3D9 Helper: Enhanced D3DDebugging disabled; Application was not compiled with D3D_DEBUG_INFO
Direct3D9: (INFO) :======================= Hal SWVP device selected

Direct3D9: (INFO) :HalDevice Driver style 9

Direct3D9: (INFO) :Failed to create driver indexbuffer
Direct3D9: (INFO) :Using X3D PSGP



If you're running your application standalone (not always the best plan during development, but sometimes unavoidable), you can also use the [free] DebugView utility from the excellent www.sysinternals.com

Share this post


Link to post
Share on other sites
Thank you S1CA! It turns out that my call to IDirect3DDevice9::SetViewport() set MaxZ to 10.0 rather than 1.0, after I had changed this, the z buffer fixed itself in the reference rasterizer. I am yet to test on my friends ATI machine, but I am pretty confident that this should fix it.

Thank you to everyone who helped with this issue.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this