Repository navigation
[Rendering][P0] Restore deterministic path-tracing goldens and oracle correctness #127
Description
Activity
Implementation status (2026-07-23): Metal implementation and qualification complete; DX12/Vulkan hardware qualification still pending.
What the investigation established:
- A clean
git archiveofe498433reproduced the historical progressive PNG byte-for-byte on Apple M1 Max / Metal, but took 167.10 s for 300 frames. Clean-main realtime still had not completed after five minutes and was terminated. This separates the clean baseline from the newer dirty-worktree image corruption while proving a severe Metal performance defect. - On the audited renderer worktree, named captures showed clean pipeline/depth/normal/albedo followed by nearly all-black sun visibility and workgroup holes in raw radiance. The first bad stage was the ray query, before accumulation/history/post.
- Naga 29.0.1 Metal lowering performs
intersector.intersect(...)inrayQueryInitialize, setsready = true, and its non-modernrayQueryProceedpath only reads that flag. The canonical proceed loop can therefore fail to advance/terminate. PT, HW-SSGI, and HW-WSRC now skip that loop on Metal; DX12/Vulkan keep the original proceed loop. - A second independent bug inverted PT's primary sun vector relative to the raster shader/public setter. PT and the test scene now use the point-to-sun convention (
0.5, 1.0, 0.3) used by the CPU oracle.
Evidence:
qualify_pt_oracle_hardwarepassed on Apple M1 Max / Metal:- three progressive repeats: byte-identical (
mean/max/outliers = 0,SSIM = 1.0); - three realtime-motion repeats: byte-identical (
mean/max/outliers = 0,SSIM = 1.0); - BRDF-energy fault failed as intended (
mean 4.528 > 4); - reprojection/cross-surface-history fault failed as intended (
6.0883%outlier pixels >1%); - corrected render wall times across qualification runs: 300-frame progressive
0.851–3.537 s, 48-frame realtime0.187–0.370 s.
- three progressive repeats: byte-identical (
- Full golden test binary:
10 passed, 0 failed, 2 explicitly ignored hardware diagnostics; both ordinary PT goldens reported exact matches. - Shared library:
128 passed, 0 failed, 1 ignored; the new backend/query-guard unit tests also pass. - CPU
pt-goldenreference: 256×256, 256 spp, 8 bounces, seed 0; topology/material tests pass and the rendered visibility, silhouettes, shadow direction, and energy agree with the corrected GPU result. - Naga validation succeeds for production PT, HW-SSGI, and HW-WSRC as Metal 2.4 (
BLOOM_RAY_QUERY_NEEDS_PROCEED=false) and HLSL SM6.0 (true, withRayQuery.Proceed()retained). - Failure artifacts now include expected/actual/diff/heatmap, JSON metadata (adapter/features/seed/frame/spp/timing/metrics), and named intermediate captures. Unsupported adapters emit structured skips;
BLOOM_REQUIRE_RAY_QUERY=1makes a supported-runner skip fatal.
The two PT goldens were intentionally updated only after the corrected Metal intermediates and independent CPU reference were inspected. The old images encoded sunless transport; the new images add coherent direct light and cast shadows, with no block regions/trails or uninitialized history.
Remaining acceptance item:
- There is currently no DX12/Vulkan hardware result.
GET /actions/runnersreportstotal_count: 0, and hosted Windows/Linux runners do not expose a non-CPU ray-query adapter. I am leaving this issue open until [CI] Make local, PR, hardware, and release quality gates truthful #140 provisions/runs the required hardware gate rather than presenting static shader validation or a structured skip as hardware coverage.
Canonical hardware command:
cd native/shared cargo test --release --test golden_render \ qualify_pt_oracle_hardware -- --ignored --exact --nocapture
Detailed root-cause and reproduction record:
docs/pt/PT-6-7-8-skinned-tlas-motion-oracle.md.- A clean
PR #147 now strengthens the PT oracle without changing accepted production images:
1041a06adds one-shot simultaneous realtime captures for rejection reason, motion, reprojected UV, variance/history length/retention confidence, plus raw HDR metrics. This replaces the need to reset and rerun separate debug modes when identifying the first temporal divergence.- The capture pass writes no production PT state and has zero normal-frame GPU resources/passes.
- Its unit contract is pinned to the production velocity convention, depth/footprint thresholds, and EMA floor.
751be72makes the oracle valid with SSGI explicitly disabled: PT now independently schedules only TLAS/geometry rebuild and raw card capture, rather than relying on the full SSGI bake chain.
Current M1 Max / Metal evidence remains exact for both checked-in PT goldens in the full release corpus (
mean/max/outliers = 0,SSIM = 1.0). The new 24-frame temporal capture also reports 10,984 accepted-history texels, 10,989 valid/accumulated texels, zero non-finite HDR pixels, and finite nonzero radiance.This advances the named-intermediate, resource-ordering, non-finite, and silent-skip portions of #127. It does not satisfy the remaining cross-backend requirement: a DX12 or Vulkan ray-query hardware qualification with the three-repeat and negative-control protocol is still required before closing this P0 issue.
Additional realtime PT oracle coverage landed at
a57ab32: retained rigid geometry now moves through the production TLAS, velocity MRT, PT reprojection, depth rejection, and SVGF recovery path in an automated hardware sequence.The first transition frame records 855 moving trace texels; 45 overlapping texels retain velocity-reprojected history and all 810 newly exposed/disoccluded texels explicitly reject it. No moving texel is unclassified. The image sequence has zero severe-trail frames and 0.0031% coherent outliers at frame four, while the pose change itself is visibly large (mean RGB delta 6.1125).
This strengthens #127 beyond camera-only motion without changing the accepted PT golden images. Cross-backend DX12/Vulkan qualification remains outstanding.
PT reset-oracle coverage landed at
ff95b63: explicit temporal reset and PT off/on both reproduce the warmed fresh realtime seed byte-for-byte after accumulating a different camera. Each path restarts at one sample, and the simultaneous rejection capture has zero non-seed texels.Together with
a57ab32rigid motion and136096fbidirectional lighting response, the local Metal corpus now covers the principal realtime history failure modes without changing accepted PT goldens. #127 still requires its DX12/Vulkan hardware protocol before closure.Metal requalification after the current rendering checkpoint is complete and pushed.
Evidence commit: 531f577
Evidence: https://github.com/Bloom-Engine/engine/blob/531f5779a013c696ef17b0fbc55c538af6acf388/docs/evidence/issue-127-pt-motion-requalification-v1.md
Qualified renderer: 09ad0b7Canonical one-device hardware oracle:
- 3/3 progressive runs pass with identical metrics: SSIM 0.998132777, 0.038147% coherent outliers.
- 3/3 realtime camera-motion runs pass with identical metrics: SSIM 0.999404554, 0.012207% coherent outliers.
- BRDF-energy fault is rejected (mean 5.299 > 4.0).
- Reprojection fault is rejected (mean 6.441 > 6.0 and 6.0760% outliers > 1.0%).
- No golden was updated.
Focused realtime PT temporal corpus: 4/4 pass.
- SVGF capture: 10,984 accepted-history texels, 10,989 valid/accumulated reprojections, zero non-finite HDR pixels.
- Rigid motion: zero trail frames; all 855 moving texels classified (45 retained, 810 explicitly rejected).
- Camera reset and PT off/on reproduce fresh seeds byte-for-byte.
- Lighting on/off converges with zero frame-12 coherent outliers.
This reconfirms Metal camera motion, rigid motion, disocclusion, reset ownership, lighting response, diagnostics, and negative controls on current HEAD. #127 remains open only for the required DX12 or Vulkan ray-query hardware run; hosted runners still cannot supply that GPU evidence.
Parent: #126
Problem
Bloom's GPU path tracer is the closest in-engine correctness oracle for BRDF energy, direct/indirect visibility, motion reprojection, and denoising. It cannot serve that role unless its golden tests are deterministic and trusted.
The audit found the two path-tracing goldens in
native/shared/tests/golden_render.rsfailing on the audited worktree:pt_progressive: large mean error plus broad black/speckled regions;pt_realtime_motion: lower mean error but localized high-error trails/outliers.The worktree contains renderer changes, so the first task is to reproduce on a clean
maincheckout before assigning blame. Do not update the goldens to make the test green. First determine whether the baseline, harness, backend, or renderer is wrong.Outcome
A deterministic GPU path-tracing correctness suite that:
Implementation contract
1. Reproduce and classify
main, recording commit, OS, adapter, driver, backend, features, and actual diff metrics.pt_progressive.actual.pngandpt_realtime_motion.actual.pngplus heatmaps.2. Make stochastic inputs explicit
3. Fix the first incorrect stage
Likely areas include
native/shared/src/renderer/pt_pass.rs,native/shared/src/renderer/shaders/pt.rs, TLAS/BLAS update ordering inrenderer/mod.rs, motion matrices, SVGF history validation, and render-graph resource ordering. Fix the earliest provably incorrect stage rather than compensating downstream.4. Improve the failure artifact
On failure, write an artifact directory containing:
BLOOM_GOLDEN_DIAGNOSTICS=1.Acceptance criteria
golden_pt_progressiveandgolden_pt_realtime_motionpass three consecutive runs on the same adapter with identical or explicitly bounded metrics.tools/bloom-referenceare used to sanity-check the static scene's energy and occlusion; any expected model difference is documented.Verification
Run the relevant reference scene through
tools/bloom-referenceand attach the result metadata to the PR.Non-goals
Dependencies
None. This blocks quality claims in every renderer issue under #126.