From 47601cbbb837405a9f8176188792771e030d7a28 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 12 Oct 2026 18:00:16 -0400 Subject: [PATCH] [Fix] (Buffer): refresh persistent read maps at a client-mapped buffer barrier --- MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp | 10 ++++++++++ MobileGL/MG_State/GLState/BufferState/BufferObject.h | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index c9b649ef..f0f03420 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -9,6 +9,7 @@ #include "GL_Drawing.h" #include #include +#include #include #include #include @@ -936,6 +937,15 @@ namespace MobileGL::MG_Impl::GLImpl { } MGP_FILL(MemoryBarrier); memoryBarrier(barriers); + // CLIENT_MAPPED_BUFFER_BARRIER_BIT asks for the shader writes issued so far to reach + // the client's persistent maps (GL 4.6 core 7.13). A persistent READ map hands out the + // frontend shadow, which only an explicit pull refreshes, and an application may read + // it after any command that waited for the GPU (a glGetTexImage, say) rather than after + // a fence - so pull here, while the writes are known to be ordered ahead of the read. + // Only buffers with a GPU write outstanding pay for it. + if ((barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) != 0) { + MG_State::GLState::SyncPersistentReadMapsFromGpu(); + } } void TextureBarrier() { diff --git a/MobileGL/MG_State/GLState/BufferState/BufferObject.h b/MobileGL/MG_State/GLState/BufferState/BufferObject.h index 118d2267..4bd69e94 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferObject.h +++ b/MobileGL/MG_State/GLState/BufferState/BufferObject.h @@ -305,7 +305,8 @@ namespace MobileGL { // CLIENT_MAPPED_BUFFER_BARRIER_BIT barrier before that fence). The pointer such a map // hands out is the frontend shadow, which nothing else pulls the GPU's bytes into, so // these two waits refresh every live persistent read map that has a GPU write - // outstanding. + // outstanding. A CLIENT_MAPPED_BUFFER_BARRIER_BIT barrier refreshes them too, for an + // application that reads after some other wait instead of a fence. void SyncPersistentReadMapsFromGpu(); } // namespace MG_State::GLState } // namespace MobileGL