diag(render): §4 flap [clip-route] probe — slot routing + clip-buffer content + landscape scissor
The decisive probe between the two surviving suspects from the 2026-06-09 building-flood-merge handoff (docs/research/2026-06-09-flap-outdoor-fullworld- building-flood-merge-handoff.md section 1), gated by ACDREAM_PROBE_CLIPROUTE=1, all print-on-change: - [clip-route] (RetailPViewRenderer.DrawLandscapeThroughOutsideView): the outside slice slot + NDC AABB + planes, the CellIdToSlot routing table, the region-SSBO bytes DECODED at the routed slot, and the terrain-UBO head — captured after SetTerrainClip + UploadClipFrame + SetClipRouting, i.e. exactly what the landscape draws consume. Pins/refutes suspect (b) and the slot-repack half of suspect (a). - [clip-route-disp] (WbDrawDispatcher.Draw, routed draws only): per-slot instance histogram exactly as staged for binding=3 plus the count of entities dropped by ResolveSlotForFrame CULL. Pins/refutes the instance-routing half of suspect (a). - [clip-route-scis] (GameWindow.DrawRetailPViewLandscapeSlice): the ACTUAL GL scissor enable + box read back right after BeginDoorwayScissor — the whole landscape pass (sky + terrain + outdoor entities + player) draws inside this box, so a doorway-sized box here IS the full-world kill by construction. Code-reading findings recorded while building the probe: the landscape pass is scissored to slice.NdcAabb end-to-end (GameWindow.cs DrawRetailPViewLandscapeSlice), and ResolveEntitySlot CULLs server entities with null ParentCellId while routing is active — both now directly observable under the probe. Throwaway apparatus — strip once §4 ships. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d877e4329a
commit
682cba36f1
4 changed files with 194 additions and 0 deletions
|
|
@ -343,6 +343,52 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
|
|||
_outdoorVisible = false;
|
||||
}
|
||||
|
||||
// §4 flap [clip-route-disp] probe state (2026-06-10, throwaway): print-on-change
|
||||
// signature + monotonic sequence + reusable histogram. See RenderingDiagnostics
|
||||
// .ProbeClipRouteEnabled for the full probe contract.
|
||||
private string? _lastClipRouteDispSig;
|
||||
private long _clipRouteDispSeq;
|
||||
private readonly SortedDictionary<uint, int> _clipRouteHist = new();
|
||||
|
||||
// §4 flap apparatus (2026-06-10): per-slot instance histogram as staged for binding=3.
|
||||
// grp.Slots is laid out 1:1 with grp.Matrices (binding=0), so this IS the slot content
|
||||
// the GPU reads per instance — if outdoor instances land on the wrong slot (or vanish
|
||||
// into cullEnt) when the building flood merges, this line shows it directly.
|
||||
private void EmitClipRouteDispatchProbe(int culledEntities)
|
||||
{
|
||||
_clipRouteHist.Clear();
|
||||
int total = 0;
|
||||
foreach (var grp in _groups.Values)
|
||||
{
|
||||
var slots = grp.Slots;
|
||||
for (int i = 0; i < slots.Count; i++)
|
||||
{
|
||||
_clipRouteHist.TryGetValue(slots[i], out int c);
|
||||
_clipRouteHist[slots[i]] = c + 1;
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
var sb = new System.Text.StringBuilder(128);
|
||||
sb.Append(System.FormattableString.Invariant(
|
||||
$"outdoorSlot={_outdoorSlot} outdoorVis={(_outdoorVisible ? 'Y' : 'n')} inst={total} cullEnt={culledEntities} slots={{"));
|
||||
bool first = true;
|
||||
foreach (var kv in _clipRouteHist)
|
||||
{
|
||||
if (!first) sb.Append(',');
|
||||
first = false;
|
||||
sb.Append(System.FormattableString.Invariant($"{kv.Key}:{kv.Value}"));
|
||||
}
|
||||
sb.Append('}');
|
||||
|
||||
string sig = sb.ToString();
|
||||
_clipRouteDispSeq++;
|
||||
if (sig == _lastClipRouteDispSig)
|
||||
return;
|
||||
_lastClipRouteDispSig = sig;
|
||||
Console.WriteLine($"[clip-route-disp] n={_clipRouteDispSeq} {sig}");
|
||||
}
|
||||
|
||||
// Phase U.4 CULL sentinel returned by ResolveEntitySlot: the entity's instances
|
||||
// are dropped entirely (not emitted into the binding=0 instance buffer NOR the
|
||||
// binding=3 slot buffer), matching the existing frustum / visible-cell cull.
|
||||
|
|
@ -752,6 +798,11 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
|
|||
uint? populateEntityId = null;
|
||||
uint populateLandblockId = 0;
|
||||
|
||||
// §4 flap [clip-route-disp] probe (2026-06-10, throwaway): entities dropped by
|
||||
// ResolveSlotForFrame's CULL sentinel this Draw. One increment per culled entity —
|
||||
// cheap enough to count unconditionally; emission below is probe-gated.
|
||||
int probeCulledEntities = 0;
|
||||
|
||||
// Tier 1 cache (#53) — fast-path one-shot tracker. The cache stores a
|
||||
// FLAT list of batches across all MeshRefs of an entity, so a single
|
||||
// ApplyCacheHit call already drew every batch. _walkScratch yields
|
||||
|
|
@ -844,6 +895,8 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
|
|||
(_currentEntitySlot, _currentEntityCulled) = ResolveSlotForFrame(
|
||||
_clipRoutingActive, entity.ServerGuid, entity.ParentCellId,
|
||||
_cellIdToSlot, _outdoorSlot, _outdoorVisible);
|
||||
if (_currentEntityCulled)
|
||||
probeCulledEntities++;
|
||||
}
|
||||
prevTupleEntityId = entity.Id;
|
||||
|
||||
|
|
@ -1067,6 +1120,15 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
|
|||
// null) or when no entities walked at all.
|
||||
FinalFlushPopulate(populateEntityId, populateLandblockId, _cache, _populateScratch);
|
||||
|
||||
// §4 flap [clip-route-disp] probe (2026-06-10, throwaway): the per-slot instance
|
||||
// histogram exactly as it will be uploaded to binding=3 (grp.Slots) plus the
|
||||
// culled-entity count. Routed draws only (the landscape pass under DrawInside) so the
|
||||
// unrouted per-cell bucket draws don't oscillate the print-on-change signature.
|
||||
// Emitted BEFORE the anyVao / totalInstances early-outs so an all-culled frame still
|
||||
// reports (inst=0).
|
||||
if (RenderingDiagnostics.ProbeClipRouteEnabled && _clipRoutingActive)
|
||||
EmitClipRouteDispatchProbe(probeCulledEntities);
|
||||
|
||||
// Nothing visible — skip the GL pass entirely.
|
||||
if (anyVao == 0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue