3
\$\begingroup\$

My application uses DX11 and it periodically gets a DXGI_ERROR_DEVICE_REMOVED error on startup. It is an infrequent thing (I can go days or weeks without seeing it) but according to the documentation here it should be expected and handled smoothly.

Because it is so infrequent I cannot debug or test this scenario. I have tried changing video card settings while the app is running, switching users, etc. I cannot seem to trigger it. What can I do?

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

The documentation you linked calls out the four most common reasons for a device reset:

  • the device is physically removed from the system
  • the device gets into a bad state and must reset
  • the system switches between two onboard GPUs (low to high power, for example)
  • the drivers are upgraded

You probably don't want to physically remove the device to stimulate the error, as most consumer PCs are not set up to safely hot-swap that way. Similarly it's not that easy to make the device crash and have to reset. Toggling GPUs is easy enough, usually, if you have them and have the ability to force the machine to use one or the other, but that's pretty hardware-dependent.

So you should update your drivers to trigger the error. Downgrading drivers should work as well, so you can just toggle between two driver versions while your code is executing to make sure you react correctly.


Note that you can just wrap the calls that might return DXGI_ERROR_DEVICE_REMOVED, ignore their actual return value, and pretend it was DXGI_ERROR_DEVICE_REMOVED on a temporary basis. This can be a quick way to test that the code path for handling the error works at the most basic level, although it is still good to check by stimulating the error for real, because the real error will come with side-effects that are much harder for you to simulate.

\$\endgroup\$
  • \$\begingroup\$ In the future this may not work out. My Intel card's version was somehow between two major versions. I upgraded the driver and I got an "out of memory" error in my application. I restarted the PC. Then I downgraded the driver to the one below my original, and it worked, I got the DXGI_ERROR_DEVICE_REMOVED. Without restarting I upgraded to the latest again, and again had an out of memory error. I would guess the latest Intel driver installer is attempting to bypass ugly "device removed" errors... but isn't yet perfect so I'm getting the "out of memory" stuff. \$\endgroup\$ – DAG Sep 11 '15 at 17:06
  • \$\begingroup\$ It can be a bit flaky, yes, and it's unfortunate there isn't (afaik) a better way to test one's codepath for this. If the number of crashes for shipped commercial titles that reference the device-removed error is any indication, very few people test this well. :( \$\endgroup\$ – Josh Sep 11 '15 at 17:09
2
\$\begingroup\$

One reliable way to cause device-removed is to intentionally trigger the TDR mechanism from another process in the system. You can do this by dispatching a compute shader containing an infinite loop, such as the following:

cs.hlsl

RWBuffer<uint> dummyUAV;
cbuffer dummyCB {uint zero;}
[numthreads(256, 1, 1)]
void main(uint3 id : SV_DispatchThreadID)
{
    [loop] while (zero == 0) dummyUAV[id.x] = zero;
}

main.cpp

#include <d3d11.h>
#include "cs.h"

int main(int argc, char* argv[])
{
    ID3D11Device* dev = nullptr;
    ID3D11DeviceContext* con = nullptr;
    D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &dev, nullptr, &con);
    ID3D11ComputeShader* cs = nullptr;
    dev->CreateComputeShader(g_main, sizeof(g_main), nullptr, &cs); // from compiled cs.h
    con->CSSetShader(cs, nullptr, 0);
    con->Dispatch(256, 1, 1);
    con->Flush(); // hangs then TDRs
    return 0;
}
\$\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.