1
\$\begingroup\$

I get the DXGI_ERROR_DEVICE_REMOVED error on some machines. According to this (https://msdn.microsoft.com/en-us/windows/uwp/gaming/handling-device-lost-scenarios) MSDN article this can happen and it should be handled by your application.

I've managed to recreate the device but I'm unsure how to handle all content. It seems I have to create all vertex buffers and textures again, which essentially means I have to reload almost the entire scene. Is this really the correct way?

\$\endgroup\$
4
\$\begingroup\$

There are two places you can potentially get this scenario: When calling ResizeBuffers or Present and you get either DXGI_ERROR_DEVICE_REMOVED or you get DXGI_ERROR_DEVICE_RESET. In both cases, the video device and driver have been fully reset and all video resources are lost: render targets, textures, vertex buffers, index buffers, etc.

When this happens, you have two choices:

  • Release all Direct3D and DXGI objects and start over including recreating all Direct3D resources

  • Display an error to the user and tell them to restart

The first one is nicer for the user. Many games just return to the initial menu with an error message--assuming they don't just crash out like many of the less robust PC console ports do because you never encounter device removed on the Xbox One.

In general this shouldn't happen all that often, but it does happen. The most common reason is that a user leaves your game running when Windows Update installs a new driver in the middle of the night--or as is often the case, while someone is up way past bedtime gaming. The other case happens because of driver bugs or if you have a DirectCompute shader that is too complex to run within the timeout.

For Universal Windows Platform apps, this scenario happens a little more often because it is used to handle migration of displays in laptops, tablets, phones, etc. This can also happen when you are resumed from a suspended state.

The best way to test your application is to open a Visual Studio Developer Command Prompt with administrator rights, and with your application running issue this command:

dxcap -forcetdr

Remember this will cause removed device for all apps running as it's system-wide including your debugger if you are using local debugging.

Take a look at the Direct3D Game VS Templates including the DeviceResources class for details on detecting and handling this properly.

    HRESULT hr = /*m_swapChain->ResizeBuffers(...) or m_swapChain->Present(...) */

    if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
    {
#ifdef _DEBUG
        char buff[64] = {};
        sprintf_s(buff, "Device Lost: Reason code 0x%08X\n",
        (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
        OutputDebugStringA(buff);
#endif
        // If the device was removed for any reason, a new device
        // and swap chain will need to be created.
        HandleDeviceLost();
    }
    else
    {
        // Any other failed result is a fatal fast-fail
        DX::ThrowIfFailed(hr);
    }

Note this applies to both DirectX 11 and DirectX 12

\$\endgroup\$
1
\$\begingroup\$

While Chuck's answer is correct, you can cause a device removed error through mistakes in your own code. Stuff to look out for includes vertex indexes out of bounds and bad mapping of buffers.

Call ID3D11Device::GetDeviceRemovedReason to get a more detailed error code. If it returns one of the below, you may be the cause rather than a random driver upgrade:

  • DXGI_ERROR_INVALID_CALL: The application provided invalid parameter data. If you get this error even once, it means that your code caused the device removed condition and must be debugged.

  • DXGI_ERROR_DEVICE_HUNG: The graphics driver stopped responding because of an invalid combination of graphics commands sent by the app. If you get this error repeatedly, it is a likely indication that your app caused the device to hang and needs to be debugged.

  • DXGI_ERROR_DEVICE_RESET: The graphics device failed because of a badly formed command. If you get this error repeatedly, it may mean that your code is sending invalid drawing commands.

There are also these:

  • DXGI_ERROR_DEVICE_REMOVED: The graphics device has been physically removed, turned off, or a driver upgrade has occurred. This happens occasionally and is normal; your app or game should recreate device resources as described in this topic.

  • DXGI_ERROR_DRIVER_INTERNAL_ERROR: The graphics driver encountered an error and reset the device.

Source: https://docs.microsoft.com/en-us/windows/uwp/gaming/handling-device-lost-scenarios

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.