mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Refactor] (MG_State, MG_Backend): PipeResource storage layer + zero-copy coherent persistent maps
Introduce a Mesa pipe_resource-style PipeResource that owns a GL buffer's bytes and its backend GPU resource, abstracting WHERE the authoritative bytes live: - Shadow mode (non-persistent buffers): a CPU Vector; the backend keeps its own GPU copy in sync via BufferBackendOps, exactly as before. - Persistent mode (coherent GL_MAP_PERSISTENT maps): the backend's host-visible, COHERENT, persistently-mapped GPU memory is the single source of truth. The app writes into it directly, every reader resolves against it, and NO per-write backend transfer happens. The CPU shadow is released. BufferObject no longer owns a raw shadow Vector; it holds a PipeResource and exposes one accessor, MappedData(), that all readers go through. Every buffer-data consumer (UBO payload, PBO texture upload, indirect draws, resident/streamed uploads, both backends) was migrated from GetDataReadOnly()->data() to MappedData(), so a persistent buffer's readers see GPU memory - not a stale shadow. That stale-shadow inconsistency is what corrupted rendering (wrong UBOs -> misplaced/"lost" vertices) in the first zero-copy attempt (625c8a6, reverted in 896cafc); routing every consumer through one accessor makes it structurally impossible. Backends provide the map via BufferBackendOps::AcquirePersistentMap: - DirectVulkan: a HOST_VISIBLE|HOST_COHERENT (required, not just requested), persistently mapped resident VkBuffer carrying every usage, seeded from the shadow, never recreated; AcquireResidentSlice binds it directly. - DirectGLES: EXT_buffer_storage immutable persistent+coherent glMapBufferRange, falling back to the shadow when the extension is absent. Fixes the ~7GB GpuMemory OOM + 100%-CPU/ANR running modern Blaze3D Minecraft on both Magma and Espryt (per-draw whole-buffer re-upload of the coherent persistent ring buffer), without the coherency/stale-read hazards of the reverted attempt. BufferTest: zero-copy stress guard (15,360 draws -> 0 per-draw transfers, and every reader resolves to GPU memory) + a shadow-fallback test. Host suite: 203/203 pass. Device verification pending.
This commit is contained in:
@@ -779,7 +779,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const auto& pixelUnpackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||
if (pixelUnpackBufferObject) {
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
if (!originalPixels) {
|
||||
@@ -896,7 +896,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (pixelUnpackBufferObject) {
|
||||
MGLOG_D("TexSubImage2D_State: Using Pixel Unpack Buffer Object ID: %u",
|
||||
pixelUnpackBufferObject->GetExternalIndex());
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
|
||||
@@ -982,7 +982,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const auto& pixelUnpackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||
if (pixelUnpackBufferObject) {
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
if (!originalPixels) {
|
||||
@@ -1393,7 +1393,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (pixelUnpackBufferObject) {
|
||||
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
||||
pixelUnpackBufferObject->GetExternalIndex());
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
|
||||
@@ -1512,7 +1512,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (pixelUnpackBufferObject) {
|
||||
MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__,
|
||||
pixelUnpackBufferObject->GetExternalIndex());
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
|
||||
@@ -1603,7 +1603,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const auto& pixelUnpackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||
if (pixelUnpackBufferObject) {
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
|
||||
@@ -3020,7 +3020,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const auto& pixelUnpackBufferObject =
|
||||
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||
if (pixelUnpackBufferObject) {
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->GetDataReadOnly()->data()) +
|
||||
originalPixels = reinterpret_cast<const char*>(pixelUnpackBufferObject->MappedData()) +
|
||||
reinterpret_cast<SizeT>(pixels);
|
||||
}
|
||||
if (!originalPixels) {
|
||||
|
||||
Reference in New Issue
Block a user