The Shader Debugger is accessible via the
Code Window for DirectX11 pixel shaders, compute shaders and vertex shaders. To start debugging click on the hammer icon on the left hand side of the shader debugger toolbar. Please note that the hammer icon may not be activated for all shaders in your application.
The Shader Debugger allows you to step through your shader one line at a time and view the register and variable values at each pixel (or thread for compute shaders). It is even possible to insert breakpoints in the code so that you can quickly jump to a particular line and start debugging. To aid in understanding the flow control of your shader, a Draw Mask image visualizes which pixels were written by the previous instruction.
For best HLSL debugging experience in DX11, also add the D3DCOMPILE_PREFER_FLOW_CONTROL and D3DCOMPILE_SKIP_OPTIMIZATION flags.
Some draw calls that are included in the Draw Call Slider, such as clears, copies, and resolves, do not have associated shaders and therefore cannot be debugged. On these draw calls, the 'Debug' and control buttons are not available. However, once you have selected a valid draw call, choose the language that you would like to debug in, and click on the blue 'Debug' button (with a hammer on it) to start the Shader Debugger. Debugging can be done in either Assembly or HLSL. There may still be a couple instructions that are not yet supported by the Shader Debugger, in this case, the 'Debug' button will be disabled. To find out why the shader cannot be debugged, simply hover the mouse over the Debug button and the tooltip will contain an explanation, or simply move the mouse into the code area and the status bar at the bottom of the application window will display the explanation.
Once debugging has started, the Frame Debugger Draw Call Slider is disabled along with the Profiler and API Trace. You must stop debugging prior to using one of these other tools. You may continue to open windows within the Frame Debugger, thus allowing you to get better views of the textures and states that affect the way your pixel shader is running.
Once the Shader Debugger is started, the Code Window gains a few more elements to become the Shader Debugger Window.
a) Control Buttons (from left to right)
- 'Run Back' (Shift + F5) - moves backwards to the previous breakpoint or to the beginning of the shader.
- 'Step Back' (Shift + F10) - moves backwards to the previous executable line.
- 'Step' (F10) - moves forward to the next executable line.
- 'Run' (F5) - moves forward to the next breakpoint or to the end of the shader.
Note: Trying to 'run' over a loop with many iterations may take a long time. You may want to increase the Shader Debugger Message Timeout prior to clicking 'run'. If the client times out before the shader debugger is finished, you may have to continue waiting or restart your application.
b) Code Window
- A green arrow will appear in the margin to the left of the next line to execute.
- Clicking in the margin to the left of a line will add / remove a breakpoint at that line. Breakpoints are cleared each time you stop / start debugging. If you try to add a breakpoint to an invalid line (on a comment for instance), the breakpoint will be added to the next executable line.
- Hovering the mouse cursor over a register or variable name will display its associated values.
c) Constants / Variables Table
- The first element in this table is the current "Thread" this shows the X,Y values corresponding to the current pixel being debugged. The thread can be changed by clicking in either the Draw Mask or the Register Buffer image.
- In addition to constants, this window will also show register / variable values for the current thread along with input variables (texture coordinates, etc).
- Values that have changed as you step between lines will be colored red.
- To save the content of the table to a file, move mouse cursor over the table and right click.
d) Fit To Window (you can also press the 'f' key)
- Toggles between showing the Draw Mask and Register Buffer so that they are visible in the current window, or displaying them at their native resolution.
- When displaying at native resolution, you can pan around the image by clicking and dragging.
- When displaying at native resolution, you can zoom into the image by positioning the mouse cursor over the pixel you would like to zoom in on and then use the scroll wheel.
e) Draw Mask
- Visualizes which pixels were written to by the last operation (shown in white); untouched pixels are shown in black.
- When stepping through flow control, only those pixels that take the current branch will be shown in white.
f) Register Buffer
- Visualizes the register / variable values that are touched by the shader
- The values output are directly from the output of the pixel shader, prior to being blended.
- The values are also displayed on the HUD, regardless of which render target they may be used for.
- Use the dropdown to select which register / variable values are displayed in the Register Buffer image.
- By default, the most recently written to register / variable is displayed, but any of the previously written register / variables are available.
- Pixels which were not touched are shown in black.
Once you have finished debugging, click the close icon in the top right to put the window back into its original state and to regain access to the Draw Call Slider and the Profiler and API Trace tools.
GPU PerfStudio uses the data returned from ID3D10ShaderReflection \ ID3D11ShaderReflection to determine which textures are in active use for a given shader stage & draw call. Using D3DStripShader to strip reflection data from your shaders restricts GPSs ability to do this. It is recommended that you do not strip reflection data whilst using GPU PerfStudio to get the best possible debugging & profiling experience.