wgpu streaming: screen-space AABB priority + grace period + interactive heartbeat

The chunk priority metric is now the 2D projected pixel area of the
chunk's AABB on screen — 8 corners projected through view-projection,
2D axis-aligned bbox of the projected points, clamped to viewport.
This replaces the prior bounding-sphere-radius² metric, which was a
3D approximation: it treated a 322 × 55 × 5 m slab as a 163 m sphere,
giving it the same huge priority face-on or edge-on. The new metric
genuinely answers "what would this chunk's AABB cover if rendered
solid given the current camera and viewport."

Newly-loaded chunks get a 30-frame grace period at full priority
(visibility_history floor temporarily forced to 1.0). Without it,
just-loaded chunks crashed to history=0 → effective priority = pri ×
0.05 → immediately reverse-swapped by the chunk they displaced.
Cycle starved the per-frame load budget so candidates ranked below
the cyclers never got attempted. 30 frames = HISTORY_ALPHA's time
constant — enough for visibility_history to develop meaningfully.

EVICT_PRIORITY_RATIO bumped 1.21 → 2.0 to suppress more swap noise
between similar-priority chunks.

Interactive heartbeat log added: every render in non-bench mode prints
[frame] with fps, ms, obj, sub_draws, hiz_rej, cull, stream, chunks
breakdown (resident/frustum/total + missing count), VRAM, model count.
Every 30 frames when something's missing, also dumps:
- top 8 models by missing chunk count
- top 20 missing chunks by priority (with AABBs)
- bottom 5 residents by effective priority
- all chunks of brace.ifc (one-off diagnostic, hardcoded
  for the brace-visibility investigation)

The heartbeat made the streaming bug visible: a brace model that
isolation-loads correctly is missing in the full set because slabs
covering more pixels win the priority contest. Per-model fairness or
manual pinning are the remaining options if pixel-area + grace +
hysteresis isn't enough — left for follow-up so the user can decide
based on real testing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-28 22:19:24 +10:00
parent 3d368e0079
commit c7fba1abb8
3 changed files with 405 additions and 59 deletions
+10
View File
@@ -520,6 +520,16 @@ private:
double bench_stream_ms_total_ = 0.0; // driveStreamingLoads only
double bench_hiz_readback_ms_total_ = 0.0;
double bench_submit_ms_total_ = 0.0;
// Last-frame per-phase times. Available in interactive mode (no
// bench) so the periodic [frame] heartbeat log can show cull /
// stream cost without needing the bench averaging machinery.
double last_cull_ms_ = 0.0;
double last_stream_ms_ = 0.0;
// Tick count for the interactive (non-bench) [frame] heartbeat log.
// Increments every render() and prints stats every N frames.
int interactive_frame_count_ = 0;
};
#endif // WGPUVIEWPORTWINDOW_H