Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
PIX GPU Captures focus on Direct3D 12 work. To capture a D3D11 app, run the app through D3D11On12 so Windows translates D3D11 device work into D3D12 calls that PIX can record and replay. You then view your D3D11 app in PIX as if it were a D3D12 app.
Use this workflow when you need PIX GPU Capture inspection for a D3D11 renderer. The capture shows the D3D12 work produced by the D3D11On12 translation layer, so the event list and resource state transitions don't always map one-to-one to the original D3D11 calls.
D3D11 isn't the focus of PIX. Most D3D12 inspection features work on D3D11On12 captures, but some features work poorly or not at all. For details, see Limitations and Features that work.
How D3D11On12 capture works
When you capture through D3D11On12, these components sit between your app and the graphics driver:
- Your app calls the D3D11 API.
- The D3D11 runtime passes the work to D3D11On12. D3D11 treats D3D11On12 much like a display driver.
- D3D11On12 translates the D3D11 work into D3D12 calls.
- The PIX GPU capturer records those D3D12 calls.
- The D3D12 runtime and the graphics driver execute the work.
Because PIX sits below both D3D11 and D3D11On12, it sees only the D3D12 calls that D3D11On12 makes. This placement explains most of the differences between a D3D11On12 capture and a native D3D12 capture.
Capture from the PIX UI
Use the Force D3D11On12 option when PIX launches the app for GPU capture.
- On the PIX Welcome page, select Launch Process for the target machine.
- Select the Win32 executable or packaged app.
- Set Capture Type to GPU Capture.
- Make sure Force D3D11On12 is selected. This option is selected by default.
- Select Launch, and then take a GPU Capture as usual.
For the full launch flow, see Launch an application from PIX. For command-line launches, use the --force11on12 option described in pixtool.exe.
Turn on D3D11On12 outside a PIX launch
You can also turn on D3D11On12 yourself instead of having PIX do it at launch. PIX GPU Capture works with D3D11 apps when D3D11On12 is turned on this way. This route is also the only way to get D3D11 markers translated in a Timing Capture, because PIX doesn't turn on D3D11On12 itself for Timing Captures.
To turn on D3D11On12 with D3DConfig, add your app to the D3DConfig app list and then set the device option:
d3dconfig apps --add MyGame.exe
d3dconfig device force-d3d11on12=true
To turn on the same setting from PIX:
- In PIX, connect to the machine that runs your app.
- On the connection toolbar, select Connection Settings.
- On the DirectX Options tab, optionally select your app's executable to apply the setting to only that app.
- Under Device Options, turn on Force D3D11on12.
- Restart your app.
Understand the captured events
The event list in a D3D11On12 capture contains more than the D3D11 calls your app made.
Your PIX markers
Your ID3DUserDefinedAnnotation markers appear in PIX as PIX markers, so you don't need to change your D3D11 code to see them. In PIX, each marker name has the prefix D3D11 Event:, which D3D11On12 adds when it translates the marker. For example, a D3D11 annotation named Draw scene appears in PIX as D3D11 Event: Draw scene.
Markers and calls that D3D11On12 generates
You also see PIX markers that your app didn't create. D3D11On12 often emulates a single D3D11 call with several D3D12 calls, and it adds its own markers to group the D3D12 calls that belong to each D3D11 call. For example, a D3D11 UpdateSubresource call or a DrawIndexed or DrawIndexedInstanced call each appear as a marker that contains the D3D12 calls used to emulate it.
Expect to see many ResourceBarrier calls inside these markers. D3D11 handles resource transitions implicitly, so D3D11On12 adds the barriers that D3D12 requires. These barriers come from the translation layer, not from your app.
Present calls
Your app's IDXGISwapChain::Present call appears in PIX as a set of D3D12 calls. The calls you see depend on the Windows version and on what else is happening in the process. A simple case contains:
- A
ResourceBarriercall for the swap chain back buffer that's about to be presented. - A
Signalcall on one of the internal fences that D3D11On12 owns. - A
Presentcall made by D3D11On12.
This Present isn't IDXGISwapChain::Present. It's ID3D12SharingContract::Present, an interface that DXGI uses to implement IDXGISwapChain::Present.
Capture from application code
Use PIXForceD3D11On12() when the application loads the GPU capturer itself instead of being launched by PIX. Call it after WinPixGpuCapturer.dll is loaded and before the app creates its D3D11 device.
#define USE_PIX
#include <Windows.h>
#include <pix3.h>
void EnablePixD3D11GpuCapture()
{
HMODULE gpuCapturer = PIXLoadLatestWinPixGpuCapturerLibrary();
if (gpuCapturer == nullptr)
{
return;
}
HRESULT forceResult = PIXForceD3D11On12();
if (FAILED(forceResult))
{
return;
}
CreateD3D11DeviceAndSwapChain(); // Application-defined device creation.
}
If your app delay-loads D3D11.dll, load it before you call PIXForceD3D11On12(). The PIX hook path looks up D3D11CreateDevice and D3D11CreateDeviceAndSwapChain in the loaded D3D11.dll module. Devices created before the call aren't converted to D3D11On12.
For the rest of the programmatic capture setup, see Programmatic capture and PIXForceD3D11On12.
Requirements
- Use a GPU Capture workflow. The PIX UI option and
pixtool --force11on12launch mode are GPU-capture settings, andpixtoolrejects--force11on12with--timing. - Load
WinPixGpuCapturer.dllbeforePIXForceD3D11On12()when the app enables capture from code.PIXLoadLatestWinPixGpuCapturerLibrary()is the recommended loader. - Call
PIXForceD3D11On12()before creating the D3D11 device that you want to capture. - Run on a device and Windows configuration where D3D11On12CreateDevice can create a D3D11On12 device over a D3D12 device. PIX creates a D3D12 device for the selected adapter and requests at least Direct3D feature level 11.0.
- Build the
pix3.hcall path for a supported WinPixEventRuntime architecture withUSE_PIXenabled. WithoutUSE_PIX,PIXForceD3D11On12()compiles to a success-valued no-op stub.
Limitations
- The capture shows translated D3D12 work, not your original D3D11 calls. PIX creates a D3D12 device for the adapter and passes it to
D3D11On12CreateDevice, so every call you see in the capture comes from D3D11On12. - D3D11 devices that DXGI creates internally for hybrid-adapter presents aren't converted to D3D11On12. A capture that contains work from multiple D3D12 devices can fail to replay, so PIX leaves those DXGI devices on their original path.
PIXForceD3D11On12()returns a failureHRESULTif the GPU capturer export isn't available or PIX can't install the D3D11 creation hooks. Check the return value before you rely on the capture path.
No shader source or reflection data
In a D3D11On12 capture:
- PIX can't show shader source code, so you can't debug shaders at the source level.
- PIX doesn't have shader reflection data, so it can't automatically show the layout of a constant buffer or know precisely which resources a shader accessed.
This happens even if you compile your shaders with /Zi. D3D11 treats D3D11On12 like a display driver, and because display drivers don't need most of the metadata that travels with a shader blob, D3D11 discards the shader PDB data before it reaches D3D11On12 and PIX.
Shader debugging at the DXIL level only
You can still debug shaders, but only at the DXIL level, because D3D11On12 translates your DXBC shaders to DXIL. It's hard to map what happens in the DXIL back to the original DXBC, and from DXBC back to HLSL.
Inaccurate warnings
The Warnings view can report false positives for D3D11On12 captures, such as Small command lists executed or Command lists performing no GPU work, that your app didn't cause. D3D11On12 batches D3D11 calls into D3D12 command lists, and because it doesn't know what calls your app makes next, it can only guess when to flush those command lists. For more information about warnings, see Find issues with warnings.
Timing Captures show almost no GPU work
A Timing Capture of a D3D11 app shows almost no GPU work. The only GPU events you can expect it to record are VSYNCs, because the D3D11 infrastructure isn't instrumented for Timing Captures.
Force D3D11On12 is a GPU Capture setting, and PIX can't turn on D3D11On12 for a Timing Capture. Your D3D11 markers appear in a Timing Capture only if you turned on D3D11On12 yourself, as described in Turn on D3D11On12 outside a PIX launch.
To measure GPU work for a D3D11 app, take a GPU Capture through D3D11On12 and collect timing data from it.
Features that work
These major PIX features work with D3D11On12 captures:
- Dr. PIX experiments.
- Collecting timing data from a GPU Capture.
- The Pipeline view. For more information, see Inspect pipeline state and resources.
- The other D3D12 state and resource inspection features in PIX.