# V2 Profiling Tool Setup, Workflows, And Budgets

This runbook is the operator-facing guide for the Phase 72 renderer and platform
profiling stack. The Tracy-specific workflow remains in
`V2/docs/engineering/tracy-profiling-workflow.md`; this document ties Tracy,
RenderDoc, PIX, Xcode GPU capture, Vulkan labels, Nsight Graphics, Superluminal,
GPU timing, memory, shader statistics, histograms, and GPU regression gates into
one workflow.

## Source Of Truth

The implementation is validated by these contracts:

- `V2/ue/Build/Performance/v2-tracy-profiling-workflow.json`
- `V2/ue/Build/Performance/v2-renderdoc-capture-api.json`
- `V2/ue/Build/Performance/v2-renderdoc-overlay-suppression.json`
- `V2/ue/Build/Performance/v2-gpu-timing-query-system.json`
- `V2/ue/Build/Performance/v2-gpu-timing-overlay.json`
- `V2/ue/Build/Performance/v2-pix-event-markers.json`
- `V2/ue/Build/Performance/v2-metal-gpu-capture.json`
- `V2/ue/Build/Performance/v2-vulkan-debug-labels.json`
- `V2/ue/Build/Performance/v2-nsight-graphics-markers.json`
- `V2/ue/Build/Performance/v2-gpu-memory-dashboard.json`
- `V2/ue/Build/Performance/v2-shader-statistics-collection.json`
- `V2/ue/Build/Performance/v2-frame-time-histogram.json`
- `V2/ue/Build/Performance/v2-gpu-performance-regression.json`
- `V2/ue/Build/Performance/v2-superluminal-markers.json`
- `V2/ue/Build/Performance/v2-cross-platform-profiling-abstraction.json`
- `V2/ue/Build/Performance/v2-profiling-documentation.json`

Renderer code lives under `libs/maya/engine-core/crates/maya-renderer/src`. CPU
instrumentation uses `maya_renderer_profile_scope!`, which keeps the Tracy zone
alive while emitting platform markers for Superluminal, PIX, and Nsight when the
backend and platform support them.

## Tool Setup Matrix

Use this matrix when choosing the first tool for a profiling request.

| Tool                     | Platform                                      | Setup                                                                               | Primary output                                                      |
| ------------------------ | --------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Tracy                    | All dev builds with `--features tracy`        | Build the affected Rust crate with `tracy`; never enable `shipping+tracy`           | `.tracy` capture and CI p95 report                                  |
| RenderDoc                | Vulkan, DX12, and supported desktop GPU paths | Enable the RenderDoc capture API and keep overlay suppression active during capture | Frame capture with clean overlays                                   |
| GPU timing overlay       | Dev renderer builds                           | Enable timestamp query backend and the dev overlay toggle                           | Per-pass timing bars and frame snapshots                            |
| PIX                      | Windows DX12                                  | Use PIX event markers from `pix_markers`; markers are DX12-only                     | Named GPU regions in PIX                                            |
| Xcode GPU capture        | macOS Metal                                   | Use `MetalCaptureConfig` and the Xcode capture destination                          | `Saved/Profiling/Metal/maya-metal-capture-{frame}-{label}.gputrace` |
| Vulkan debug labels      | Vulkan                                        | Keep `vkCmdBeginDebugUtilsLabel` labels around render passes and compute dispatches | Named passes in Vulkan debuggers                                    |
| NVIDIA Nsight Graphics   | Vulkan or DX12 on NVIDIA GPUs                 | Use NVTX ranges through `nsight_markers`                                            | Render pass, compute dispatch, and debug marker ranges              |
| Superluminal Performance | Windows CPU profiling                         | Load `PerformanceAPI.dll` and use Superluminal thread names and event scopes        | CPU event timeline with render command mapping                      |
| GPU memory dashboard     | All renderer backends                         | Feed resource lifetimes, memory budgets, and resource descriptors                   | Memory pressure, breakdowns, and top resource rows                  |
| Shader statistics        | Shader compiler outputs                       | Parse compiler reports and shader source metadata                                   | VGPR, SGPR, occupancy, and warning rows                             |

Local command shape for Tracy-enabled Rust validation:

```bash
cd libs/maya/engine-core
CARGO_BUILD_JOBS=1 cargo check -p maya-renderer --features tracy
TRACY_NO_INVARIANT_CHECK=1 CARGO_BUILD_JOBS=1 cargo test -p maya-renderer --lib profiling_abstraction --features tracy
```

Local command shape for GPU regression validation:

```bash
python3 V2/ue/Tools/run-v2-gpu-performance-regression.py --self-test
python3 V2/ue/Tools/check-v2-gpu-performance-regression.py
```

## Capture Workflows

Start with the workflow that matches the symptom.

| Symptom                                                    | First capture            | Required follow-up                                                               |
| ---------------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------- |
| CPU spike, scheduler gap, lock contention, or packet burst | Tracy                    | Preserve `.tracy`, Git SHA, command line, and p95 frame summary                  |
| Single-frame rendering defect                              | RenderDoc                | Capture with overlay suppression enabled and note the triggering pass            |
| DX12 GPU pass ordering or marker issue                     | PIX                      | Confirm `PIXBeginEvent` and `PIXEndEvent` ranges are balanced                    |
| Metal-only rendering defect                                | Xcode GPU capture        | Save the `.gputrace` path and frame label                                        |
| Vulkan or NVIDIA GPU bottleneck                            | Nsight Graphics          | Confirm `nvtxRangePushEx` and `nvtxRangePop` ranges surround render passes       |
| CPU timeline correlation on Windows                        | Superluminal Performance | Confirm `PerformanceAPI_BeginEvent`, `PerformanceAPI_EndEvent`, and thread names |
| Memory pressure or residency issue                         | GPU memory dashboard     | Export memory breakdown and top 32 resource rows                                 |
| Shader occupancy or register pressure issue                | Shader statistics        | Preserve compiler report input and warning rows                                  |
| Repeatable GPU performance regression                      | GPU regression runner    | Compare current report with baseline and store the report artifact               |

Manual Tracy capture still uses:

```bash
tracy-capture -o Saved/Profiling/Tracy/maya-capture.tracy -a 127.0.0.1 -p 8086 -f -s 10 -m 4096
```

GPU regression capture uses the standardized scene contract:

```text
/Game/V2/Performance/Maps/GPUBaseline_City
V2_GPURegression_CityFlythrough
pc-ultra-4k
3840x2160
30 warmup frames
120 sample frames
required passes: shadow_map, gbuffer, lighting, post_process
```

## Triage Workflow

Use this order for performance incidents:

1. Confirm the frame-time histogram: p50, p95, p99, jitter, hitch count, and
   whether samples exceed `DEFAULT_FRAME_TIME_HISTOGRAM_HITCH_US`.
2. Check GPU timing overlay bars and pass snapshots to decide whether the frame
   is CPU-bound, GPU-bound, or memory-bound.
3. If CPU-bound, open Tracy first; on Windows, open Superluminal when thread
   naming or render command mapping needs a second CPU view.
4. If GPU-bound, choose RenderDoc for correctness, PIX for DX12, Xcode GPU
   capture for Metal, or Nsight Graphics for NVIDIA Vulkan/DX12 captures.
5. If memory-bound, inspect the GPU memory dashboard pressure level, resource
   breakdown, transient resources, alias groups, and large resources.
6. If shader-bound, inspect shader statistics for VGPR, SGPR, temporary
   registers, local memory, shared memory, thread group size, wave size, and
   occupancy percent.
7. If the issue is repeatable, run the GPU regression self-test or full
   standardized scene and compare against baseline.

Every incident note must include the capture tool, artifact path, Git SHA,
backend, resolution, render preset, scene, sample count, and threshold result.

## Performance Budgets

Budgets are enforced by source contracts and Horde gates. Do not relax these in
docs; change the source contract and checker if the budget changes.

| Budget                                       | Value                   |
| -------------------------------------------- | ----------------------- |
| 60 Hz frame target                           | 16.67 ms                |
| 120 Hz frame target                          | 8.33 ms                 |
| 30 Hz recovery target                        | 33.33 ms                |
| Frame histogram hitch threshold              | 33.333 ms               |
| GPU regression average delta                 | <= 5.0 percent          |
| GPU regression p95 delta                     | <= 10.0 percent         |
| GPU regression p99 delta                     | <= 12.5 percent         |
| GPU regression per-pass p95 delta            | <= 15.0 percent         |
| GPU regression hitch rate                    | <= 1.0 percent          |
| GPU regression minimum sample count          | 60                      |
| GPU regression required pass coverage        | 100.0 percent           |
| GPU memory default budget                    | 8589934592 bytes        |
| GPU memory warning pressure                  | 80 percent              |
| GPU memory critical pressure                 | 90 percent              |
| GPU memory row cap                           | 32 resources            |
| GPU large resource warning                   | 20 percent of budget    |
| Shader VGPR warning / critical               | 96 / 128                |
| Shader SGPR warning / critical               | 80 / 104                |
| Shader temporary register warning / critical | 96 / 160                |
| Shader low occupancy / critical occupancy    | 50 percent / 25 percent |

CI gates that fail the build:

- `performance.gpu_regression.p95_regression_pct <= 10`
- `performance.gpu_regression.pass_p95_regression_pct <= 15`
- `performance.gpu_memory_dashboard.budget_pressure == 1`
- `performance.frame_time_histogram.budget_hitches == 1`
- `performance.shader_statistics.register_pressure == 1`
- `performance.cross_platform_profile.balanced_scopes == 1`

## CI And Release Gates

The V2 build workflow must run these documentation checks:

```bash
python3 V2/ue/Tools/check-v2-profiling-documentation.py
python3 -m json.tool V2/ue/Build/Performance/v2-profiling-documentation.json
python3 V2/tools/validate-v2-docs.py
```

The profiling documentation gate is complete only when these Horde gates are
present:

- `profiling-doc-tool-setup`
- `profiling-doc-capture-workflows`
- `profiling-doc-performance-budgets`
- `profiling-doc-evidence-checklist`
- `profiling-doc-ci-wired`

The broader profiling gate chain must also keep the Tracy, RenderDoc, GPU
timing, PIX, Metal, Vulkan, Nsight, GPU memory, shader statistics, frame
histogram, GPU regression, Superluminal, and cross-platform profiling checks in
the workflow.

## Evidence Checklist

Attach this evidence for any profiler-driven performance fix:

- Capture artifact: `.tracy`, RenderDoc capture, `.wpix`, `.gputrace`, Nsight
  report, Superluminal session export, GPU memory snapshot, shader statistics
  report, or GPU regression report.
- Git SHA and branch.
- Backend: Vulkan, DirectX12, Metal, or WebGPU.
- Platform and GPU driver version when available.
- Scene, map, view sequence, resolution, render preset, and sample count.
- Frame histogram p50, p95, p99, jitter, and hitch count.
- GPU regression result with average, p95, p99, per-pass p95, hitch rate, and
  pass coverage.
- Budget result: pass, warning, or failed.

## Verification

Run these checks after changing profiling docs, contracts, or workflow wiring:

```bash
python3 V2/ue/Tools/check-v2-profiling-documentation.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 -m json.tool V2/ue/Build/Performance/v2-profiling-documentation.json
python3 -m json.tool V2/ue/Build/Horde/v2-buildgraph-job.json
python3 V2/tools/validate-v2-docs.py
npx prettier --check V2/docs/engineering/profiling-tool-setup-workflows-budgets.md
```

For changes that touch Rust profiling macros, marker encoders, or GPU regression
data models, also run the affected `cargo check` and focused unit tests from
`libs/maya/engine-core`.
