Export a GPU capture to C++

Export to C++ turns a GPU capture into a C++ project that recreates its Direct3D 12 resources and replays the captured GPU work. You can build and run the project separately from your original app.

Use the exported code as a starting point for a standalone reproduction of a rendering problem, such as a suspected GPU driver bug. You can edit the generated calls to experiment with a change or manually remove unrelated work to reduce the reproduction.

Export from PIX

  1. Open the GPU capture you want to export and make it the active document.
  2. On the File menu, select Export "<capture name>" to C++.
  3. In the Export to C++ dialog, set Export Path to the destination folder. To avoid overwriting files from an earlier export, choose a folder that doesn't contain any files yet.
  4. Choose the Export Options described below, and then select Export.
  5. When the export succeeds, select Yes if you want PIX to open the output folder.

The export command is available when a GPU capture is the active document. If export fails, PIX displays an error code.

Export options

The dialog provides these settings:

Setting What it does
Export Path Chooses where PIX writes the generated project and its data files.
Overwrite any pre-existing files Skips the confirmation for a nonempty destination folder. Existing files with matching names can be overwritten. If you leave this unchecked, PIX asks before continuing into a nonempty folder.
Use WinPixEventRuntime* Enables the generated graphics-command-list and command-queue PIX events and markers. CMake configures the WinPixEventRuntime package dependency. Without it, those generated marker calls aren't compiled in.
Use DirectX 12 Agility SDK** Configures the project to obtain the DirectX 12 Agility SDK package and use its Direct3D headers and runtime. The build copies the runtime into a D3D12 subfolder beside the executable. Without this option, the project uses the Windows SDK headers and system Direct3D runtime.
Use replay-time ExecuteIndirect argument buffers (experimental) Uses the argument buffers produced during replay instead of copies recorded at capture time. Try this if your app generates argument buffers nondeterministically alongside other buffers that must stay in sync, such as index buffers, and the default export produces corruption or crashes.

The asterisks in the two package options refer to license acknowledgments. Selecting either option acknowledges and accepts that package's license; the dialog links to the terms on NuGet.org.

What PIX generates

The export is a CMake project, not a prebuilt executable or a Visual Studio solution. It includes these files:

Files Purpose
CMakeLists.txt Defines the PixCapturePlayer build target and optional package dependencies. You can use CMake to generate a Visual Studio solution.
Main.cpp and Win32Application.cpp Provide the Windows application entry point and replay loop.
FrameResources*.cpp, CreateAndInitResources*.cpp, and CreatePSOs.cpp Recreate the captured resources and pipeline state.
CommandLists*.cpp and RenderFrame*.cpp Record command lists and execute the captured work.
Descriptors*.cpp, ModifyDescriptors*.cpp, and ResourceModifications*.cpp Recreate descriptors and apply captured updates.
resources.bin Stores compressed binary data, including resource contents and shader bytecode, which the generated code reads at runtime.
Supporting headers and source files Provide resource loading and replay helpers, including the d3dx12 headers.

PIX splits large generated source files into numbered files, such as CommandLists_000.cpp. Keep the entire export together when you share or move the project; the C++ files alone aren't sufficient.

Build and run

For an x64 Visual Studio build, install:

  • Visual Studio with the Desktop development with C++ workload, including the MSVC tools.
  • A Windows SDK that provides the declarations used by the generated code. The project asks CMake to select the newest installed Windows SDK.
  • CMake 3.30 or later. The project requires C++17.

The following example uses Visual Studio 2022. From its x64 developer command prompt, change to the exported folder and run:

cd /d C:\Exports\Frame
cmake -G "Visual Studio 17 2022" -B out\build -A x64
cmake --build out\build --config Release

If you select either package option, CMake attempts to download the package from NuGet when you configure the project. Allow network access for that step and check the configuration output for download warnings.

Run the generated executable from out\build\Release, or open the generated solution in out\build and run the PixCapturePlayer target. The target name stays PixCapturePlayer, but the executable normally takes the captured app's name. PIX can use the capture filename instead; PixCapturePlayer.exe is the fallback.

The generated application repeatedly replays the captured work. Start with the unmodified export and check that it reproduces the issue before simplifying the code.

Keep resources.bin available at runtime. The reader searches the working directory and up to three parent directories, then falls back to the export directory recorded at build time. When you move a built reproduction, place resources.bin in its working directory and include any generated runtime dependencies:

  • WinPixEventRuntime.dll, if enabled.
  • The D3D12 subfolder, if the Agility SDK is enabled.

Limitations

  • Multi-adapter C++ export isn't supported. PIX rejects captures that create devices with different adapter descriptions.
  • The generated application tries to use an adapter with the capture-time description and falls back to the default adapter if it can't find one. For a driver-bug reproduction, start on the original hardware and validate the result before sharing it for use on another GPU.

Export from the command line

Use pixtool to open a GPU capture and export it in the same session:

pixtool open-capture C:\Captures\Frame.wpix export-to-cpp C:\Exports\Frame

The export command accepts these switches:

Switch Equivalent export option
--force Overwrite files with matching names. Required when the output directory isn't empty.
--use-winpixeventruntime Use WinPixEventRuntime and accept its license.
--use-agilitySdk Use the DirectX 12 Agility SDK and accept its license.
--use-replay-time-executeindirect-buffers Use replay-time ExecuteIndirect argument buffers.

For example, to export with both optional packages:

pixtool open-capture C:\Captures\Frame.wpix export-to-cpp C:\Exports\Frame --use-winpixeventruntime --use-agilitySdk

Unlike the UI, pixtool doesn't prompt before writing to a nonempty directory: the command fails unless you supply --force.