# How do I deal with timeout detection and recovery in D3D?

What is exactly measured when checking TDR in Windows? What do I need to do in my D3D11 app to tell TDR that long rendering is okay? I've already split the workload into smaller batches, but how do I tell TDR when this batch begins and when it ends?

I know that IDXGISwapChain::Present method will do this for me, but is it the only way? Is ID3D11DeviceContext::Flush method doing the same thing?

• On a side note, I was having constant issues with this until I ripped open my old 6870 and removed the 26 pounds of dust that had accumulated in the heatsink. Most games would just crash and be unplayable but Borderlands/Unreal was smart enough to handle the issue and would keep on trucking after the black-screen/hang every couple of minutes. You might just be having a hardware issue causing it to overheat, clock itself down, take too long for reasonable workloads, and then hit the driver timeout. – Sean Middleditch Nov 22 '13 at 18:06

By "task" in the TDR docs, I believe they essentially mean "draw call or dispatch call". So if a single draw/dispatch takes over 2 seconds, the OS will assume the GPU/driver is crashed and reset it. AFAIK, you shouldn't get TDRs if the work is split into individual draws/dispatches that take less than 2 seconds each.

Also, in D3D 11.1 (Windows 8.0) there is a flag to disable TDR, which can be specified when you create the device. It's D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT, as described on this page.

• it turned out, that all TDR crashes I'm experiencing are NOT caused by long Draw calls, but by the long time between IDXGISwapChain::Present. If I put those calls inbetween my small render chunks, no TDR occurs. – GPUquant Nov 28 '13 at 15:50
• I'm limited to Win7 (and D3D 11) only. One way or another, I don't think long GPU lags (caused by extensive render/processing demands) are a good way to create responsive GUI. – GPUquant Nov 28 '13 at 15:56
• @GPUquant Hmm. Maybe it's the length of a command buffer submission instead of a draw/dispatch. If that's the case, then calling Flush more often should fix it. – Nathan Reed Nov 28 '13 at 20:41
• unfortunately this does NOT work. Flush() was the first thing I was trying to insert between render chunks. No effect. But once I replace those Flush() with Present() - everything works fine and smooth. – GPUquant Nov 29 '13 at 12:34

The best way is to not have a timeout.

TDR is covered at the following MSDN article: http://msdn.microsoft.com/en-us/Library/Windows/Hardware/ff570088%28v=vs.85%29.aspx and is discussed in some detail, including the reasons for it, how it operates, and which registry keys control it.

You can certainly extend the TDR interval beyond the default 2 seconds, but Microsoft themselves advise that:

You can use the following TDR-related registry keys for testing or debugging purposes only. That is, they should not be manipulated by any applications outside targeted testing or debugging.

In other words, fix whatever is causing a TDR during your testing and ship your program without TDRs.

The reason is that the behaviour is by design: it's to assist with misbehaving programs or drivers that lock up the GPU and cause an unresponsive system. By issuing a TDR the OS will at least be returned to the user in an actual usable state and without requiring a hard reboot.

So if you're getting TDRs you've either (1) got a bad driver, or (2) are doing something that takes an abnormally long time.

According to Windows, if a graphics device takes longer than 2 seconds to perform a task, it is hung. If your program is causing the graphics device to TDR, consider upgrading your driver or breaking up the workload into smaller segments.

There is also some TDR registry keys (linked below). However, these are more for debugging purposes: "You can use the following TDR-related registry keys for testing or debugging purposes only. That is, they should not be manipulated by any applications outside targeted testing or debugging."

When a TDR occurs you will get a DirectX device lost error. To recover, you have to recreate your D3D device.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff569918(v=vs.85).aspx (tdr related registry keys)

• I know all this, and because I know that those registry values should not be manipulated I'm asking, what is measured by the TDR. – GPUquant Nov 28 '13 at 15:46