using AcDream.App.Diagnostics; namespace AcDream.App.Rendering.Gpu.Vk; /// /// Campaign V slice V8: the Vulkan arm's render-transaction measurement. /// /// V6h left the Vulkan arm on NullRenderFrameGpuMeasurement, /// which meant was never called at /// all — so a Vulkan run produced no [frame-prof] line, no frame-history /// CSV and no allocation-per-frame column. That is not a missing nicety: the R6 /// soak waits on [frame-prof] boundaries to time its samples, so the /// campaign's performance vehicle could not be pointed at the backend it was /// meant to judge. V8 cannot measure what it cannot instrument, so the /// instrument lands first. /// /// The bracket was deliberately the SAME one GL used. On GL, /// FrameProfilerGpuMeasurement (deleted at Campaign V slice V11) began a /// TimeElapsed query at and ended it at /// , spanning resource preparation, the world scene and /// private presentation but not the swapchain present. This adapter opens and /// closes a Vulkan timestamp scope at exactly those two points, so /// gpu_ms means the same thing in both columns of the V8 table. /// Comparing two differently-bracketed numbers would have been worse than /// reporting none. /// /// Timestamps resolve two or three frames late, which is why the sample /// carries the profiler frame index that ISSUED it /// () rather than being /// credited to the frame that happened to read it — the same pairing the /// deleted GpuFrameTimer used to perform internally on the GL arm. /// internal sealed class VulkanFrameGpuMeasurement : IRenderFrameGpuMeasurement { private readonly FrameProfiler _profiler; private readonly VulkanGpuDevice _device; internal VulkanFrameGpuMeasurement(FrameProfiler profiler, VulkanGpuDevice device) { _profiler = profiler ?? throw new ArgumentNullException(nameof(profiler)); _device = device ?? throw new ArgumentNullException(nameof(device)); } public void BeginFrame() { _profiler.FrameBoundary(); // Drain first: these are measurements of frames that have already // retired, and the queue is bounded by the flight count. while (_device.TryTakeFrameGpuSample(out int frameIndex, out long elapsedUs)) _profiler.RecordGpuSample(frameIndex, elapsedUs); _device.BeginFrameTimerScope(_profiler.CurrentFrameIndex); } public void EndFrame() => _device.EndFrameTimerScope(); }