chore(diag): FPS_PROF=2 clean split + [CPU-PHASE] DrawInside timers [throwaway]

Decouple the whole-frame TimeElapsed query from the per-pass glFinish so the
CPU-vs-GPU split is honest: ACDREAM_FPS_PROF=2 runs the frame query with NO
per-pass glFinish (PassGpuEnabled stays "1"-gated). Plus [CPU-PHASE] timers
around each DrawInside phase (flood/assemble/prepare/partition/landscape/
portalmask/shells/cellobjects/dynamics) — the CPU analog of [PASS-GPU].

This is what proved the dense town is ~96% CPU-bound (GPU=0.5ms) and that the
cost is per-cell draw submission (cellobjects ~3.5ms), not the portal floods /
punch-seal / clip allocs the static analysis had guessed. Throwaway; strip with
the rest of the FPS apparatus (plan Task 5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-23 20:41:45 +02:00
parent 1473e4dbf9
commit fe1f81371a
3 changed files with 57 additions and 2 deletions

View file

@ -65,6 +65,18 @@ public sealed class RetailPViewRenderer
{
ArgumentNullException.ThrowIfNull(ctx);
// THROWAWAY CPU sub-phase timing (ACDREAM_FPS_PROF=2 clean-split): attribute
// which CPU phase of DrawInside eats the dense-town frame. Strip with the FPS
// apparatus (plan Task 5). Zero-alloc: GetTimestamp/GetElapsedTime + a direct-
// call local fn (struct closure over _ts, never a delegate).
long _ts = System.Diagnostics.Stopwatch.GetTimestamp();
void Phase(string n)
{
if (FrameProfiler.CpuPhaseEnabled)
FrameProfiler.AddCpuPhase(n, System.Diagnostics.Stopwatch.GetElapsedTime(_ts).TotalMilliseconds);
_ts = System.Diagnostics.Stopwatch.GetTimestamp();
}
var pvFrame = PortalVisibilityBuilder.Build(
ctx.RootCell,
ctx.ViewerEyePos,
@ -101,9 +113,11 @@ public sealed class RetailPViewRenderer
&& ctx.NearbyBuildingCells is not null
&& pvFrame.OutsideView.Polygons.Count > 0)
BuildInteriorRootLookIns(ctx, pvFrame);
Phase("flood");
var clipAssembly = ClipFrameAssembler.Assemble(_clipFrame, pvFrame);
UploadClipFrame(ctx.SetTerrainClipUbo);
Phase("assemble");
// R1: draw EVERY visible cell (retail cell_draw_list), not only the cells the
// assembler handed a clip-slot. This feeds the Prepare filter + entity partition,
@ -136,6 +150,7 @@ public sealed class RetailPViewRenderer
centerLbX: ctx.RenderCenterLbX,
centerLbY: ctx.RenderCenterLbY,
renderRadius: ctx.RenderRadius);
Phase("prepare");
var partition = InteriorEntityPartition.Partition(prepareCells, ctx.LandblockEntries);
var result = new RetailPViewFrameResult
@ -189,12 +204,18 @@ public sealed class RetailPViewRenderer
}
}
Phase("partition");
DrawLandscapeThroughOutsideView(ctx, clipAssembly, partition, viewcone);
Phase("landscape");
UseIndoorMembershipOnlyRouting();
DrawExitPortalMasks(ctx, pvFrame, clipAssembly, drawableCells);
Phase("portalmask");
DrawEnvCellShells(pvFrame);
Phase("shells");
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition, viewcone);
Phase("cellobjects");
DrawDynamicsLast(ctx, partition, viewcone, ctx.RootCell.IsOutdoorNode);
Phase("dynamics");
return result;
}