From 336ad3444405c26f5d96bc00918084d5a5af8a9c Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 9 May 2026 09:36:13 +0200 Subject: [PATCH] =?UTF-8?q?chore(N.5b):=20TEMPORARY=20perf=20benchmark=20t?= =?UTF-8?q?oggle=20for=20legacy=E2=86=94modern=20terrain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an ACDREAM_LEGACY_TERRAIN=1 env var that routes Draw through the legacy TerrainChunkRenderer instead of the new TerrainModernRenderer. Both renderers are constructed and fed AddLandblock/RemoveLandblock so they stay in sync; only one is drawn per frame. The [TERRAIN-DIAG] log line is labeled /modern or /legacy so the user can tell which numbers they're capturing. Removed in Task 9 along with TerrainChunkRenderer.cs, terrain.vert, and terrain.frag. Usage: \$env:ACDREAM_LEGACY_TERRAIN = "1" # legacy mode \$env:ACDREAM_LEGACY_TERRAIN = \$null # modern mode (default) Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index f8edcaa..f34fb77 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -19,6 +19,12 @@ public sealed class GameWindow : IDisposable private GL? _gl; private IInputContext? _input; private TerrainModernRenderer? _terrain; + // Phase N.5b benchmark toggle (TEMPORARY — removed in Task 9 along with TerrainChunkRenderer): + // when ACDREAM_LEGACY_TERRAIN=1, route Draw through the legacy renderer + // for direct perf comparison. Both renderers are constructed and fed + // AddLandblock/RemoveLandblock; only one is drawn per frame. + private TerrainChunkRenderer? _terrainLegacy; + private bool _useLegacyTerrain; private Shader? _shader; /// Phase N.5b: terrain_modern.vert/.frag program. Owned by /// at draw time but allocated + disposed here. Lives @@ -1445,6 +1451,10 @@ public sealed class GameWindow : IDisposable _terrain = new TerrainModernRenderer(_gl, _bindlessSupport, _terrainModernShader!, terrainAtlas); + // Phase N.5b benchmark toggle (TEMPORARY — see field declaration). + _useLegacyTerrain = Environment.GetEnvironmentVariable("ACDREAM_LEGACY_TERRAIN") == "1"; + _terrainLegacy = new TerrainChunkRenderer(_gl, _shader!, terrainAtlas); + int centerX = (int)((centerLandblockId >> 24) & 0xFFu); int centerY = (int)((centerLandblockId >> 16) & 0xFFu); @@ -1602,6 +1612,7 @@ public sealed class GameWindow : IDisposable _lightingSink.UnregisterOwner(ent.Id); } _terrain?.RemoveLandblock(id); + _terrainLegacy?.RemoveLandblock(id); // Phase N.5b benchmark toggle (TEMPORARY). _physicsEngine.RemoveLandblock(id); _cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu); }); @@ -5122,6 +5133,7 @@ public sealed class GameWindow : IDisposable var meshData = AcDream.Core.Terrain.LandblockMesh.Build( lb.Heightmap, lbXu, lbYu, _heightTable, _blendCtx, _surfaceCache); _terrain.AddLandblock(lb.LandblockId, meshData, origin); + _terrainLegacy?.AddLandblock(lb.LandblockId, meshData, origin); // Phase N.5b benchmark toggle (TEMPORARY). // Step 4: drain pending LoadedCells from the worker thread. while (_pendingCells.TryTake(out var cell)) @@ -6346,7 +6358,11 @@ public sealed class GameWindow : IDisposable // (gated on ACDREAM_WB_DIAG=1, same env var as [WB-DIAG]). Stopwatch // is cheap; only the periodic Console.WriteLine is gated. _terrainCpuStopwatch.Restart(); - _terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb); + // Phase N.5b benchmark toggle (TEMPORARY): pick renderer per ACDREAM_LEGACY_TERRAIN. + if (_useLegacyTerrain) + _terrainLegacy?.Draw(camera, frustum, neverCullLandblockId: playerLb); + else + _terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb); _terrainCpuStopwatch.Stop(); _terrainCpuSamples[_terrainCpuSampleCursor] = (long)(_terrainCpuStopwatch.Elapsed.TotalMicroseconds); _terrainCpuSampleCursor = (_terrainCpuSampleCursor + 1) % _terrainCpuSamples.Length; @@ -8765,7 +8781,7 @@ public sealed class GameWindow : IDisposable long cpuMedUs = TerrainDiagMedianMicros(_terrainCpuSamples); long cpuP95Us = TerrainDiagPercentile95Micros(_terrainCpuSamples); Console.WriteLine( - $"[TERRAIN-DIAG] cpu_ms={cpuMedUs / 1000.0:F2}/{cpuP95Us / 1000.0:F2} " + + $"[TERRAIN-DIAG{(_useLegacyTerrain ? "/legacy" : "/modern")}] cpu_ms={cpuMedUs / 1000.0:F2}/{cpuP95Us / 1000.0:F2} " + $"draws={_terrain?.VisibleSlots ?? 0}/frame " + $"visible={_terrain?.VisibleSlots ?? 0} " + $"loaded={_terrain?.LoadedSlots ?? 0} " + @@ -8813,6 +8829,7 @@ public sealed class GameWindow : IDisposable _meshShader?.Dispose(); _terrain?.Dispose(); + _terrainLegacy?.Dispose(); // Phase N.5b benchmark toggle (TEMPORARY). _shader?.Dispose(); _terrainModernShader?.Dispose(); _sceneLightingUbo?.Dispose();