From 25cb147d972fec907589e693520b0d2ef3933c49 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 11 May 2026 11:28:22 +0200 Subject: [PATCH] fix(perf #N6.1): gate gpu_us read on diag for symmetric toggle behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code-quality review on Task 1 (commit a7c9800) flagged an asymmetric diag gate: the read-before-overwrite block at the top of the dispatcher was not gated on diag, but the frame-counter increment and BeginQuery calls were. If a maintainer toggled ACDREAM_WB_DIAG from "1" to "" mid- session, _gpuQueryFrameIndex would freeze (gated inside if(diag)) while the read kept firing every frame at the same slot — producing duplicate stale samples. Add diag to the read block's outer condition so the read/issue/increment trio is symmetric. One-line change; behavior under the normal usage pattern (env var set at launch, never toggled) is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs index 605b1e6..36ebdc9 100644 --- a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs +++ b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs @@ -772,7 +772,11 @@ public sealed unsafe class WbDrawDispatcher : IDisposable // §3 Q1/Q2 + §4 in // docs/superpowers/specs/2026-05-11-phase-n6-slice1-design.md. int gpuQuerySlot = _gpuQueryFrameIndex % GpuQueryRingDepth; - if (_gpuQueriesInitialized && _gpuQueryFrameIndex >= GpuQueryRingDepth) + // diag is part of the gate so the read/issue/increment trio stays + // symmetric — without it, toggling ACDREAM_WB_DIAG mid-session would + // freeze the frame counter (gated by diag below) while the read kept + // re-reading the same slot, producing duplicate stale samples. + if (diag && _gpuQueriesInitialized && _gpuQueryFrameIndex >= GpuQueryRingDepth) { _gl.GetQueryObject(_gpuQueryOpaque[gpuQuerySlot], QueryObjectParameterName.ResultAvailable, out int avail); if (avail != 0)