Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/tickets.md
Original file line number Diff line number Diff line change
Expand Up @@ -689,3 +689,27 @@ symbolized stack; fix then.
(profiler overlay/history strings are the heaviest string traffic in the
crashing runs), or an engine-side heap read overrun in a small shared
helper. Audit report: `shooter/docs/audit-round2.md` finding F1.

## EN-023 — GI software path: colored bounce is unreachable 🟡

**Why.** Round-2 audit (F4): on adapters without EXPERIMENTAL_RAY_QUERY
(the dev box's Radeon 760M reports none — see the new boot log), the
probe trace runs the SDF path, where the mesh-card lookup compares
world-space hits against OBJECT-space AABBs (ssgi.rs broad phase) — every
transformed instance falls through to the flat gray 0.55 analytic — and
the software WSRC bake is analytic sun+sky with no geometry at all.
Measured in-game: SSGI on/off is ≤2.5% achromatic luma, hue ratio
unchanged to 4 decimals. The ~267 gi_only proxies feed a pipeline whose
colored output cannot reach the screen on SW adapters, at ~1.6 ms GPU in
combat.

**Sketch.** (1) Transform SDF hits into instance object space (or
instance AABBs into world space) in the card broad-phase so textured/
tinted cards resolve. (2) Make the SW WSRC bake sample cards (or at
least sun-shadowed ground/albedo bounce) instead of pure analytic.
(3) Re-run the audit's GI A/B: acceptance = G/R hue shift at the
building base and ≥8-10% luma in shaded receivers.

**Interim option** (decision D2-B in the shooter audit): boot-time
`setSsgiEnabled(false)` on SW adapters banks the ~1.6 ms until this
lands; needs a backend query FFI or the game reading the new boot log.
9 changes: 9 additions & 0 deletions native/shared/src/renderer/scene_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,15 @@ impl Renderer {
if let Some(tid) = scene_color_tid {
self.transient_pool.release(tid);
}
// Round-2 audit: the depth snapshot was acquired every frame but
// NEVER released — the pool (which has no auto-reclaim by design)
// allocated a brand-new render-res Depth32Float every frame with
// refractive water on screen. ~8 MB/frame of texture creation plus
// an ever-growing slot scan; measured as translucent_pass CPU
// climbing 0.4 ms → 6.7 ms over ~50 s of play, in every session.
if let Some(tid) = scene_depth_tid {
self.transient_pool.release(tid);
}
profiler.end("translucent_pass");
}
}
Expand Down
15 changes: 15 additions & 0 deletions native/shared/src/renderer/transient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ impl TransientPool {
}

// Nothing matched — allocate a new slot.
//
// Leak watchdog: a steady-state frame needs a handful of slots.
// A count that keeps growing means some caller acquires without
// releasing (the pool has no auto-reclaim by design) — exactly
// the depth-snapshot leak the round-2 audit spent a day tracing
// from the profiler side. Warn at every power of two past 64 so
// the log stays quiet but the failure mode is named.
let n = self.slots.len();
if n >= 64 && n.is_power_of_two() {
eprintln!(
"bloom transient pool: {} slots allocated and growing — \
an acquire without a matching release is leaking textures",
n
);
}
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("transient"),
size: wgpu::Extent3d {
Expand Down