Skip to content

Round-2 integration: lag + flicker + GI-bake fixes land in main#83

Merged
proggeramlug merged 20 commits into
mainfrom
round2/integration
Jul 8, 2026
Merged

Round-2 integration: lag + flicker + GI-bake fixes land in main#83
proggeramlug merged 20 commits into
mainfrom
round2/integration

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Consolidates all round-2 work into main: every open round-2 PR (already merged into this integration branch) plus the 2026-07-06/07 fullscreen-lag + flicker + gameplay fixes that are not in any individual PR.

Round-2 PRs subsumed (all already merged here)

New fixes landed on top

  • Fullscreen lag: amortized the Lumen SDF-clipmap/WSRC camera bakes (binned + sliced) that stalled the GPU 1-2.4s per camera move on the 760M. SSGI stays on, locked 60fps.
  • Flicker: stale material-path shadow VP, cascade pancake hysteresis, auto-exposure quantization + anchored deadband, EN-022 jitter-cancelled velocity, GTAO temporal phase dither + history clamp, TAA chroma clamp, unsharp-mask halo clamp.
  • Windowed-mode crash fix (partial depth copy) + native F12 screenshot hotkey (COPY_SRC surface).

Verified: rotating-camera gameplay 40fps+freezes -> locked 59-60fps; building gray-line flicker eliminated (native F12 diff).

Summary by CodeRabbit

  • New Features

    • Added richer profiler data, including per-row CPU/GPU timings and history samples.
    • Added new rendering controls for sharpen strength and display present mode.
    • Windows builds now capture crash dumps and support a screenshot hotkey.
  • Bug Fixes

    • Improved shadow, motion-vector, TAA, SSAO, SSR, and exposure stability to reduce flicker and ghosting.
    • Fixed resource cleanup and transient allocation growth issues.
    • Added clearer error logging for frame-acquisition, glyph atlas, and screenshot failures.
  • Documentation

    • Expanded build, test, and crash-triage guidance for Windows and renderer workflows.

Ralph Kuepper added 20 commits July 4, 2026 09:55
…nd-2 audit)

Profiler correctness (audit F9 — these skewed every round-1 measurement):
- Rolling stats expire: a pass that stops running (feature toggled off)
  drops out of snapshot/summary/overlay after one window instead of
  showing a frozen average forever; entries evict after 4 windows.
- Re-enabling the profiler starts a fresh session (clears rolling stats
  + frame histogram) instead of blending pre-disable numbers in.
- One-shot warning when the 32-pair GPU timestamp budget is exhausted
  (was a silent truncation of later passes).
- Restore the orphaned `post_fx` CPU bracket — begin() was lost at some
  point, leaving end() a no-op while a comment claimed the phase covered
  the composite tail's cost.
- frame_end doc no longer claims the readback is non-blocking: it
  map_asyncs + poll(Wait)s every frame, serialising CPU<->GPU, so wall
  fps is pessimistic while profiling (measured ~3 fps at combat load).
- Unit tests for the expiry + fresh-session semantics.

Boot observability (audit F4 — the silent HW->SW GI fallback cost a
debugger day):
- windows: log adapter name/backend + ray_query/timestamp feature flags
  at device creation.
- One-shot "bloom: ssgi trace backend = hw-ray-query|sdf-clipmap|
  hiz-screen" when the trace tier is chosen (re-logs on promotion).

Crash-triage kit (audit F1, EN-020):
- native/windows release profile carries line-tables-only debug info so
  `perry compile --debug-symbols` yields a usable PDB.
- docs/crash-triage-windows.md: the standing WER LocalDumps + symbols +
  llvm-symbolizer workflow, and everything known about the layout-
  sensitive heap-read AV (3x reproduced pre-relink, gone after relink).
- docs/tickets.md: EN-020 filed with repro history and ruled-out causes.

Test repairs (pre-existing breakage from the round-1 merge):
- material_system_tests: MaterialDrawCommand fixture gained the `model`
  field Tier 2 added — cargo test has not compiled since.
- Regenerate the two golden references (lit_primitives_3d,
  many_point_lights_clustered_scene) that still encoded pre-round-1
  shading; the other goldens pass unchanged and stay untouched.
…ma, sharpen knob

- fs_main_scene's foliage backlit-transmission block was pasted TWICE
  (verbatim, 1.7x intended strength) and ran unshadowed — a canopy in
  another tree's shadow still glowed at full strength. Dormant in the
  shooter today (no MASK assets drawn) but a landmine for any cutout
  foliage. De-duplicated + multiplied by the sun shadow factor.
  (audit F3 side-finding)

- 2D colors (shapes, textures, text) are now sRGB-decoded to linear
  before hitting the sRGB swapchain view — they were double-encoded:
  washed-bright HUD midtones, gamma-skewed glyph AA. Deliberately
  scoped to the 2D pass via a separate color_to_f32_srgb helper: the
  3D immediate batch and model tints keep their historical raw /255
  interpretation, because flipping those would silently re-tint every
  existing drawCube/drawModel call in shipped games. shapes_2d golden
  regenerated (midtones darken to their authored values); all 3D
  goldens unchanged. (audit F5)

- New FFI `setSharpenStrength` / bloom_set_sharpen_strength: the
  composite unsharp mask was hardcoded 0.8 with no runtime control
  while visibly haloing silhouettes at 4K output. Default unchanged.
  (audit F8; manifest entry included — Perry silently no-ops
  undeclared natives)

- docs/tickets.md: EN-021 (SSR+IBL exclusive ownership — deferred
  because a correct fix needs the env-miss fallback in the SSR pass,
  not just the ibl_spec complement) and EN-022 (motion vectors for
  material-system draws — the in-motion quality project).
…e leak

The translucent pass acquires TWO transients when a refractive material
is on screen (scene-colour + depth snapshots) but released only the
colour one. The pool has no auto-reclaim by design, so every frame:
- the still-in-use depth slot can never be reused,
- acquire() allocates a brand-new render-res Depth32Float (~8.3 MB at
  1920x1080 — ~370 MB/s of driver allocation churn at 45 fps),
- the slot vector grows by one forever (linear scans slow down too).

This was the round-2 audit's "translucent_pass CPU mystery" (F7): the
bracket climbed 0.4 ms -> 6.7 ms over ~50 s in every session, tracking
RUN TIME, not scene load. Measured with the audit's instrumented combat
build, same workload, before vs after:

  before (leaky):  750 us at t=8, dipping then climbing to 1144 us at
                   t=58 and still growing
  after (fixed):   30-46 us, flat for the entire run  (~16-26x)

On the 4 GB shared-memory dev iGPU the unbounded VRAM growth is also a
plausible contributor to long-session instability (EN-020 heap
pressure).

Also:
- transient pool: leak watchdog — warn at every power-of-two slot count
  past 64, naming the acquire-without-release failure mode. This exact
  bug cost a day of profiler archaeology; the next one costs a log line.
- docs/tickets.md: EN-023 (GI software path — colored bounce is
  unreachable on non-RT adapters; measured achromatic <=2.5%).
Round-2 audit F10: compose is `hdr + ssr` and fs_main_scene already
adds IBL specular into hdr, so SSR-hit pixels double-counted specular
for roughness ~0.05-0.85 (worst on metals at r~0.55-0.75).

The fix is ownership, not subtraction:
- fs_main_scene scales ibl_spec by the complement of SSR's OWN
  roughness fade x its strength. The share rides the free
  dir_light_count.z lane (written per frame; 0 when SSR is disabled,
  so the full IBL term returns automatically).
- The SSR march no longer returns black on a miss: camera-facing rays
  and off-screen/no-hit marches fall back to the env panorama sampled
  by the world-space reflection direction at the material path's
  roughness x 6 mip ramp, x env intensity (camera_pos.w), x the same
  fresnel/fade/strength weighting as a hit. Without this, reducing
  ibl_spec would darken every off-screen reflection - the reason the
  ticket deferred the one-line version.
- SsrParams gains the view->world rotation (transpose of the view 3x3)
  + env LOD/intensity; SSR bind group gains the env panorama at
  bindings 9/10 and its cache invalidates wherever the env source
  swaps (HDR upload, panorama/procedural lighting-bg swaps).

Suite green (99 lib + 7 golden; goldens unchanged within tolerance).
Boot-smoked on the shooter at 4K - no WGSL errors, clean frames.
Closes EN-021.
Round-2 audit F4: on non-RT adapters (the dev 760M) SSGI's SDF path
degraded every transformed instance to flat gray and the SW radiance
cache was light-source-only — colored bounce structurally impossible.

Fixed in this PR:
- instance data now carries WORLD-space AABBs alongside the object-
  space ones (all four shader layout mirrors updated). The SDF broad-
  phase compares its world-space clipmap hits against the world boxes
  — the old object-space comparison only ever matched assets whose
  vertices were already in world space (Sponza). HW paths keep using
  the object-space boxes with hit.world_to_object, unchanged.
- broad-phase picks the SMALLEST containing box, not the first: the
  shooter's +/-140 m terrain proxy otherwise swallowed every hit
  (walls and trees included) and its mostly-empty side cards actively
  darkened the bounce.
- the SW WSRC bake gains a ground-bounce term for below-horizon
  octels (scene-average instance albedo x sun-shadowed irradiance +
  half sky) — it previously returned ~black for every downward miss
  ray, dropping the strongest real bounce source entirely.

Measured honesty (GI pose A/B, sky-normalized, settled):
- ship intensity 1.0: deltas within noise (<=1%), hue unchanged
- intensity 4.0:      +1.4-2.1% luma in shaded receivers, hue still
                      unchanged (G/R 0.9456 vs 0.9460)
The data path is now correct, but visible colored bounce on the SW
tier remains capped downstream (probe resolve magnitude, composite AO
multiply on exactly the shaded receivers, radius/hit-rate at the
receivers). EN-023 stays open pointing at the resolve/integration
stage; decision D2-B (bank the ~1.6 ms on iGPU) remains sensible until
that lands.

Suite green (99 lib + 7 golden). Boot-smoked at 4K; A/B runs above
were on the live game.
Round-2 audit F6: the present mode was hardcoded Fifo at both surface
config sites, which also made setTargetFPS inert — its sleep-based cap
only engages when vsync is off, and vsync could never be off.

- Renderer::set_present_mode(0=Fifo, 1=Mailbox, 2=Immediate):
  reconfigures the live surface on change; no-op when unchanged; logs
  the switch. All three modes are DXGI-native on Windows.
- FFI bloom_set_present_mode + TS setPresentMode + manifest entry
  (Perry silently no-ops undeclared natives).

Validated on the live game at 4K: "bloom: present mode = Immediate"
followed by getFPS pinning at a steady 29 under setTargetFPS(30) —
the first time the cap has ever engaged. This is the knob that makes
audit decision D1 (operating point) testable: cap-45 / cap-60 /
uncapped can now be compared like-for-like.
Round-2 audit F5: glyphs were rasterized at LOGICAL pixel size and the
2D projection stretched them x1.5 at 150% display scaling — every HUD
string was a bilinear-magnified blur at 4K.

- draw_text_ex rasterizes at size x dpi (dpi = physical surface width /
  logical width) and divides the layout metrics back to logical, so the
  projection's stretch lands the bitmap 1:1 on physical pixels.
- measureText stays in logical units and stays exact: fontdue advances
  are strictly linear in pixel size, so advance(phys)/dpi ==
  advance(logical) up to f32 rounding.
- The glyph atlas warns once when full instead of silently wrapping
  UVs into garbage glyphs (grow/evict is the durable follow-up; the
  physical-size cache entries raise pressure, so the warning matters
  now).

Validated on the live game at 4K: title + HUD render with correct
layout and native-res rasters; no atlas warnings on the shooter's
glyph set.
…erial draws

The material ABI carried PerDraw.prev_mvp "for motion vectors" since
day one, but every submit path filled it with the CURRENT mvp — world
motion vectors were identically zero by construction, so TAA's
motion-adaptive clamp never engaged for material-drawn geometry
(round-2 audit F8, the primary TSR-shimmer mechanism).

- MaterialSystem keeps a per-slot model history (draw slot =
  submission order, stable frame-to-frame — the same identity
  convention the cached-model path relies on). submit_draw /
  submit_draw_instanced now compose prev_vp x prev_model[slot] into
  PerDraw.prev_mvp; a fresh slot falls back to the current model
  (zero object motion on its first frame).
- reset_draw_slot rotates the history and pins the previous frame's
  view-projection (from Renderer::prev_vp_matrix, which already fed
  PerView.prev_view_proj correctly).
- The legacy prev_mvp parameter on the submit APIs is ignored and
  renamed _legacy_prev_mvp (callers passed current-mvp garbage).
- material_abi.wgsl gains `abi_motion_vector(curr, prev)` — the core
  path's exact NDC-delta x 0.5 convention — plus doc guidance for
  static vs wind-displaced vertex shaders (PerFrame.delta_time already
  enables prev-time wind evaluation with no ABI change).

Behavioral no-op until materials read prev_mvp / write velocity (the
shooter's material updates ride a stacked shooter PR). Suite green:
99 lib + 7 golden, all unchanged.
# Conflicts:
#	native/shared/src/ffi_core/visual.rs
#	native/shared/src/renderer/mod.rs
#	package.json
#	src/core/index.ts
Root cause of the round-1/round-2 'unreproducible' AVs and the title-
screen freeze family: alloc_perry_string sized allocations exactly to
header+payload, while Perry's compiled string scanners (split/indexOf)
read word-at-a-time and touch up to a word past byte_len. When an
allocation lands flush against an unmapped page the overread is an AV
(reproduced 3/3 in ~7-29s with the shooter profiler overlay on: faults
in perry_fn_...getProfilerOverlay at +0xe925 and
...getProfilerFrameHistory at +0xf0a3; historical EN-020 signature was
main.exe+0xe8e5 reading 0x...FFF8). Fix: 16 zeroed pad bytes after every
FFI string payload; capacity still reports byte_len so Perry never
writes into the pad. Regression test included.

Diagnostics added while hunting this (kept - they make the next silent
death loud): SetUnhandledExceptionFilter that prints code +
main.exe-relative address and writes a minidump via runtime-loaded
dbghelp (import lib is not on perry's link line), eprintln on
WM_CLOSE/WM_DESTROY (clean-exit path), one-shot log when surface
acquire fails (headless-spin path). Report upstream to Perry: scanner
overread on exact-sized string allocations.
…heir own slices

Tail-padding engine-allocated strings (previous commit) did not stop the
crashes: 3/3 runs still faulted at the same perry_fn offsets, proving the
overread happens on Perry-INTERNAL allocations (split() slices fed to
parseFloat), which the engine cannot pad. Route the per-frame profiler
data across the FFI as f64s instead: bloom_profiler_row_count/_label/
_cpu_us/_gpu_us + _hist_* natives, getProfilerOverlay/getProfilerFrame-
History rewritten on top (no split, no parseFloat; the label crosses
whole and is only drawn). Packed-text FFIs stay for back-compat.

Validated on the shooter: 3/3 runs x 90s gameplay with the overlay ON
continuously, zero faults, correct overlay data - previously 6/6 dead
within 7-29s of overlay time across two link layouts. EN-020 ticket
updated with root cause + upstream repro; remaining: file against Perry,
migrate the OBJ text loader off split/parseFloat when touched.
- Remove Surreal_Engine_Spec_v01.md (pre-rename draft; philosophy lives
  in README + the API itself) and bloom-renderer-spec.md (superseded;
  its Strategic Framing already survives as v2 spec section 6).
  bloom-renderer-spec-v2.md is now the only renderer spec and carries
  an as-built status block (wgpu/WGSL deferred MRT vs planned
  forward+/Slang; what landed from each track; where live status
  lives).
- tickets.md: EN-019 Windows half field-validated on the 4K@150% dev
  box; EN-021/EN-022 implemented (PRs #78, #82 + shooter #4); EN-023
  partially landed (PR #79), stays open pointed at resolve/AO.
- crash-triage-windows.md: rewritten around the in-engine crash
  reporting (stderr + self-written minidumps), symbolizer flag drift,
  WinDbg/lldb tool notes, working repro patterns (PostMessage keys,
  pixel-diff freeze detection), EN-020 case study.
- CLAUDE.md: Windows + test/golden build commands, consumer
  relink/perry-cache rules, real renderer/ tree, hard-won FFI rules
  (manifest discipline, EN-020 numeric-ABI rule, string_header, i64
  scratch pattern), runtime/debug behavior, docs index.
…gation)

One commit because the fixes interleave through renderer/mod.rs and
intermediate splits would not build. Each fix is documented at its site.

LAG (multi-second GPU stalls every ~5s of camera motion on iGPUs):
- Scene-SDF-clipmap rebake was a single brute-force dispatch (64^3 voxels
  x ALL scene triangles, timestamp-less, refired on every 10m of eye
  travel -> 1-2.4s stall inside submit). Now: CPU triangle binning into
  16^3 cells (one-cell expansion, conservative 2.5m narrow-band clamp,
  sphere-trace-safe) + 16 Z-layers/frame baked into a staging volume,
  copied over atomically on completion. Startup GI stall (~2.5s) gone too.
- WSRC bakes one cascade per frame. Also fixes params aliasing: all
  same-frame cascade dispatches read the LAST cascade's uniform because
  queue.write_buffer applies before any encoded command executes.

FLICKER (building face banding/popping, reported on round2/integration):
- Material path sampled shadow cascades with the PREVIOUS frame's VPs
  (PerView uploaded before the shadow fit; the deferred path reads the
  fresh lighting buffer, which is why only material-path receivers
  banded). refresh_shadow_uniforms patches PerView after the fit; the
  splits .w mip-bias slot stays 0 as the material path always had it.
- Cascade pancake extents now grow-fast/shrink-hysteresis at 2m steps;
  animated caster bounds crossing the old 1/16m ceil() steps toggled the
  fitted VP between two matrices every idle-anim cycle.
- Auto-exposure: in-bin percentile interpolation (target was quantized to
  whole 0.22-log2 bins = 16% exposure steps), anchored 2% deadband
  (anchor persisted in the exposure texture .g, now Rg16Float), and
  gap-proportional adaptation rate. Measurement sits downstream of TAA,
  so its wiggle no longer round-trips into visible brightness hunting.
- EN-022 motion vectors: prev_mvp / prev_view_proj were composed from the
  raw jittered previous VP, giving every static pixel a one-texel
  jitter-delta velocity that wobbled TAA history reprojection. All
  velocity references now use prev UNJITTERED proj+view with the CURRENT
  frame's jitter re-applied, cancelling exactly in (curr_ndc - prev_ndc).
- GTAO temporal: the ao_delta>0.35 hard history refresh fired
  simultaneously across whole surfaces (per-frame 2-of-8 direction phase
  is globally shared), replacing converged AO with the noisiest possible
  single-frame estimate. Now: raw sample clamped to history +/-0.15 and
  the phase is dithered across each 2x2 quad so all 4 phases land every
  frame. TAA disocclusion reject deliberately NOT motion-gated -- it is
  what flushes chroma-poisoned history (luma-only variance clamp leaves
  chroma free); weakening it green-tints the frame within seconds.

WINDOWS:
- Windowed mode crashed on the first frame with a scene-reading
  translucent material: default render_scale is 0.5, so
  setRenderScale(0.5) no-ops and windowed (which never gets the WM_SIZE
  the borderless transition forces) kept construction-time render targets
  -> partial Depth32Float snapshot copy -> fatal validation error.
  Windows init now routes through resize() once.
- Swapchain gets COPY_SRC so bloom_take_screenshot's readback is legal,
  and its failure paths now eprintln instead of being swallowed. (The
  FFI is still never invoked by Perry-compiled code -- upstream bug.)

Measured on the 4K/Radeon 760M box: rotating-camera gameplay 40fps with
1-2.4s freezes -> locked 59-60fps, GI enabled throughout; startup worst
frame 2.5s -> ~90ms; shadow banding eliminated (wall-region captures
15-16% alternation -> 0.0% with TAA off, stable with TAA on).
The YCoCg clamp was luma-only (per-channel RGB clamping had caused
chromatic sparkle on grazing stone), but fully unclamped chroma let
stale history colour bleed through on high-contrast edges: green
terrain fringing crawled along cloud and canopy silhouettes during
camera motion — user-visible as flickering. Clamping Co/Cg at 3x the
luma gamma bounds gross cross-object bleed while staying far looser
than the sparkle-prone hard clamp. Verified in windowed gameplay
captures: cloud-edge fringing gone, no reintroduced sparkle.
Perry drops the game-side takeScreenshot FFI call entirely
(PerryTS/perry#6087), so trigger the capture in the window procedure
where no compiler sits in the path: F12 (initial press only) requests
the swapchain readback and writes screenshot_<unix-ms>.png into the
working directory. Depends on the earlier COPY_SRC surface-usage fix;
verified end to end via PostMessage-injected F12 -> valid 4K PNG.
The composite unsharp mask ran at strength 0.8 (the engine already
flagged it as visibly haloing silhouettes at 4K). Under half-res TSR
the building silhouette edge wobbles a sub-pixel per frame, and a strong
unsharp turns that wobble into a crawling bright/dark rim. Lower the
default to 0.5 and clamp the detail term to +/-0.12: fine texture (small
local contrast) sharpens as before, but extreme high-contrast edges no
longer overshoot into a halo or amplify the sub-pixel shimmer.
@proggeramlug proggeramlug merged commit 74ee9c7 into main Jul 8, 2026
7 of 10 checks passed
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5dc57f8b-ee4b-42da-9b4f-63f41807419b

📥 Commits

Reviewing files that changed from the base of the PR and between f8614c6 and 7c5f20d.

⛔ Files ignored due to path filters (3)
  • native/shared/tests/golden/lit_primitives_3d.png is excluded by !**/*.png
  • native/shared/tests/golden/many_point_lights_clustered_scene.png is excluded by !**/*.png
  • native/shared/tests/golden/shapes_2d.png is excluded by !**/*.png
📒 Files selected for processing (35)
  • CLAUDE.md
  • Surreal_Engine_Spec_v01.md
  • bloom-renderer-spec-v2.md
  • bloom-renderer-spec.md
  • docs/crash-triage-windows.md
  • docs/tickets.md
  • native/shared/shaders/material_abi.wgsl
  • native/shared/src/engine.rs
  • native/shared/src/ffi_core/assets.rs
  • native/shared/src/ffi_core/game_loop.rs
  • native/shared/src/ffi_core/visual.rs
  • native/shared/src/profiler.rs
  • native/shared/src/renderer/draw2d.rs
  • native/shared/src/renderer/formats.rs
  • native/shared/src/renderer/material_system.rs
  • native/shared/src/renderer/material_system_tests.rs
  • native/shared/src/renderer/mod.rs
  • native/shared/src/renderer/scene_pass.rs
  • native/shared/src/renderer/shaders/ao.rs
  • native/shared/src/renderer/shaders/core.rs
  • native/shared/src/renderer/shaders/gi.rs
  • native/shared/src/renderer/shaders/mod.rs
  • native/shared/src/renderer/shaders/post.rs
  • native/shared/src/renderer/shaders/ssgi.rs
  • native/shared/src/renderer/shadow_pass.rs
  • native/shared/src/renderer/ssgi_pass.rs
  • native/shared/src/renderer/ssr_pass.rs
  • native/shared/src/renderer/transient.rs
  • native/shared/src/shadows.rs
  • native/shared/src/string_header.rs
  • native/shared/src/text_renderer.rs
  • native/windows/Cargo.toml
  • native/windows/src/lib.rs
  • package.json
  • src/core/index.ts

📝 Walkthrough

Walkthrough

This PR updates engine documentation and tickets, introduces a numeric profiler FFI ABI with Perry string padding hardening, reconstructs previous-frame model history for motion vectors, extends SSR with environment fallback and IBL specular ownership sharing, reworks scene SDF clipmap baking into an amortized job with world-space GI data, applies several renderer visual-stability fixes, and adds Windows crash-reporting/telemetry.

Changes

Bloom Engine renderer and tooling update

Layer / File(s) Summary
Documentation and ticket updates
CLAUDE.md, bloom-renderer-spec-v2.md, docs/crash-triage-windows.md, docs/tickets.md
Build/FFI/architecture guidance, renderer spec status, a Windows crash-triage runbook, and EN-019–EN-023 ticket entries are updated.
Numeric profiler ABI and string padding
native/shared/src/ffi_core/game_loop.rs, native/shared/src/string_header.rs, native/shared/src/profiler.rs, package.json, src/core/index.ts
New numeric FFI profiler row/history accessors replace text parsing, Perry strings get zeroed tail padding, and stale profiler labels are evicted.
EN-022 motion vector reconstruction
native/shared/shaders/material_abi.wgsl, native/shared/src/engine.rs, native/shared/src/renderer/material_system*.rs, native/shared/src/renderer/mod.rs
Per-draw previous-model history and a stable velocity-reference VP matrix are added and wired into shadow/material/reflection uniform updates.
EN-021 SSR environment fallback and IBL ownership
native/shared/src/renderer/mod.rs, native/shared/src/renderer/ssr_pass.rs, native/shared/src/renderer/shaders/ssgi.rs, native/shared/src/renderer/shaders/core.rs
SSR gains an environment-texture miss fallback, and IBL specular is scaled to avoid double-counting with SSR.
GI/SDF clipmap amortized bake
native/shared/src/renderer/formats.rs, native/shared/src/renderer/mod.rs, native/shared/src/renderer/shaders/gi.rs, native/shared/src/renderer/shaders/ssgi.rs, native/shared/src/renderer/ssgi_pass.rs
Scene SDF clipmap baking is rewritten into a binned, sliced, staged job, and world-space AABB/ground-albedo data is added to GI structures and shaders.
Renderer visual stability fixes
native/shared/src/renderer/*, native/shared/src/shadows.rs, native/shared/src/text_renderer.rs
Sharpen/present-mode controls, exposure format change, AO/TAA/composite stability fixes, shadow pancake hysteresis, sRGB color correction, and leak fixes are added.
Windows crash reporting and telemetry
native/windows/Cargo.toml, native/windows/src/lib.rs
A Win32 unhandled-exception minidump filter, PDB line tables, screenshot hotkey, adapter telemetry, and resize wiring are added.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TS as TypeScript (index.ts)
  participant FFI as Native FFI (game_loop.rs)
  participant Profiler as Profiler (profiler.rs)
  TS->>FFI: bloom_profiler_row_count/label/cpu_us/gpu_us(i)
  FFI->>Profiler: snapshot()
  Profiler-->>FFI: row data (f64 values)
  FFI-->>TS: numeric row values
  TS->>FFI: bloom_profiler_hist_count/cpu_us/gpu_us(i)
  FFI->>Profiler: frame_history()
  Profiler-->>FFI: history samples
  FFI-->>TS: numeric history values
Loading
sequenceDiagram
  participant Renderer as Renderer (mod.rs)
  participant MaterialSystem as MaterialSystem
  participant Shader as material_abi.wgsl
  Renderer->>MaterialSystem: reset_draw_slot(prev_vp)
  MaterialSystem->>MaterialSystem: rotate prev_models/cur_models
  Renderer->>MaterialSystem: submit_draw(model, ...)
  MaterialSystem->>MaterialSystem: compute prev_mvp = prev_vp * prev_model
  MaterialSystem->>Shader: PerDrawUniforms(prev_mvp)
  Shader->>Shader: abi_motion_vector(curr_clip, prev_clip)
Loading
sequenceDiagram
  participant OS as Windows OS
  participant WndProc as wndproc
  participant CrashReport as crash_report module
  participant DbgHelp as dbghelp.dll
  OS->>WndProc: unhandled SEH exception
  WndProc->>CrashReport: install()-registered filter invoked
  CrashReport->>CrashReport: compute module-relative address
  CrashReport->>DbgHelp: MiniDumpWriteDump
  DbgHelp-->>CrashReport: minidump written to tools/.testout/dumps/
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch round2/integration

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant