Debugging D3D12 driver crash
Tags: directx, d3d12, direct3d
Published: 2018-09-13 08:51:16

---
title: Debugging D3D12 driver crash
published: true
tags: directx,d3d12,direct3d
canonical_url: http://asawicki.info/news_1690_debugging_d3d12_driver_crash.html
---

New generation, explcit graphics APIs (Vulkan and DirectX 12) are more efficient, involve less CPU overhead. Part of it is that they don't check most errors. In old APIs (Direct3D 9, OpenGL) every function call was validated internally, returned success of failure code, while driver crash indicated a bug in driver code. New APIs, on the other hand, rely on developer doing the right thing. Of course, some functions still return error code (especially ones that allocate memory or create some resource), but those that record commands into a command list just return `void`. If you do something illegal, you can expect undefined behavior. You can use Validation Layers / Debug Layer to do some checks, but otherwise everything may work fine on some GPUs, you may get incorrect result, or you may experience driver crash or timeout (called "TDR"). Good thing is that (contrary to old Windows XP), crash inside graphics driver doesn't cause "blue screen of death" or machine restart. System just restarts graphics hardware and driver, while your program receives `DXGI_ERROR_DEVICE_REMOVED` code from one of functions like `IDXGISwapChain::​Present`. Unfortunately, you then don't know which specific draw call or other command caused the crash.

NVIDIA proposed solution for that: they created [NVIDIA Aftermath](https://developer.nvidia.com/nvidia-aftermath) library. It lets you (among other things) record commands that write custom "marker" data to a buffer that survives driver crash, so you can later read it and see which command was successfully executed last. Unfortunately, this library works only with NVIDIA graphics cards.

Some time ago I showed a portable solution for Vulkan in my post: ["Debugging Vulkan driver crash - equivalent of NVIDIA Aftermath"](http://asawicki.info/news_1677_debugging_vulkan_driver_crash_-_equivalent_of_nvidia_aftermath.html). Now I'd like to present a solution for Direct3D 12. It turns out that this API also provides a standardized way to achieve this, in form of a method [ID3D12GraphicsCommandList2::​WriteBufferImmediate](https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12graphicscommandlist2-writebufferimmediate). One caveat: This new version of the interface requires:

- User to have at least Windows 10 Fall Creators Update.
- Developer to have Windows SDK in version at least for Windows 10 Fall Creators Update.
- Developer to use Visual Studio 2017 - required by this version of Windows SDK.

I created a simple library that implements all the required logic under easy interface, which I called [**D3d12AfterCrash**](https://github.com/sawickiap/MISC/tree/master/D3d12AfterCrash). You can find all the details and instruction for how to use it in file "D3d12AfterCrash.h".

I guess it would be better to allocate the buffer using WinAPI function `VirtualAlloc(NULL, bufferSize, MEM_COMMIT, PAGE_READWRITE)`, then call `ID3D12Device3::​OpenExistingHeapFromAddress` and `ID3D12Device::​CreatePlacedResource`, but my simple way of just doing `ID3D12Device::​CreateCommittedResource` seems to work - buffer survives driver crash and preserves its content. I checked it on AMD as well as NVIDIA card.