Wednesday, 10 January 2007

Exception is thrown at Device Reset

Hi there,

In order to get no exceptions when resetting the device, due to a resize or to a FullScreen toggle, you must be sure to have freed every single resource of the device, because for each resource, DirectX mantains an internal counter of references. If any of these counters is not 0 at Reset, it throws an exception and the Reset fails.

Well, in order to make sure this counters are all 0:

1.- Every resource must be Disposed in the OnLostDevice() event.
2.- Every resource must be re-created in the OnResetDevice() event.

BUT: there´s a singularity to this procedure regarding the DepthStencilBuffers.

If you handle depth buffers manually (setting the EnableAutoDepthStencil = false), there´s something you have to be careful with.

When an access to the Device.DepthStencilSurface is done, the API actually calls to the native Device->GetStencilSurface() method. If you take a look at the GetStencilSurface() specs in the SDK C++ docs, you will find that this method increments the resource´s internal reference counter. So:

AFTER TO EVERY SINGLE ACCESS TO Device.DepthStencilSurface, YOU MUST DECREMENT THE REFERENCE COUNTER

If you don´t, you will get an exception at Reset. How to decrement the counter? Calling the Dispose() method.

Example:

1.- ACCESS

Surface mySurface = null;try
{
mySurface = device.DepthStencilSurface;
}
catch {}

........... [ DO YOUR STUFF HERE ] ..................

2.- RELEASE

if(mySurface != null)
{
mySurface.Dispose();
}

1 comment:

Vicente said...

This sounds so familiar :p

Vicente