DirectX:Direct3D:Tutorials:VBNET:DX9:Handling Device Loss

From GPWiki

Files:GUITutorial_warn.gif The Game Programming Wiki has moved! Files:GUITutorial_warn.gif

The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server.

However, the GPWiki forums are still active! Come say hello.

Handling Device Loss In Managed Direct3D

When you make a fullscreen Direct3D game, your program takes exclusive control of the Device. Your game will lose exclusive control whenever your game loses focus. When your program tries to render as normal, it will throw an error message. In order to continue rendering, your device needs to be reset, and exclusive control needs to be regained.

You'll need a boolean variable to keep track of whether or not the device is currently lost:

Private DeviceLost As Boolean    'For handling device loss 


You need to check and see if the device is currently lost at the beginning of your render sub. It should look like this:

Public Sub Render()
 
        'check for device loss
        If DeviceLost Then
            AttemptRecovery() ' this is obvious, isn't it?
        End If
 
        If DeviceLost Then 'if device is still lost, then forget it for now
            'if you want your program to do something while the device is lost, you can tell it here
        End If

That will check and if the device is lost, then check to see if Attempt recovery worked. The second part is optional. Now, when you present your device, you need to handle DeviceLostException, which will be thrown if you don't have exclusive control. My code looks like this:

Try
            graphicsdevice.Present()    'draw device contents to screen
        Catch e As DeviceLostException
            'AAACK! We lost the device!
            DeviceLost = True
        End Try

If you no longer have exclusive control, DeviceLost will be set to true; therefore your render sub will call the AttemptRecoverey subroutine the next time you try to render your graphics. Now let's look at AttemptRecoverey:

Private Sub AttemptRecovery()
        ' when we lose the device, this code will run
 
        Try
            graphicsdevice.TestCooperativeLevel()  'Test for Exclusive control; if it's lacking, it'll throw
        Catch e As DeviceLostException     'DeviceLostException. If it does, we just wait until
            'Failed.                       'our game is given the focus again.
        Catch e As DeviceNotResetException  'If we have the focus, we only need to reset the device:
 
            ' Basically we re-do what we did in initialize graphics
            Try
                'Here, you need to destroy everything in Pool_Default, and all instances of the
                ' swapchain class.
 
                graphicsdevice.Reset(presentParams) 'reset the device, so we can use it again
                DeviceLost = False    'device is no longer lost!!!
 
                'Now recreate all your Pool_Default stuff, and your swapchain instances.
 
            Catch bug As DeviceLostException  'it is possible to lose the device while resetting it.
                'if it got lost again or not reset, do nothing
            End Try
        End Try
    End Sub 'AttemptRecovery 

Looks nasty, but there's a reason for all that junk. First we test the cooperative level. If that throws Devicelostexception again, there’s no point in even trying to reset the device. If it throws DeviceNotReset, then we reset the device, and everything in Pool_Default. (This code was from a game that used only D3DX_Sprite objects, so nothing was destroyed and recreated).

This is done by destroying the objects( setting them to nothing), and re-loading all the info. Sucks, huh? After we do all that, we check for deviceloss again just in case it died while we were resetting the device.

It is hard to understand. I beat my head against it again and again before I managed to get it working. If you still have problems, check out the links on the bottom of this page, or ask around at the forums.

I hope this very rough tutorial is of some help to somebody. Feel free to change it, or replace it with a superior one.


--Lachlan87 15:46, 2 Dec 2004 (EST)


External Links

MSDN Article On Lost Devices

DirectX4VB.com

Blog On Lost Devices