mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-17 00:28:31 +09:00
[Fix] (DirectVulkan, tools/trace_replay): preserve resident buffer ordering and coherent trace copies - fix intermittent geometry and UI corruption in Minecraft 26.3-rc-3
Stage updates to adopted GPU-resident buffers on the command timeline instead of overwriting memory that earlier draws still read. Wait for submitted copies as well as pending commands before CPU readback. Commit coherent mapped writes before Android trace buffer copies, and retire buffer shadows on deletion so copies see current vertices and name reuse cannot leave dangling dirty-shadow entries. Validated draw ordering, submitted-copy readback, traced buffer copies, and mapped-buffer deletion/name reuse on Redmi Adreno 830. Minecraft 26.3-rc-3 Magma passed movement, HUD, and menu checks and exited normally; the new trace parsed all 64,410 frames without warnings.
This commit is contained in:
+35
@@ -123,6 +123,41 @@ static void mobilegl_capture_record_request(void) {
|
||||
if brace < 0:
|
||||
raise SystemExit("eglSwapBuffers wrapper has no function body")
|
||||
text = text[:brace + 1] + "\n mobilegl_capture_record_request();" + text[brace + 1:]
|
||||
|
||||
# A buffer copy consumes coherent mapped writes just like a draw. Upstream
|
||||
# only commits shadows at draws, so Minecraft's staging-buffer copies could
|
||||
# consume the previous frame's vertices before the current writes landed.
|
||||
for name in ("glCopyBufferSubData", "glCopyNamedBufferSubData", "glNamedCopyBufferSubDataEXT"):
|
||||
start = text.find(f"void APIENTRY {name}(")
|
||||
if start < 0:
|
||||
raise SystemExit(f"generated egltrace.cpp has no {name} wrapper to patch")
|
||||
brace = text.index("{", start)
|
||||
text = (text[:brace + 1] +
|
||||
"\n GLMemoryShadow::commitAllWrites(gltrace::getContext(), trace::fakeMemcpy);" +
|
||||
text[brace + 1:])
|
||||
|
||||
# Deleting a mapped buffer implicitly unmaps it. Retire its shadow before
|
||||
# the real storage is freed; a later draw must not commit to a deleted map,
|
||||
# and reuse of the GL name must not leave a dangling dirtyShadows entry.
|
||||
retire_shadows = r'''
|
||||
auto *_ctx = gltrace::getContext();
|
||||
for (GLsizei i = 0; i < n; ++i) {
|
||||
auto it = _ctx->sharedRes->bufferToShadowMemory.find(buffers[i]);
|
||||
if (it != _ctx->sharedRes->bufferToShadowMemory.end()) {
|
||||
if (it->second->getMapFlags() != 0) {
|
||||
it->second->unmap(trace::fakeMemcpy);
|
||||
}
|
||||
_ctx->sharedRes->bufferToShadowMemory.erase(it);
|
||||
}
|
||||
}
|
||||
'''
|
||||
for name in ("glDeleteBuffers", "glDeleteBuffersARB"):
|
||||
start = text.find(f"void APIENTRY {name}(")
|
||||
if start < 0:
|
||||
raise SystemExit(f"generated egltrace.cpp has no {name} wrapper to patch")
|
||||
brace = text.index("{", start)
|
||||
text = text[:brace + 1] + retire_shadows + text[brace + 1:]
|
||||
|
||||
generated.write_text(text, encoding="utf-8", newline="\n")
|
||||
return generated
|
||||
|
||||
|
||||
Reference in New Issue
Block a user