Sign in to follow this  
BinaryStylus

Clearing Depthstencil Error

Recommended Posts

BinaryStylus    133
Hi, I'm getting a bit of an error, and I haven't had much luck getting a solution on the Net at large. I'd love any ideas you might have!
DepthStencil Buffer must be at least as big as the RenderTarget


This happens when I do this
if(flGraphics){flag |= D3DCLEAR_TARGET;}
	if(flZBuffer){flag |= D3DCLEAR_ZBUFFER;}
	if(flStencil){flag |= D3DCLEAR_STENCIL;}
	pclD3DDevice->Clear(0,0,flag,stColour,1.0f,0);


All the flags are true. The D3D Device has been aimed at
if(FAILED(pstCounter->pstSwapChain->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pclSurface))){return(0);}
pclD3DDevice->SetRenderTarget(0,pclSurface);
pclSurface->Release();


Where the pstSwapChain is a D3D swapchain object pointer and is another render window - with identical size to the to the primary window and using a copy of its presentation parameters. What is weird is that the "main" window (the one that is supplied to CreateDevice) works fine. I would really appreciate any suggestions, Thanks

Share this post


Link to post
Share on other sites
BinaryStylus    133
Yes - I'm not rendering though - not yet - I'm just getting a 4 view rendering environment setup.

I have my main D3D Device - on one window - Fine. And then three D3DDevice->CreateAdditionalSwapChain off of it - each with its own Presentation parameters with the target window set to its new target window - and all the windows are an Identical size (width height set to zero on creation).

Now - when I clear them - The only window that clears is the one that was supplied as a parameter to D3D->CreateDevice. And I simply set the render target as shown above.

What is weird is that my Radeon 9600 works fine, (All windows update - no errors) - how ever my little SiS 650 will only update the one window.

Weird! - I guess my code is flawed and the more advanced Radeon drivers just fix the error on the fly. However the Reference drivers - run on either machine do the same - ?

Cheers

Share this post


Link to post
Share on other sites
sirob    1181
Since you're using Swap chains, I you likely havn't created an AutoDepthStencil buffer. When you use SetRenderTarget, you are only setting the render target from the frame buffer (color portion of the frame). If you want to use a stencil buffer, you'll need to also create a DepthStencil buffer seperately, and set it to the device.
If you don't want to use a stencil buffer, just remove the stencil flag from your clear call.

Hope this helps :).

Share this post


Link to post
Share on other sites
BinaryStylus    133
Whoa!

Err - That's really interesting. So even though you specify PresentationParameters, (with the DepthStencil format entry set), for CreateAdditionalSwapChain - you only get graphics? If you want an additional Depth buffer - you have to make one?

I'll look into it - What are the implications for D3DDevice->SetRenderTarget? How do you tell it to render the depth to an alternative Depth Buffer?

Cheers - I'll look into this!

Share this post


Link to post
Share on other sites
sirob    1181
Ahhh, I'm not really sure what happens when you specify it in the Presentation Parameters, but I do recall something about only one being created when you create extra swap chains.

If you did specify a AutoDepthStencil buffer in the presentation parameters, and all windows are the same size, and you never called SetDepthStencil, you should be good, if that's what you're doing, I'm not sure what's up.

You can use SetDepthStencil (or something like that, don't have the SDK handy), to set the current DepthStencil buffer.

Hope this helps.

Share this post


Link to post
Share on other sites
You cannot use AutoDepthStencil on a swapchain, only the main device. Why? There's no way to access the depth buffer to set it as the active depth surface.

When using the main device, you can always call GetBackBuffer() and GetDepthStencilSurface(). You can then pass these values into SetRenderTarget and SetDepthStencilSurface to activate them.

When using a swap chain, there is no way to ask it what the auto created depth surface is. I'm not sure if even makes one, but if it does, it's just wasted video RAM. You must make your own depth surface, via CreateDepthStencilSurface in the device, and swap between depth surfaces just like you're swapping between render surfaces.

You probably want to grab the device's surface upon creation (and possibly again after a reset). If you set another depth surface as being active, I'm not sure if you can get back the pointer to the one the device was created with.

You should also SetViewport() whenever you change render targets. DX8 automatically did a SetViewport to the full surface on a call to SetRenderTarget. DX9 *DOES NOT* do this.

Also, be aware there appears to be a problem using depth surfaces larger than the one created with the device (ie: swapchain or nVidia depth shadow map are larger than your device's backbuffer size), but only when using the debug runtimes. I've submitted a small repro case to MS, so hopefully that'll get fixed soon.

Share this post


Link to post
Share on other sites
BinaryStylus    133
Hi,
Thanks to everyone who helped me!. This post is just FYI incase anyone should every look this up.

I started out checking pointers and looking at what was going on by calling the descriptions of the surfaces - it took a day - and I've learnt a lot.

I only had One DepthStencil surface and it was the size of the Device Window, which should have been OK as the other three child windows were all supposed to be the same size.

However - In effect the Child Windows that the swapchains used as their render targets were weird sizes because the DirectX code was executed before the MessageHandler: The child windows hadn't yet run thier initial WM_SIZE messages. So that was the true nature of the problem.

The solution was to simply make additional DepthStencil buffers and store their pointers along with their Swapchain pointers. Also I stored the origional DepthStencil buffer's pointer - so I could swap back to it when the Device window became the render target.

Notes
=====

Namethatnobodyelsetook's comment: If you set another depth surface as being active, I'm not sure if you can get back the pointer to the one the device was created with. // Totally - which is why I needed to get a pointer to the Device's DepthStencil surface. Changing the depth target decreases the count on the old surface's interface - so if you don't grab a pointer to the origional Depth surface it is destroyed when you assign a new DepthStencil buffer.

Cheers Namethatnobodyelsetook!

Additionally - the Radeon card was running as a PureDevice - run not as a PureDevice it too had the issue - So it seems that its drivers were fixing my Depth buffer size problem automatically - nice.

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