GFXReconstruct Documentation

repository·dev·Indexed 20 days ago

https://github.com/lunarg/gfxreconstruct

A toolset for capturing and replaying graphics API calls for Vulkan and D3D12. It enables developers to record graphics commands to a file and replay them for analysis, debugging, regression testing, and platform bringup. The suite includes components such as the VK_LAYER_LUNARG_gfxreconstruct Vulkan layer, D3D12 capture libraries, and a variety of utility tools including gfxrecon-replay, gfxrecon-info, gfxrecon-compress, gfxrecon-extract, gfxrecon-convert, and gfxrecon-optimize.

Tokens
53K
Snippets
121
Records
196
Agent score
68%

What's inside GFXReconstruct

  1. Overview of GFXReconstruct components

    dev

    GFXReconstruct is a suite of tools designed to capture and replay graphics API calls. It allows developers to record graphics commands executed by an application to a file and later replay them to reconstruct the application's graphics behavior. This is useful for regression testing, platform bringup, and bug reporting.

    Core components include:

    • VK_LAYER_LUNARG_gfxreconstruct: A Vulkan layer used to capture Vulkan application commands.
    • D3D12 capture libraries: Libraries used to capture D3D12 application commands.
    • gfxrecon-replay: Tool to replay GFXReconstruct capture files.
    • gfxrecon-info: Tool to print descriptive information about capture files.
    • gfxrecon-compress: Tool to compress or decompress capture files (requires LZ4, Zstandard, and/or zlib).
    • gfxrecon-extract: Tool to extract SPIR-V binaries from capture files.
    • gfxrecon-convert: Tool to convert capture files to a JSON Lines listing of API calls (D3D12 support is experimental).
    • gfxrecon-optimize: Tool to produce new capture files with improved replay performance.
  2. Understand the purpose and use cases of GFXReconstruct

    dev

    GFXReconstruct is designed to record graphics API calls to a capture file, replay those calls, and process the resulting files. It serves three primary use cases:

    1. Reproduction: Prioritizes high fidelity and integrity of captured data for bug reporting, analysis, and testing. This is typically done via CLI tools or scripts rather than internal API usage.
    2. Tooling: Provides a foundation for building other tools. Users of this use case may opt to relax fidelity constraints to improve capture/replay performance or responsiveness.
    3. Silicon: Used for hardware/driver development. This involves replaying content on pre-production hardware, often in resource-constrained environments (low RAM/storage) or requiring API transformations to test new features.
  3. GFXReconstruct Vulkan Capture and Replay Overview

    dev
    GFXReconstruct is a software toolset designed for capturing and replaying Vulkan API calls on desktop operating systems, including Windows, Linux, and macOS. It allows developers to record a sequence of Vulkan commands during application execution and subsequently replay them to debug or analyze graphics behavior.
  4. GFXReconstruct Vulkan API Capture and Replay

    dev
    GFXReconstruct provides tools and layers for capturing Vulkan API calls during application execution and replaying them later to debug or analyze graphics workloads. This process involves enabling a capture layer that intercepts and records Vulkan commands into a capture file.
  5. GFXReconstruct D3D12 Overview

    dev
    GFXReconstruct provides software for capturing and replaying Direct3D 12 (D3D12) API calls on Windows Desktop systems. This allows developers to record graphics API sequences during application execution and replay them later for debugging, analysis, or regression testing.
  6. How GFXReconstruct replay works and its goals

    dev

    The primary goal of replay is to achieve execution in the same environment as the capture without user intervention.

    Replay Environment

    • Target: Ideally, replay occurs on the same GPU model, OS, and driver revision under similar or lower load conditions.
    • Portability: While same-environment replay is the priority, the capture format is designed not to make portable replay (different GPUs/OS/drivers) impossible.

    Workload and Sequence Fidelity

    • GPU Workload: Replay aims to produce a GPU workload (shaders, resources, memory access patterns) as similar to the capture as possible.
    • Command Sequence: The replayed sequence should match the captured sequence as closely as possible.

    Known Exceptions and Limitations

    • Virtual Swapchain: Used to ensure swapchain image index determinism during replay.
    • Single-threaded Replay: Currently, replay is single-threaded. This means memory and object creation/access sequences may differ from the original multi-threaded captured workload.
    • Trimmed Sequences: For trimmed ranges, the order of commands used to create objects and set state is not guaranteed, though state is kept as close to the original as possible.
    • Android: Replay on Android may require the --surface-index parameter to force the selection of a specific surface.
  7. Use hotkey triggers for capture

    dev

    You can enable manual capture triggering using a hotkey. Set GFXRECON_CAPTURE_TRIGGER to a key (F1-F12, TAB, or CONTROL).

    • Pressing the hotkey once starts the capture.
    • Pressing it again stops the capture.
    • Each start/stop pair generates a unique capture file.

    For workloads without frame boundaries (like pure compute), set GFXRECON_CAPTURE_TRIGGER_BOUNDARY to queue_submits to ensure the trigger checks for queue submission changes rather than frame boundaries.

    # Example: Use F3 to start and stop capture
    export GFXRECON_CAPTURE_TRIGGER="F3"
    export GFXRECON_CAPTURE_TRIGGER_BOUNDARY="queue_submits"
  8. Use a spinlock to wait for debugger attachment

    dev

    If you need to debug the capture layer from the moment the application starts, you can implement a manual spinlock in VulkanCaptureManager::OverrideCreateInstance(). This prevents the layer from proceeding until a debugger is attached.

    Implementation: Add the following loop to the start of VulkanCaptureManager::OverrideCreateInstance():

    while (util::platform::GetEnv("debug.gfxrecon.debug_wait") == "1") {
        usleep(100000);
    }

    Workflow:

    1. Set the spinlock property on the device: adb shell setprop debug.gfxrecon.debug_wait 1.
    2. Start the application. It will now spin in the loop.
    3. Launch your lldb client and attach to the process.
    4. Release the spinlock by setting the property to 0: adb shell setprop debug.gfxrecon.debug_wait 0.
    5. Continue debugging normally.
    // In VulkanCaptureManager::OverrideCreateInstance()
    while (util::platform::GetEnv("debug.gfxrecon.debug_wait") == "1") {
        usleep(100000);
    }
    
    // Commands to control the spinlock via ADB:
    // Enable: adb shell setprop debug.gfxrecon.debug_wait 1
    // Disable: adb shell setprop debug.gfxrecon.debug_wait 0
  9. Understand the output of Vulkan resource dumping

    dev

    The resource dumping feature generates several files. The primary metadata is stored in a JSON file named after the input file (e.g., vulkanCapture.gfxr becomes vulkanCapture_rd.json).

    Output File Types

    • JSON Output: Contains the header, drawCallCommands, and dispatchCommands/traceRays details. It maps Vulkan API parameters to specific dumped files.
    • Image Files: Created in the specified ImageFormat (bmp or png).
    • Binary Files (.bin): All buffers are dumped as raw binary files. Additionally, images that cannot be converted to a standard 32-bit RGBA layout are dumped as raw .bin files.

    JSON Structure

    1. Header: Contains source path, GFXR/Vulkan versions, and the dumpResourcesOptions used.
    2. Draw call commands: An array of entries including Vulkan parameters, color/depth attachments, vertex/index buffers, and immutable descriptors.
    3. Dispatch/Trace Rays commands: Includes Vulkan parameters, generated images/buffers, and immutable descriptors.
    [
    {
      "header": {
        "source-path": "vulkanCapture.gfxr",
        "gfxrecon-version": "1.0.3",
        "vulkan-version": "1.3.275",
        "dumpResourcesOptions": { ... }
      }
    },
    {
       "drawCallCommands": [
        {
          "drawIndex": 407,
          "parameters": { "drawCallType": "vkCmdDraw", ... },
          "colorAttachments": [{ "file": "Draw_407_..._att_0_aspect_color.bmp" }],
          "descriptors": { "vertex": [...] }
        }
       ]
    },
    {
       "dispatchCommands": [ ... ]
    }]
  10. Configure trimmed captures and asset dumping

    dev

    Trimmed captures allow you to capture specific portions of execution rather than the entire session.

    Trimming Options

    • debug.gfxrecon.capture_frames: Specifies frame ranges to capture. Each range generates a separate file.
    • debug.gfxrecon.capture_android_trigger: Triggers capture/stop based on specific events.
    • debug.gfxrecon.capture_trigger_boundary: Set to queue_submits to detect triggers at queue-submit boundaries instead of frame boundaries. When using queue_submits, use debug.gfxrecon.capture_trigger_frames to count submits.

    Asset Files

    To reduce capture size, use debug.gfxrecon.capture_use_asset_file to dump assets (images, buffers, descriptors) into a separate file. Only assets that change outside of the specified trim range are dumped, which speeds up the process.

  11. Use the --sync flag for precise QueueSubmitEnd timing

    dev

    By default, QueueSubmitEnd is emitted immediately after the vkQueueSubmit* call returns on the CPU. If you enable the --sync flag, the timing behavior changes:

    • Behavior: When a submit returns VK_SUCCESS, replay will wait for the GPU to become idle using vkQueueWaitIdle() before emitting the QueueSubmitEnd event.
    • Benefit: This provides exact completion timing at the granularity of the replayed vkQueueSubmit* call.
    • Trade-off: Replay becomes more serialized because the host waits after each successful submit, which changes host-observed timing even though the command stream remains identical.

    Use this flag when your external tool requires correlation between replay submits and actual GPU completion points.

  12. How OpenXR Capture and Replay works

    dev

    The OpenXR capture/replay model has specific behaviors regarding state and tracking:

    • Input Discrepancy: Real-time head, hand, and controller capture data will not match the data used during replay. Replay input data is largely ignored.
    • State Machine: State machine transitions and events may not match exactly between capture and replay. However, the system attempts to match event data for events reflecting runtime state, such as XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED.
    • Head Tracking: Replayed OpenXR frames are displayed at the same head relative position as they were captured. Consequently, replayed frames are insensitive to replay-time head tracking.