Share via


HLSL Debugger

The HLSL debugger, which is one of the Graphics Diagnostics tools in Visual Studio, can help you understand how your HLSL shader code operates with graphics data that was recorded during a Graphics Diagnostics capture session.

This is the HLSL debugger:

Debugging HLSL using watch and call stack windows.

Understanding the HLSL debugger

The HLSL debugger can help you understand problems that arise in your shader code. Debugging HLSL code in Visual Studio resembles debugging code that's written in other languages—for example, C++, C#, or Visual Basic. You can inspect the contents of variables, set break points, step through code, and walk up the call-stack, just like you can when you debug other languages.

However, because GPUs achieve high performance by running shader code on hundreds of threads simultaneously, the HLSL debugger is designed to work together with the other Graphics Diagnostics tools to present all of this information in a way that helps you make sense of it. Graphics Diagnostics recreates captured frames by using information that was recorded in a graphics log; the HLSL debugger does not monitor GPU execution in real time as it runs shader code. Because a graphics log contains enough information to recreate any part of the output, and because Graphics Diagnostics provides tools that can help you pinpoint the exact pixel and event where an error occurs, the HLSL debugger only has to simulate the exact shader thread that you are interested in. This means that the work of the shader can be simulated on the CPU, where its inner workings are in full view. This is what gives the HLSL debugger a CPU-like debugging experience.

However, the HLSL debugger is currently limited in the following ways:

  • It's not possible to debug an app and its shader code at the same time. However, you can alternate between them.

  • You can add variables and registers to the Watch window, but expressions are not supported.

Nevertheless, the HLSL debugger provides a better, more CPU-like debugging experience than would be possible otherwise.

HLSL Shader Edit and Apply

The HLSL shader debugger doesn't support Edit and Continue in the same way that the CPU debugger does because the GPU execution model doesn't allow shader state to be undone. Instead, the HLSL debugger supports Edit and Apply, which allows you to edit HLSL source files and then choose Apply to regenerate the frame to see the effect of your changes. Your modified shader code is stored in a separate file to preserve the integrity of your project's original HLSL source file, but when you're satisfied with your changes you can choose Copy to… to copy the changes into your project. Using this feature, you can quickly iterate on shader code that contains errors and eliminate costly rebuild and capture steps from your HLSL debugging workflow.

Important

The altered shader does not apply to Frame Analysis.

HLSL Disassembly

The HLSL shader debugger provides a listing of HLSL shader assembly to the right of the HLSL source code listing.

Debugging HLSL code

You can access the HLSL debugger from the Graphics Pipeline Stages window or from Graphics Pixel History.

To start the HLSL debugger from the Graphics Pipeline Stages window

  1. In the Graphics Pipeline Stages window, locate the pipeline stage that's associated with the shader that you want to debug.

  2. Below the title of the pipeline stage, choose Start Debugging, which appears as a small green arrow.

    Note

    This entry point into the HLSL debugger debugs only the first shader thread for the corresponding stage—that is, the first vertex or pixel that is processed. You can use Graphics Pixel History to access other threads of these shader stages.

To start the HLSL debugger from the Graphics Pixel History

  1. In the Graphics Pixel History, expand the draw call that's associated with the shader that you want to debug. Each draw call can correspond to multiple primitives.

  2. In the draw call details, expand a primitive whose resulting color contribution suggests a bug in its shader code. If multiple primitives suggest a bug, choose the first primitive that suggests it so that you can avoid an accumulation of errors that can make diagnosis of the problem more difficult.

  3. In the primitive details, choose whether to debug the Vertex Shader or the Pixel Shader. Debug the vertex shader when you suspect that the pixel shader is correct but is generating an incorrect color contribution because the vertex shader is passing incorrect constants to it. Otherwise, debug the pixel shader.

    To the right of the chosen shader, choose Start Debugging, which appears as a small green arrow.

    Note

    This entry point into the HLSL debugger debugs either the pixel shader thread that corresponds to the chosen draw call, primitive, and pixel that you have chosen, or to the vertex shader threads whose results are interpolated by the draw call, primitive, and pixel that you have chosen. In the case of vertex shaders, you can further refine the entry point to a specific vertex by expanding the vertex shader details.

For examples about how to use the HLSL Debugger to debug shader errors, see Graphics Diagnostics Examples or the walkthroughs linked to in the See Also section.

See Also

Tasks

Walkthrough: Missing Objects Due to Vertex Shading

Walkthrough: Debugging Rendering Errors Due to Shading

Walkthrough: Using Graphics Diagnostics to Debug a Compute Shader