Skip to content

Skin: per-pass GPU cost and memory for the skin stack — wall clock cannot resolve it #1396

Open

Description

@drsnuggles8

Found while capturing the epic acceptance for #1222 (PR #1388).

The problem

#1222's delivery contract asks to "record image quality, per-pass cost and memory on named
hardware". PR #1388 delivers the image-quality half and a cost measurement that cannot resolve
the thing it measures
.

DigitalHuman_Timing.txt times the full skin stack against a version-0 split-only control, per
raster path, wall clock, 384×384 offscreen, each arm after a discarded warm-up. Two consecutive
runs of the identical binary:

path run A run B
Forward −12.9% −4.6%
Forward+ +11.9% +44.5%
Deferred −4.7% −17.2%

The full stack cannot really be cheaper than the control, so the negative values and the sign
flips mean the cost is below the fixture's noise floor — not that the stack is free. All that
file legitimately claims is that the stack does not cost an order of magnitude.

(An earlier revision reported a uniform +146%/+47%/+95%. That was the frame-graph reconfigure a
path switch forces, charged to whichever arm was captured first. Fixed in PR #1388; noted here so
nobody resurrects those numbers as a baseline.)

Memory was not measured at all.

What to build

A cost measurement that can actually resolve the skin stack:

  • GPU timer queries, not wall clock. GPUPassTimerPool already exists and
    olo_render_frame_breakdown already reports per-pass GPU time; wall clock around RunFrames on
    a box that also hosts CI runners for another repo is the wrong instrument.
  • A scene with enough skin to dominate the frame — one head at 384×384 is a rounding error.
    A crowd of heads, or a full-screen face at native resolution.
  • Per-pass, not per-frame, so SkinDiffusionPass is attributable separately from the
    G-Buffer and lighting cost it rides with.
  • Memory: the diffusion pass's transient targets and the profile table, on named hardware.

Acceptance criteria

  • Per-pass GPU cost for the skin stack, with a stated run-to-run spread that is smaller than
    the effect being reported.
  • Memory recorded for the skin-specific resources.
  • Named hardware, and a re-run procedure someone else can follow.
  • The result is a measurement to establish a budget from, per the epic's contract — not a
    justification for reducing ambition.

Evidence

#1222 (comment)

Score

capability: 3
craft: 5
stability: 3
decay: 2
effort: 5
confidence: 0.7
learning: 5
fun: 3
kano: performance
blocked_by: []
blocks: [1222]

Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.

Activity

  1. added
    performancePerformance / data-oriented optimization
    ready-for-agentSpecified for agent implementation after scored blockers are satisfied
    on Sep 21, 2026
  2. drsnuggles8 commented on Oct 25, 2026

    @drsnuggles8
    OwnerAuthor

    Partial delivery, checked 2026-10-25: the #1259 acceptance benchmark (PR #1597) records per-pass GPU time for SkinDiffusionPass with timer queries, three counted runs per cell, on an RTX 4090 (GL test host): 0.03–0.04 ms at the outdoor cameras and 0.15–0.45 ms p50 at the head close-up, in docs/testing/evidence/integrated-acceptance-1259/gl-summary.md. So "GPU timer queries, per-pass, named hardware, re-run procedure" now exist for one head.

    Still open against the acceptance criteria:

    • Memory for the skin-specific resources (diffusion transient targets, profile table) is still not recorded anywhere.
    • A scene where skin dominates the frame. At the close-up the run-to-run spread (0.15–0.45 ms) is as large as the value itself, so the "spread smaller than the effect" criterion is not met.
    • Vulkan cells.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance / data-oriented optimizationready-for-agentSpecified for agent implementation after scored blockers are satisfied

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions