Debugging DirectX Graphics
Visual Studio contains diagnostic tools that you can use to help solve rendering problems in DirectX-based games and apps.
Debugging rendering problems in a game or app is usually not as easy as starting a debugger and stepping through code. Diagnosing graphics rendering problems presents several unique challenges. For example, in any given frame, hundreds of thousands—if not millions—of pixels are produced as output and several times more than that might be produced but never seen—of these, perhaps only a few pixels will exhibit the problem you are trying to diagnose. In addition, there might be several gigabytes of data behind every rendered frame, and to complicate matters even further, all of this data is processed on dedicated hardware that splits the work among hundreds or thousands of specialized processing units, all of which are outside the direct observation of the Central Processing Unit (CPU). Traditional debuggers just aren't built to solve these kinds of challenges.
The Graphics Diagnostics tools in Visual Studio are designed to help you locate the source of rendering problems by starting with the visual artifacts that indicate the problem and then tracing backward through the related shader code, graphics pipeline, draw calls, resources, and device state, and even through the app's own source code.
Here are some of the kinds of rendering problems that Visual Studio can help you with.
Correct configuration of the graphics device is important because it sets the expectations that model and texture data must meet throughout the entire app. For example, if the device state specifies the winding order as clockwise, then any model that specifies vertices in a counter-clockwise direction will not be rendered correctly; or, if the depth-test function has been set to greater-than, objects that are further away will be drawn on top of objects that are closer. Device state problems can be difficult to diagnose because the root of the problem in the source code is often far removed from the affected objects.
Graphics Diagnostics can help you examine the data and device state behind the affected pixels so that you can narrow in on device state problems.
Making a mistake in app code is almost inevitable, whether the code is C++ or High Level Shader Language (HLSL). However, debugging HLSL code has traditionally been more difficult because it hasn't had the rich debugging support that C++ and other languages enjoy.
Graphics Diagnostics can help you find and fix shader bugs because it makes it possible to debug HLSL code. By using information that's captured in a graphics log, the HLSL debugger can "replay" draw events at the shader level so that you can step through execution, set breakpoints, and examine the contents of temporary variables, parameters, and constant buffers. To help you focus on the right thing, Graphics Diagnostics provides entry points to the HLSL debugger from draw events (through the Graphics Pipeline Stages window), and from individual pixels (through the Graphics Pixel History).
Graphics apps use constant buffers and parameters to render different objects in different positions and orientations, or with different appearances. When a constant buffer or a parameter has not been initialized, or when it contains incorrect values, the corresponding object is rendered incorrectly, or perhaps not at all. This kind of problem can be difficult to diagnose because it's not always clear whether the error is caused by a problem with a constant buffer or a parameter, or by a shader bug. It can also be difficult to determine which shaders, constant buffers, and parameters correspond to the error.
Graphics Diagnostics can help you identify the shaders that correspond to the error so that you can use the HLSL Debugger to inspect the code. When you are satisfied that the shader code is correct, you can continue to use the HLSL Debugger to identify suspicious constant buffer entries or parameters, and then use the Graphics Event Call Stack to navigate into the source code of the app to find where they were last set.
Graphics Diagnostics supports apps that use Direct3D 10, Direct3D 10.1, Direct3D 11, and Direct3D 11.1 and provides limited support for apps that use Direct2D. It does not support apps that use earlier versions of Direct3D, DirectDraw, or other graphics APIs.
Because the Direct2D API uses the Direct3D API for much of its functionality, Graphics Diagnostics can be used to help debug apps that use Direct2D. However, because Graphics Diagnostics hooks the underlying Direct3D events instead of higher-level Direct2D events, it doesn't capture the details of Direct2D events that don't use Direct3D. Also, because the relationships between Direct2D API calls and the resulting Direct3D API calls are not always clear, the use of the Graphics Diagnostics for Direct2D apps is not straight-forward. Still, you can use Graphics Diagnostics to get information about low-level rendering problems in apps that use Direct2D.
Windows 8 installs the runtime components that are required by the graphics debugging features that are described in this document. To use these features on Windows 7 and Windows Vista, you must install one of the following Software Development Kits (SDKs):
DirectX SDK (June 2010)
Windows SDK (version 7.1)
Describes how to use Graphics Diagnostics to diagnose and debug rendering problems in DirectX-based apps.
Provides links to articles that demonstrate how to use Graphics Diagnostics to capture graphics information and diagnose common rendering problems.
Describes the Graphics Diagnostics programmatic capture API.
Introduces the debugging functionality in Visual Studio.
Provides links to articles that discuss DirectX graphics technologies.