A Microsoft Direct3D device can be in either an operational state or a lost state. The operational state is the normal state of the device, in which the device runs and presents all rendering as expected. The device makes a transition to the lost state when an event, such as the loss of keyboard focus in a full-screen application, causes rendering to become impossible. The lost state is characterized by the silent failure of all rendering operations, which means that the rendering methods can return success codes even though the rendering operations fail. In this situation, the Device.DeviceLost event is triggered.
By design, the full set of scenarios that can cause a device to become lost is not specified. A typical example is a loss of focus, such as when the user presses ALT+TAB or a system dialog is initialized. Devices can also be lost due to a power management event, or when another application assumes full-screen operation. In addition, any failure from Device.Reset puts the device into a lost state.
The following two exception objects may be handled:
- DeviceLostException: This object indicates that the device has been lost but cannot be reset, so rendering is not possible.
- DeviceNotResetException: This object indicates that the device has been lost but can be reset at this time.
Responding to a Lost Device
A lost device must re-create resources (including video memory resources) after it has been reset. If a device is lost, the application queries the device to see if it can be restored to the operational state. If not, the application waits until the device can be restored.
If the device can be restored, the application prepares the device by destroying all video-memory resources and any swap chains. Then, the application calls the Reset method. Reset is the only method that has an effect when a device is lost, and is the only method by which an application can change the device from a lost to an operational state. The method will fail unless the application releases all resources that are allocated in Default, including those created by the CreateRenderTarget and CreateDepthStencilSurface methods.
For the most part, the high-frequency calls of Direct3D do not return any information about whether the device has been lost. The application can continue to call rendering methods, such as Device.DrawPrimitives, without receiving notification of a lost device. Internally, these operations are discarded until the device is reset to the operational state.
The application can determine whether a device is lost by querying the return value of the CheckCooperativeLevel method.
Internally, Direct3D does enough work to ensure that a lock operation will succeed after a device is lost. However, it is not guaranteed that the data of the video-memory resource will be accurate during the lock operation. It is guaranteed that no error code will be returned. This allows applications to be written without concern for device loss during a lock operation.
Resources can consume video memory. Because a lost device is disconnected from the video memory owned by the adapter, it is not possible to guarantee allocation of video memory when the device is lost. As a result, all resource creation methods allocate only dummy system memory. Because any video-memory resource must be destroyed before the device is resized, there is no issue of over-allocating video memory. These dummy surfaces allow lock and copy operations to appear to function normally until the application calls Device.Present and discovers that the device has been lost.
All video memory must be released before a device can be reset from a lost state to an operational state. This means that the application should release any swap chains created with SwapChain and any resources placed in Pool.Default memory. The application need not release resources in Managed or SystemMemory memory. Other state data is automatically destroyed by the transition to an operational state.
You are encouraged to develop applications with a single code path to respond to device loss. This code path is likely to be similar, if not identical, to the code path taken to initialize the device at startup.
Direct3D allows applications to validate texture and render states against single-pass rendering by the hardware using ValidateDevice. This method, which is typically invoked during initialization of the application, will return a DeviceLostException object if the device has been lost.
Direct3D also allows applications to copy generated or previously written images from video-memory resources to nonvolatile system-memory resources. Because the source images of such transfers might be lost at any time, Direct3D allows such copy operations to fail when the device is lost.
Copy operations, using UpdateSurface and GetFrontBufferData, can return a DeviceLostException object when the source object is in volatile memory (Pool.Default) and the destination object is in nonvolatile memory (SystemMemory or Managed). A GetFrontBufferData call can fail due to retrieving data from the primary surface. Note that these cases are the only instance of DeviceLostException that will be returned outside of the Present, TestCooperativeLevel, and Reset methods.
In Microsoft DirectX 9.0, Vertex Shader 1_1 and Pixel Shader 1_X do not need to be re-created after Device.Reset is called. They will be remembered. In previous versions of DirectX, when a device was lost, shaders had to be re-created.