PIX on Windows

Performance tuning and debugging for DirectX 12 games on Windows

Programmatic Capture

PIX allows applications to take and configure GPU Captures programmatically using various APIs documented here. Timing captures cannot currently be taken programmatically using PIX on Windows.

 

pix3.h GPU Capture APIs

pix3.h is included in the WinPixEventRuntime, which is documented here.

Before using the pix3 GPU Capture APIs, you must:

    1. Install PIX onto the target PC
    2. Add WinPixEventRuntime to your application (see docs here)
    3. Define one of these preprocessor symbols in your build: USE_PIX, DBG, _DEBUG, PROFILE, or PROFILE_BUILD.
    4. Include pix3.h in your application
    5. EITHER load a copy of WinPixGpuCapturer.dll into your application’s process before creating any D3D devices
      • WinPixGpuCapturer is shipped with PIX, and not with WinPixEventRuntime.
      • pix3.h contains a helper function, PIXLoadLatestWinPixGpuCapturerLibrary(), to find the library and load it for you. See docs below for details.
      • You can also use the sample code here to manually find and load the library.
    6. OR launch your application through PIX or pixtool
      • This will inject WinPixGpuCapturer.dll into your application for you.
    7. Use APIs like PIXBeginCapture(), PIXSetTargetWindow(), etc in your application.

 

Programmatic Capture API Documentation

HMODULE PIXLoadLatestWinPixGpuCapturerLibrary()

This is a helper function that will find the latest PIX installation in Program Files on the current PC and LoadLibrary() its copy of WinPixGpuCapturer.dll for you. The function’s semantics are similar to LoadLibrary(): upon success, it increments the module’s reference count and returns a non-NULL module handle. This means that FreeLibrary() needs to be called on the module before it will be unloaded. Upon failure, the function returns nullptr and a detailed error can be accessed via GetLastError().

 

HRESULT WINAPI PIXBeginCapture(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)

This API immediately starts a programmatic capture and outputs it to the capture file specified in the  GpuCaptureParameters part of captureParameters struct. Other parts of that struct are ignored. For compatibility with Xbox, captureFlags must be set to PIX_CAPTURE_GPU otherwise the function will return E_NOTIMPL.

The capture filename specified in the captureParameters struct should use the .wpix file extension.

You may want to wait for all pending GPU work to finish executing before calling this API, to ensure that you capture everything that you expect to capture.

 

HRESULT WINAPI PIXBeginCapture2(DWORD captureFlags, _In_opt_ const PPIXCaptureParameters captureParameters)

This API is functionally equivalent to PIXBeginCapture. It exists for compatibility reasons.

 

HRESULT WINAPI PIXEndCapture(BOOL discard)

This API immediately terminates any in-progress GPU Capture started via PIXBeginCapture(). PIX on Windows ignores the discard parameter.

You may want to wait for all pending GPU work to finish executing before calling this API, to ensure that you capture everything that you expect to capture.

 

HRESULT WINAPI PIXGpuCaptureNextFrames(PCWSTR fileName, UINT32 numFrames)

This API enqueues a Present-to-Present GPU capture that will begin next time a qualifying Present() call is made. This is equivalent to pressing the Print-Screen key or hitting the capture button in the PIX UI.

The filename should use the .wpix file extension.

 

HRESULT WINAPI PIXSetTargetWindow(HWND hwnd)

This API tells PIX which target window the application is interesting in capturing. After calling this API, PIX will only start or stop Present-to-Present captures when the application presents the target HWND. Present() calls to other HWNDs will be captured when applicable, but they will not start or stop capture.

PIXSetTargetWindow is useful in multi-window applications such as game engine editors, where PIX users typically want to capture one particular window.

 

HRESULT WINAPI PIXSetHUDOptions(PIXHUDOptions hudOptions)

This API is used to set different display options for the PIX overlay. Valid options are

  • PIX_HUD_SHOW_ON_ALL_WINDOWS: Overlay displayed on the top left all the windows created by the test app.
  • PIX_HUD_SHOW_ON_TARGET_WINDOW_ONLY: Overlay should only be seen on the target window (set using PIXSetTargetWindow)
  • PIX_HUD_SHOW_ON_NO_WINDOWS: Overlay should not be seen on any window created by the test app.

 

HRESULT WINAPI PIXForceD3D11on12()

This API allows a D3D11 app to be captured by PIX using the 11on12 mapping layer

  • Important: Call the function before a D3D11 device is created.
  • Can be used to launch and take captures of a D3D11 app (leaving the Force11on12 checkbox empty).
  • Can also be used to attach to a running D3D11 app.

 

Legacy GPU Capture APIs

GPU Captures can also be taken via the IDXGraphicsAnalysis interface. The methods on this interface will only work after launching your application through PIX/pixtool, or after attaching PIX to your application.

The interface is defined in DXProgrammableCapture.h header, included with the Windows 10 SDK.

    #include <DXProgrammableCapture.h>

Alternatively, here is the definition:

    interface DECLSPEC_UUID("9f251514-9d4d-4902-9d60-18988ab7d4b5") DECLSPEC_NOVTABLE

    IDXGraphicsAnalysis : public IUnknown

    {

        STDMETHOD_(void, BeginCapture)() PURE;

        STDMETHOD_(void, EndCapture)() PURE;

    };

IDXGraphicsAnalysis can be retrieved using DXGIGetDebugInterface1:

    ComPtr<IDXGraphicsAnalysis> ga;

    HRESULT hr = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&ga));

    // hr will be E_NOINTERFACE if not attached for GPU capture

Once you have the IDXGraphicsAnalysis*, then you can call BeginCapture and EndCapture on it to control when a GPU capture is taken:

    ga->BeginCapture();

    // Perform rendering work

    // ...

    ga->EndCapture();