From 14605723f0dc6874f1164445b501e652a0ece650 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Tue, 4 Aug 2026 19:56:28 -0400 Subject: [PATCH] [Fix] (DirectVulkan): flag a transform feedback capture as a GPU write A capture is a GPU write like any shader's, so a later CPU read of the buffer has to wait for it. Only shader storage buffers were flagged, so mapping or reading back a capture buffer could observe whatever the queue had retired so far. Nothing needs copying -- the capture writes land in coherent host-visible storage already -- but coherence only says the writes are visible once they have happened, which is exactly what MarkGpuWritten arranges through the readback op. --- MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index bc08fe00..731ef167 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -8086,8 +8086,11 @@ void main() { return false; } // Host-visible coherent GPU residency: the capture writes land where - // MapBuffer/GetBufferSubData read. + // MapBuffer/GetBufferSubData read. Coherence makes them visible once they + // have happened, so the buffer is also flagged for the wait that a later CPU + // read has to perform - the capture is a GPU write like any shader's. bufferObject->EnsureGpuResidentStorage(); + bufferObject->MarkGpuWritten(); BufferSlice slice{}; if (!m_bufferManager.AcquireResidentSlice(BufferKind::Vertex, bufferObject, slice)) { MGLOG_E("BeginXfbCaptureForDraw: failed to acquire capture buffer %zu", i);