mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-08 10:33:24 +09:00
[Refactor] (P13 W5 S8): MOBILEGL_BUILD_RECORD_ARM is folded away - the record arm is unconditional - and retired_switches keeps it from coming back.
This commit is contained in:
@@ -18,12 +18,10 @@
|
||||
// needs only the name - the deleter is captured where the archive is constructed - but the
|
||||
// program build reads through it, so the one translation unit that does needs the whole type.
|
||||
#include <MG_State/GLState/ProgramState/ProgramArtifactsCodec.h>
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// R-11's server-owned staging copy. Header-only and package v1's; see its own header block for
|
||||
// why GLESBufferResource does not simply gain a member.
|
||||
#include <MG_Backend/Record/StagedShadow.h>
|
||||
#include <MG_Backend/Record/StagedTextureStore.h>
|
||||
#endif
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
#include <MG_Remote/Server/ServerLoop.h>
|
||||
// P5c (ct): object_death's producer (CONTRACT-P5C.md §5.2) - the death notice's split arm
|
||||
@@ -1256,7 +1254,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return StorageMatchesSize(resource, bufferObject.GetSize());
|
||||
}
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// -------------------------------------------------------------------------------
|
||||
// R-11 - THE SERVER'S OWN COPY OF THE STAGED BYTES. Package v1.
|
||||
//
|
||||
@@ -1304,7 +1301,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
ServerStaged().RequireCoverage(&resource, hostBase, start, end, site);
|
||||
}
|
||||
}
|
||||
#endif // MOBILEGL_BUILD_RECORD_ARM
|
||||
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
// -------------------------------------------------------------------------------
|
||||
@@ -1385,7 +1381,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// The four hostBytes sites read the same in both builds. The non-split expansion is the
|
||||
// ORIGINAL EXPRESSION, character for character - `raw - offset` - so a push or verify build
|
||||
// compiles exactly what it compiled before R-11 and the split arm is the only new behaviour.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
#define MGL_SERVER_STAGED_ADOPT(res, width, bytes, offset, size) \
|
||||
ServerStaged().Adopt(&(res), (width), (bytes), (offset), (size))
|
||||
#define MGL_SERVER_STAGED_DROP(res) ServerStaged().Drop(&(res))
|
||||
@@ -1394,14 +1389,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
ServerStaged().RequireCoverage(&(res), (base), (start), (end), (site))
|
||||
#define MGL_SERVER_STAGED_REQUIRE_PENDING(res, base, frontendSize, site) \
|
||||
RequireStagedCoverageForPendingRanges((res), (base), (frontendSize), (site))
|
||||
#else
|
||||
#define MGL_SERVER_STAGED_ADOPT(res, width, bytes, offset, size) \
|
||||
(static_cast<const Uint8*>(bytes) - (offset))
|
||||
#define MGL_SERVER_STAGED_DROP(res) ((void)0)
|
||||
#define MGL_SERVER_STAGED_DROP_ALL() ((void)0)
|
||||
#define MGL_SERVER_STAGED_REQUIRE(res, base, start, end, site) ((void)0)
|
||||
#define MGL_SERVER_STAGED_REQUIRE_PENDING(res, base, frontendSize, site) ((void)0)
|
||||
#endif
|
||||
|
||||
// The host bytes a range upload/flush reads. On the legacy arm the frontend object's
|
||||
// shadow; on the handle arm the base the last content-carrying call handed over.
|
||||
@@ -1410,9 +1397,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
#endif
|
||||
if (start >= end || hostBase == nullptr) return;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
MGL_SERVER_STAGED_REQUIRE(resource, hostBase, start, end, "upload_range");
|
||||
#endif
|
||||
BindBufferId(TempBufferTarget, resource.id);
|
||||
g_GLESFuncs.glBufferSubData(TempBufferTarget, (GLintptr)start, (GLsizeiptr)(end - start),
|
||||
hostBase + start);
|
||||
@@ -1987,9 +1972,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
auto* glesResource = static_cast<GLESBufferResource*>(resource.get());
|
||||
if (glesResource->contextGeneration != g_bufferContextGeneration) {
|
||||
glesResource->id = 0; // id belonged to a destroyed context
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
RetireT0Import(*glesResource); // P11 B2: its GL store died with that context
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (CanTouchGLNow()) {
|
||||
@@ -2005,10 +1988,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
g_GLESFuncs.glDeleteBuffers(1, &glesResource->id);
|
||||
glesResource->id = 0;
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P11 B2: a T0 store's AHardwareBuffer goes only after a fence behind the delete.
|
||||
RetireT0Import(*glesResource);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
const std::lock_guard<std::mutex> lock(g_deferredBufferReleasesMutex);
|
||||
@@ -2112,7 +2093,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
void Ops_H_Respecify(MG_Pipe::MGPipeHandle res, const MG_Pipe::MGPResourceDesc& desc,
|
||||
const void* initialBytes) {
|
||||
auto* resource = FindBufferResourceForHandle(res);
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P13 W4a (§1.4): ON MONOLITH'S RECORD ARM THE TWIN IS MINTED HERE, not lazily at
|
||||
// the first draw. The record arm's readers have no frontend object to re-read a
|
||||
// base from, so the base this call carries - the client's shadow, for an orphaning
|
||||
@@ -2122,9 +2102,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (resource == nullptr && aliasesFrontend && initialBytes != nullptr) {
|
||||
resource = GetOrCreateBufferResourceForHandle(res);
|
||||
}
|
||||
#else
|
||||
constexpr Bool aliasesFrontend = false;
|
||||
#endif
|
||||
if (resource != nullptr) {
|
||||
// A respecify's companion pointer IS the shadow base (offset 0) - and an
|
||||
// ORPHANING one (glBufferData with NULL) carries HasDefinedContent clear and
|
||||
@@ -2155,11 +2132,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MGL_SERVER_STAGED_DROP(*resource);
|
||||
resource->hostBytes = nullptr;
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P8-C: whatever a shader wrote belonged to the store this call replaces.
|
||||
resource->serverGpuWritten = false;
|
||||
resource->contentSinceRespecify = false;
|
||||
#endif
|
||||
}
|
||||
if (!resource) return; // lazy: the ensure path full-uploads on creation
|
||||
if (resource->immutableStorage) {
|
||||
@@ -2178,13 +2153,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
resource->id = 0;
|
||||
resource->immutableStorage = false;
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P11 B2: a respecified T0 store ends here on the server's side too. Its
|
||||
// AHardwareBuffer is released only after a fence behind the delete (or at once
|
||||
// when the store's context is already gone) - never under a frame in flight,
|
||||
// however the client's own release (at this respecify) raced it.
|
||||
RetireT0Import(*resource);
|
||||
#endif
|
||||
resource->storageInitialized = false;
|
||||
resource->storageSize = 0;
|
||||
resource->pendingRespecify = true;
|
||||
@@ -2219,7 +2192,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const SizeT offset = static_cast<SizeT>(MG_Pipe::MGPipeSubDataBufferOffset(record));
|
||||
const SizeT size = static_cast<SizeT>(MG_Pipe::MGPipeSubDataBufferSize(record));
|
||||
auto* resource = FindBufferResourceForHandle(res);
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// R-11 / ID-52 item 3: under an ACTIVE TRANSPORT this record's bytes are the ONLY
|
||||
// delivery of the buffer's content - the client sends no companion pointer and the
|
||||
// server has no MappedData to fall back on. But the twin is created LAZILY at the
|
||||
@@ -2233,9 +2205,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Config::DataArmIsRecord()) {
|
||||
resource = GetOrCreateBufferResourceForHandle(res);
|
||||
}
|
||||
#endif
|
||||
if (!resource) return;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P11 B2: A T0 STORE TAKES A SERVER-ORIGINATED WRITE GPU-ORDERED. Its pages are the
|
||||
// client's AHardwareBuffer, so there is no staged copy to refresh and the adopted
|
||||
// early return below ("the coherent map already has the bytes") is false for bytes
|
||||
@@ -2294,7 +2264,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (resource != nullptr) resource->serverGpuWritten = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// M-2: UNDER pendingMutex, because this line runs BEFORE the CanTouchGLNow()
|
||||
// test below - i.e. on the arm D-A2 deliberately keeps reachable off the render
|
||||
// thread - while every reader of hostBytes (Ops_H_Readback's drain, the
|
||||
@@ -2317,9 +2286,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// ("these bytes, at this base") and the drain takes this mutex to lift them.
|
||||
resource->hostBytes =
|
||||
MGL_SERVER_STAGED_ADOPT(*resource, ResourceWidthOf(res), bytes, offset, size);
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (size != 0) resource->contentSinceRespecify = true;
|
||||
#endif
|
||||
}
|
||||
if (resource->pendingRespecify) return; // full re-upload pending anyway
|
||||
if (!CanTouchGLNow() || resource->id == 0 ||
|
||||
@@ -2380,9 +2347,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const std::lock_guard<std::mutex> lock(resource->pendingMutex);
|
||||
resource->hostBytes = MGL_SERVER_STAGED_ADOPT(*resource, ResourceWidthOf(res), bytes,
|
||||
start, end - start);
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (end > start) resource->contentSinceRespecify = true;
|
||||
#endif
|
||||
}
|
||||
if (resource->pendingRespecify) return;
|
||||
if (!CanTouchGLNow() || resource->id == 0 ||
|
||||
@@ -2413,14 +2378,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
#ifdef TRACY_ENABLE
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
#endif
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// The kill-switch arm's own Memcpy, and the one that passes
|
||||
// GL_MAP_INVALIDATE_RANGE_BIT - i.e. the one that tells the driver the old
|
||||
// bytes are dead. Bytes outside the staged coverage are exactly the ones
|
||||
// that claim is false for.
|
||||
MGL_SERVER_STAGED_REQUIRE(*resource, resource->hostBytes, start, end,
|
||||
"flush_range_invalidate_map");
|
||||
#endif
|
||||
BindBufferId(TempBufferTarget, resource->id);
|
||||
void* mappedData = g_GLESFuncs.glMapBufferRange(
|
||||
TempBufferTarget, (GLintptr)start, (GLsizeiptr)(end - start),
|
||||
@@ -2440,15 +2403,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
void Ops_H_Readback(MG_Pipe::MGPipeHandle res, const MG_Pipe::MGPReadback& record) {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// An empty capture may conservatively request a writeback before
|
||||
// any draw materialized this buffer. Resolve its staged resource
|
||||
// exactly as a GPU consumer would, then return the real bytes.
|
||||
auto* resource = MG_Config::DataArmIsRecord()
|
||||
? EnsureBufferResourceForHandle(nullptr, res) : FindBufferResourceForHandle(res);
|
||||
#else
|
||||
auto* resource = FindBufferResourceForHandle(res);
|
||||
#endif
|
||||
if (!resource || resource->id == 0 || !resource->storageInitialized) return;
|
||||
if (!CanTouchGLNow() || resource->contextGeneration != g_bufferContextGeneration) return;
|
||||
if (resource->persistentMapped) {
|
||||
@@ -2517,7 +2476,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// The shadow now matches the backend byte for byte; without this the next draw
|
||||
// would see a newer serial and re-upload the readback over it.
|
||||
resource->syncedChangeSerial = ResourceSerialOf(res);
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P13 W4a: on monolith's record arm the base this twin reads IS the shadow the
|
||||
// writeback just filled, so a whole-store readback is also the refresh
|
||||
// SplitHostBytesForCpuRead would owe. (A copying store's copy is not the
|
||||
@@ -2525,7 +2483,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (MG_Config::RecordArmAliasesFrontend() && readOffset == 0 && size >= ResourceWidthOf(res)) {
|
||||
resource->serverGpuWritten = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Ops_H_Destroy(MG_Pipe::MGPipeHandle res) {
|
||||
@@ -3052,7 +3009,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
#endif // MOBILEGL_BUILD_DISAGGREGATED && __ANDROID__
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// ---- P5c (tx): the TEXTURE half of the resource family, staged server-side --------
|
||||
//
|
||||
// The buffer half's R-11 pattern (ServerStaged() above), for texture levels: the
|
||||
@@ -3110,7 +3066,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// disaggregation did not compile. The narrower fix (guarding the macro block too) is wrong:
|
||||
// that block also carries TextureDiagName and MGB_TEXTURE_RECORD_ARM_SELECTED, which the push
|
||||
// flavour does need. Caught by the `flavours` gate step; see ID-124.
|
||||
#endif // MOBILEGL_BUILD_RECORD_ARM
|
||||
// The inverse of MG_Pipe::MGPipeResourceTargetForTextureTarget, for the sync's
|
||||
// target reads (ConvertTextureTargetToBackendGLEnum and MapToBackendTextureTarget
|
||||
// both want the frontend enum).
|
||||
@@ -3130,7 +3085,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
default: return TextureTarget::Unknown;
|
||||
}
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
|
||||
void Ops_H_TextureSubData(MG_Pipe::MGPipeHandle res, const MG_Pipe::MGPSubData& record,
|
||||
const void* bytes, const MG_Pipe::MGPSubRegion* regions) {
|
||||
@@ -3232,7 +3186,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Record::ServerStagedTexture().Drop(
|
||||
MG_Record::StagedTextureStore::KeyForHandle(res));
|
||||
}
|
||||
#endif // MOBILEGL_BUILD_RECORD_ARM
|
||||
|
||||
const MG_Pipe::MGPipeResourceOps g_glesResourceOps = {
|
||||
.Create = Ops_H_Create,
|
||||
@@ -3244,7 +3197,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
.Destroy = Ops_H_DestroyTracked,
|
||||
.MapPersistent = Ops_H_MapPersistentTracked,
|
||||
.UnmapPersistent = Ops_H_UnmapPersistent,
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
.TextureSubData = Ops_H_TextureSubData,
|
||||
.TextureRespecify = Ops_H_TextureRespecify,
|
||||
.TextureDestroy = Ops_H_TextureDestroy,
|
||||
@@ -3252,7 +3204,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// P11 B2 (T0). Android only: nowhere else is there an AHardwareBuffer to import.
|
||||
.ImportExternal = Ops_H_ImportExternalTracked,
|
||||
.SelfTestExternal = Ops_H_SelfTestExternal,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -3512,7 +3463,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return twin ? twin->get() : nullptr;
|
||||
}
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
void RequireStagedCoverage(GLESBufferResource& resource, const Uint8* hostBase, SizeT start,
|
||||
SizeT end, const char* site) {
|
||||
ServerStaged().RequireCoverage(&resource, hostBase, start, end, site);
|
||||
@@ -3678,7 +3628,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const std::lock_guard<std::mutex> lock(resource.pendingMutex);
|
||||
resource.hostBytes = MGL_SERVER_STAGED_ADOPT(resource, ResourceWidthOf(res), bytes, offset, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
MG_Pipe::MGPipeHandle HandleOfBuffer(const MG_State::GLState::BufferObject* bufferObject) {
|
||||
if (bufferObject == nullptr) return MG_Pipe::kMGPipeNullHandle;
|
||||
@@ -3690,7 +3639,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// allocator probe on a miss - and remembers the answer, which the minting overload
|
||||
// was previously the only writer of. A null answer is deliberately never memoised
|
||||
// (see the comment at HandleOf).
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c merge coordination (CONTRACT-P5C §3.1's named exemption): every caller of
|
||||
// this function is a site whose handle-carrying records (set_shader_buffers /
|
||||
// set_stream_output_targets) the client does not emit until sb, so the probe
|
||||
@@ -3706,7 +3654,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// IsBufferDrawCleanByHandle / MarkBufferGpuWrittenByHandle, which is the last
|
||||
// caller set this function has.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
return g_backendBufferResources.HandleOf(bufferObject);
|
||||
}
|
||||
|
||||
@@ -3816,7 +3763,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// generation, and a shadow that outlived its twin would be looked up by a RECYCLED
|
||||
// address on the next allocation - which is the quietest possible wrong answer.
|
||||
MGL_SERVER_STAGED_DROP_ALL();
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// tx's texture shadows die for the same reason, keyed by handle rather than address
|
||||
// but with the same recycled-identity failure mode: a new context's allocator may
|
||||
// hand out a {slot, gen} the old one's store still answers for.
|
||||
@@ -3827,7 +3773,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
ProcessDeferredT0Retires();
|
||||
SweepT0Retired(/*contextGone=*/true);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3929,11 +3874,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
const auto* record = ResourceRecordOf(res);
|
||||
if (record == nullptr) return false;
|
||||
#if MOBILEGL_PIPE_VERIFY && !MOBILEGL_BUILD_RECORD_ARM
|
||||
MOBILEGL_ASSERT(!record->HasLiveHostWrites,
|
||||
"MGPipeResourceRecord::HasLiveHostWrites is set, but this build has no producer "
|
||||
"for it - P5 b1's producer is MGPSubData::HasLiveHostWrites and is split-only");
|
||||
#endif
|
||||
if (record->HasLiveHostWrites) return false;
|
||||
// THE LAST FRONTEND READ IN THIS FUNCTION, AND P5 b1 RETIRES IT - under split
|
||||
// only, because that is the only build where it is both wrong and replaceable.
|
||||
@@ -4012,7 +3952,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// fallback for the drains that have NO object (the readback flush), and it is
|
||||
// nulled at both of those events.
|
||||
const auto liveHostBase = [&resource, &bufferObject]() -> const Uint8* {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// M-2 / codex 3 / ID-52 item 3: under an ACTIVE TRANSPORT the server's staged
|
||||
// copy (resource->hostBytes, filled by MGL_SERVER_STAGED_ADOPT in Ops_H_SubData /
|
||||
// Ops_H_FlushRange) is the ONLY authoritative base. Preferring the frontend
|
||||
@@ -4024,7 +3963,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
return resource->hostBytes;
|
||||
}
|
||||
#endif
|
||||
if (bufferObject) return bufferObject->MappedData();
|
||||
return resource->hostBytes;
|
||||
};
|
||||
@@ -4041,7 +3979,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
resource->persistentMapped = false;
|
||||
resource->persistentPtr = nullptr;
|
||||
resource->immutableStorage = false;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// m-5 / codex 5: OnBackendContextDestroyed ran MGL_SERVER_STAGED_DROP_ALL(), which
|
||||
// frees every server shadow but does NOT null the hostBytes that name them - so a
|
||||
// twin that SURVIVES a context loss still carries a base into the freed allocation.
|
||||
@@ -4084,7 +4021,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
RetireT0Import(*resource);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4129,12 +4065,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// application ORPHANED the gap is its own undefined content and the upload is
|
||||
// legal (ResourceContentIsDeclared, above). RequireCoverage is a no-op for the
|
||||
// legacy arm's MappedData() and for a non-copying store.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (ResourceContentIsDeclared(res)) {
|
||||
MGL_SERVER_STAGED_REQUIRE(*resource, liveHostBase(), 0, poolSize,
|
||||
"pool_reuse_whole_store");
|
||||
}
|
||||
#endif
|
||||
g_GLESFuncs.glBufferSubData(TempBufferTarget, 0, (GLsizeiptr)poolSize, liveHostBase());
|
||||
if (MG_Util::PipeStats::Enabled()) {
|
||||
MG_Util::PipeStats::AddBytes(MG_Util::PipeStats::ByteClass::StageBuffer,
|
||||
@@ -4161,7 +4095,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
// D-N keeps this call here for P3a. It can queue ranges and move the record, so
|
||||
// everything below is read AFTER it.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (hd, CONTRACT-P5C §3.8): under an active transport the frontend accessor is a
|
||||
// layer-1 surface ("buffer-legacy-arm") and the client's own pre-verb
|
||||
// persistent-map push is the only producer; the call is skipped outright. Under
|
||||
@@ -4169,9 +4102,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (bufferObject && !MG_Config::DataArmIsRecord()) {
|
||||
bufferObject->SyncPersistentMappedRange();
|
||||
}
|
||||
#else
|
||||
if (bufferObject) bufferObject->SyncPersistentMappedRange();
|
||||
#endif
|
||||
|
||||
const auto* record = ResourceRecordOf(res);
|
||||
const SizeT size = record != nullptr ? static_cast<SizeT>(record->Desc.Width) : 0;
|
||||
@@ -4214,13 +4144,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// the last orphan". With no coverage and a clear bit the store is undefined by the
|
||||
// application's own declaration and the upload stays a pure NULL reallocation.
|
||||
const Bool shadowHasContent =
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
MG_Config::DataArmIsRecord()
|
||||
? (record->Desc.HasDefinedContent != 0 ||
|
||||
(ServerStaged().CopiesIntoServerStorage() ? ServerStaged().CoveredRunCount(resource) != 0
|
||||
: resource->contentSinceRespecify))
|
||||
:
|
||||
#endif
|
||||
(bufferObject ? bufferObject->HasDefinedContent() : (record->Desc.HasDefinedContent != 0));
|
||||
const void* initialData = shadowHasContent ? hostBase : nullptr;
|
||||
// M-3 / codex 4: a RespecifyStorageWith(..., initialData != nullptr) is a WHOLE-STORE
|
||||
@@ -4235,14 +4163,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// the bytes it did not write are undefined by its own glBufferData(NULL) - the rule at
|
||||
// ResourceContentIsDeclared. Round 2 refused that idiom and aborted six joint entries.
|
||||
const auto requireWholeStoreCoverage = [&]() {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (initialData != nullptr && record->Desc.HasDefinedContent != 0) {
|
||||
MGL_SERVER_STAGED_REQUIRE(*resource, static_cast<const Uint8*>(initialData), 0,
|
||||
size, "respecify_whole_store");
|
||||
}
|
||||
#else
|
||||
(void)initialData;
|
||||
#endif
|
||||
};
|
||||
|
||||
if (resource->pendingRespecify || !resource->storageInitialized || resource->storageSize != size) {
|
||||
@@ -4942,7 +4866,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// THE SAFETY ARGUMENT P4a MADE AND NEVER RAN (P3b/P4b espryt D1 slice 5).
|
||||
//
|
||||
// "Running the legacy arm" is a real answer in a monolith and a POSTPONED CRASH under a
|
||||
@@ -4974,7 +4897,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
bit, detail);
|
||||
BufferImpl::StopOnArmlessPipeSubsystem(what);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The release-build VOICE for StateBackendObjectRegistry::GetOrCreateByHandle's two
|
||||
// silent refusals, shared by the kinds P4a re-keys so the wording cannot drift between
|
||||
@@ -5096,7 +5018,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"MOBILEGL_PIPE_PUSH leaves kMGPipeSubsystemFramebuffer (bit 9) clear (or refuses "
|
||||
"it) and MOBILEGL_PIPE_LEGACY_MEMOS=0 disables the pre-handle g_fboSynced* arm");
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord() &&
|
||||
verdict != BufferImpl::PipeSubsystemArmVerdict::Handles) {
|
||||
StopOnTransportWithoutRecordArm(
|
||||
@@ -5107,7 +5028,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"to reach it would raise Fatal{UnmigratedPipeInput, "
|
||||
"\"GetFramebufferBindingSlot@<verb>\"} mid-frame instead");
|
||||
}
|
||||
#endif
|
||||
const Bool enabled = verdict == BufferImpl::PipeSubsystemArmVerdict::Handles;
|
||||
MGLOG_D("MGPipe: Espryt framebuffer family runs the %s arm", enabled ? "handle" : "legacy");
|
||||
return enabled;
|
||||
@@ -5141,7 +5061,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"refuses it) and MOBILEGL_PIPE_LEGACY_MEMOS=0 disables the pre-handle texture "
|
||||
"cheap-gate trio");
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord() &&
|
||||
verdict != BufferImpl::PipeSubsystemArmVerdict::Handles) {
|
||||
StopOnTransportWithoutRecordArm(
|
||||
@@ -5150,7 +5069,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"objects and their binding slots, which under a transport are client memory (rule "
|
||||
"E) rather than anything this side owns");
|
||||
}
|
||||
#endif
|
||||
const Bool enabled = verdict == BufferImpl::PipeSubsystemArmVerdict::Handles;
|
||||
MGLOG_D("MGPipe: Espryt texture-resource family runs the %s arm", enabled ? "handle" : "legacy");
|
||||
return enabled;
|
||||
@@ -5177,7 +5095,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"it) and MOBILEGL_PIPE_LEGACY_MEMOS=0 disables UnitSamplerLookupMemo's WeakPtr "
|
||||
"arm and SamplerPassMemo's raw-pointer rows");
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord() &&
|
||||
verdict != BufferImpl::PipeSubsystemArmVerdict::Handles) {
|
||||
StopOnTransportWithoutRecordArm(
|
||||
@@ -5187,7 +5104,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"this side to key on - a WeakPtr that can never lock is not a slower arm, it is a "
|
||||
"unit that samples through whatever it last held");
|
||||
}
|
||||
#endif
|
||||
const Bool enabled = verdict == BufferImpl::PipeSubsystemArmVerdict::Handles;
|
||||
MGLOG_D("MGPipe: Espryt sampler family runs the %s arm", enabled ? "handle" : "legacy");
|
||||
return enabled;
|
||||
@@ -5206,7 +5122,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"MOBILEGL_PIPE_PUSH leaves kMGPipeSubsystemPrograms (bit 12) clear and "
|
||||
"MOBILEGL_PIPE_LEGACY_MEMOS=0 disables g_programTwinLookupMemo");
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord() &&
|
||||
verdict != BufferImpl::PipeSubsystemArmVerdict::Handles) {
|
||||
StopOnTransportWithoutRecordArm(
|
||||
@@ -5216,7 +5131,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"ShaderCso handle with its archive beside the record and there is no frontend "
|
||||
"program here at all");
|
||||
}
|
||||
#endif
|
||||
const Bool enabled = verdict == BufferImpl::PipeSubsystemArmVerdict::Handles;
|
||||
MGLOG_D("MGPipe: Espryt program family runs the %s arm", enabled ? "handle" : "legacy");
|
||||
return enabled;
|
||||
@@ -5487,11 +5401,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// MGPipeSlots().FindByLifetimeId, which is a hash lookup. HandleOf answers
|
||||
// identically - the same allocator probe on a miss - and remembers the answer; a
|
||||
// null answer is deliberately never memoised (SlotTables.h, at HandleOf).
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed twin resolution, named debt inside
|
||||
// the scope - P3b/P4b rekeys the sampler-view registry onto handles.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
return g_backendSamplerViews.HandleOf(textureObject);
|
||||
}
|
||||
} // namespace SamplerViewImpl
|
||||
@@ -6366,15 +6278,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// recorded shadow base for such a resource read freed memory; hostBytes is nulled
|
||||
// at adoption for the same reason, so the fallback below is a null and a refusal
|
||||
// rather than a stale read.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
const Bool sourceGpuWritten =
|
||||
MG_Config::DataArmIsRecord() && resource->serverGpuWritten;
|
||||
if (sourceGpuWritten) {
|
||||
BufferImpl::SplitHostBytesForCpuRead(*resource, binding.Res, "fp64_vertex_narrowing");
|
||||
}
|
||||
#else
|
||||
constexpr Bool sourceGpuWritten = false;
|
||||
#endif
|
||||
const Uint8* const sourceBase =
|
||||
(resource->persistentMapped && resource->persistentPtr != nullptr)
|
||||
? static_cast<const Uint8*>(resource->persistentPtr)
|
||||
@@ -6553,7 +6461,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (m_imageBindableStorageRequired) {
|
||||
return;
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P13 W4b (defect h): monolith's record arm takes the body too; its old arm only
|
||||
// cleared m_isInitialized and replayed the frontend shadow at the next sync.
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
@@ -6704,10 +6611,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Util::PipeStats::AddCalls(MG_Util::PipeStats::CallClass::TextureRemintPulls, 1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)res;
|
||||
(void)record;
|
||||
#endif
|
||||
// Every defined byte now belongs to the server and every required
|
||||
// replay is in its pending set. The existing upload path builds and
|
||||
// fills the immutable/widened carrier from those records.
|
||||
@@ -6948,11 +6851,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const MG_Pipe::MGPipeHandle rearmRes =
|
||||
TextureResourceSubsystemEnabled()
|
||||
? [&]() {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed resolution, named
|
||||
// debt inside the scope - P3b/P4b rekeys the registry.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
return g_backendTextureObjects.HandleOf(stateTextureObject.get());
|
||||
}()
|
||||
: MG_Pipe::kMGPipeNullHandle;
|
||||
@@ -7171,11 +7072,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
static inline GLint s_skipImages = 0;
|
||||
};
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
void ExerciseDefaultUnpackScopeForTesting() {
|
||||
const ScopedDefaultUnpackState scope;
|
||||
}
|
||||
#endif
|
||||
|
||||
// --- Unpack-ring staging (see BufferImpl::UnpackRingAvailable) ---------------
|
||||
// One rectangular (or whole-level) region of a level shadow, repacked TIGHTLY
|
||||
@@ -7859,12 +7758,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// read). Sites that were previously correct only because every writer of a handle-note happens
|
||||
// to be transport-gated now say so themselves, so a future by-handle noter cannot quietly
|
||||
// re-open ID-107's hole somewhere else.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
#define MGB_TEXTURE_RECORD_ARM_SELECTED() \
|
||||
(MG_Config::DataArmIsRecord() && TextureResourceSubsystemEnabled())
|
||||
#else
|
||||
#define MGB_TEXTURE_RECORD_ARM_SELECTED() (false)
|
||||
#endif
|
||||
|
||||
// Returns true when the caller must decline (no handle noted: the caller's bug it always
|
||||
// was, named by the caller's own log line), false when the record arm can serve the call,
|
||||
@@ -8017,7 +7912,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
StampViewSyncKeys(stateTextureObject);
|
||||
}
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5e (tx2): see the declaration for the split between what the record answers and what
|
||||
// the wire still cannot say about a view.
|
||||
void BackendTextureObject::SyncTextureViewToBackendByRecord(
|
||||
@@ -8102,7 +7996,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// The storage's, for the steady arm's reason above (P3b/P4b D3).
|
||||
m_syncedResourceSerial = storageSerial;
|
||||
}
|
||||
#endif
|
||||
|
||||
// P4a (D-D5), the dirty-ownership inversion, applied at the two places the upload loops
|
||||
// below actually ask: "does this (uploadTarget, level) owe an upload" and "it has been
|
||||
@@ -8126,7 +8019,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// pre-P4a expression exactly when MOBILEGL_PIPE_PUSH is off, so the pull build's
|
||||
// preprocessed text, and therefore its object code, is unchanged. Both are #undef'd
|
||||
// immediately after the function.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (tx): THE READS THE FOUR UPLOAD ARMS MAKE, re-sourced. With an active transport the
|
||||
// apply thread may not name the client's TextureObjectMipmap at all (rule E), so on the
|
||||
// handle arm:
|
||||
@@ -8172,15 +8064,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Record::StagedTextureStore::KeyForHandle(pushedRes), static_cast<Uint16>(tgt), \
|
||||
static_cast<Uint16>(lvl), site) \
|
||||
: (obj)->MapMipmapData(tgt, lvl))
|
||||
#else
|
||||
#define MGB_TEXTURE_TARGET(obj) ((obj)->GetTarget())
|
||||
#define MGB_UPLOAD_TARGETS(obj) ((obj)->GetUploadTargets())
|
||||
#define MGB_LEVEL_TEXEL_SIZE(obj, tgt, lvl) ((obj)->GetMipmapTexelSize(tgt, lvl))
|
||||
#define MGB_LEVEL_BYTE_SIZE(obj, tgt, lvl) ((obj)->GetMipmapByteSize(tgt, lvl))
|
||||
#define MGB_LEVEL_TEXELS(obj, tgt, lvl, site) ((obj)->MapMipmapData(tgt, lvl))
|
||||
#endif
|
||||
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (tx): the disaggregated pair adds ONE term and ONE clear to the P4a shapes - the
|
||||
// staged-texture store's GPU-dirty mark (T5: a level the GPU generated dirties the SERVER's
|
||||
// shadow, and the pending set cannot see it). The mark is never set on Espryt today - its
|
||||
@@ -8210,23 +8094,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
(obj)->MarkStorageDirty(tgt, lvl, false); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define MGB_LEVEL_NEEDS_UPLOAD(obj, tgt, lvl) \
|
||||
(pushedStorage != nullptr \
|
||||
? FindPipeTextureUpload(*pushedStorage, static_cast<Uint16>(tgt), static_cast<Uint16>(lvl)) != nullptr \
|
||||
: (obj)->IsStorageDirty(tgt, lvl))
|
||||
// Re-resolves the record itself, so it is safe after any amount of driver work - and it
|
||||
// invalidates any PendingUpload* taken earlier for THIS texture, which is why every such pointer
|
||||
// is used and dropped inside one level's iteration.
|
||||
#define MGB_LEVEL_UPLOAD_DONE(obj, tgt, lvl) \
|
||||
do { \
|
||||
if (pushedStorage != nullptr) { \
|
||||
ConsumePipeTextureUpload(pushedRes, static_cast<Uint16>(tgt), static_cast<Uint16>(lvl)); \
|
||||
} else { \
|
||||
(obj)->MarkStorageDirty(tgt, lvl, false); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// THE STORAGE SHAPE, and on the handle arm it is the DESCRIPTOR's (C.3's d2: "the
|
||||
// m_prevTextureInfo probe re-keyed onto the resource record's Serial AND Desc"; review
|
||||
@@ -8480,7 +8347,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
// SHARED IMAGES: ahead of the view test and of the staged-store and serial gates below,
|
||||
// none of which knows the texels belong to an image - the staged store holds none of
|
||||
@@ -8515,7 +8381,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (MG_Config::DataArmIsRecord() && pushedStorage != nullptr) {
|
||||
// Not a view: fall through to the storage body with the frontend test skipped.
|
||||
} else
|
||||
#endif
|
||||
// A texture created by glTextureView owns no storage: the levels, the format and
|
||||
// every texel belong to the texture it views, and this name only has to be made to
|
||||
// ALIAS them. Everything below - storage allocation, respecification, per-level
|
||||
@@ -8563,14 +8428,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
pushedStorage->Desc.ImageBindableHint != 0 ||
|
||||
(pushedStorage->Desc.BindMask & MG_Pipe::kMGPipeBindShaderImage) != 0;
|
||||
if (pushedWantsImageBindableStorage && !m_imageBindableStorageRequired) {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5e (tx2), ruling 1's arm: under a transport the re-dirty half is a NAMED
|
||||
// refusal at its entry (§5.2) instead of a walk of the client's level shadows;
|
||||
// the push-monolith build keeps the frontend transition exactly as it is.
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
RequireImageBindableStorageByHandle(pushedRes, *pushedStorage);
|
||||
} else
|
||||
#endif
|
||||
RequireImageBindableStorage(stateTextureObject);
|
||||
}
|
||||
|
||||
@@ -8638,7 +8501,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// left the backend name with no levels whatsoever, so the level that WAS defined could
|
||||
// never be sampled or read back. Sync whenever some level holds an image; the per-level
|
||||
// loops below skip the degenerate ones individually.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (gt, CONTRACT-P5C §6 layer 1): on the staged arm the same question is answered
|
||||
// out of the SERVER's staged-texture store, never out of the frontend object - the
|
||||
// store's Defined-ness (fed by the respecify hook and the sub-data adoption) IS "some
|
||||
@@ -8679,7 +8541,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (!stateTextureObject->IsComplete() && !HasAnyDefinedMipmapLevel(stateTextureObject.get())) {
|
||||
MGLOG_D("Texture object with ID: %u has no defined image level, skipping sync.",
|
||||
stateTextureObject->GetExternalIndex());
|
||||
@@ -9263,7 +9124,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
: nullptr;
|
||||
const auto dirtyRegion = [&]() -> MG_State::GLState::MipmapDirtyRegion {
|
||||
if (pendingUpload == nullptr) {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (tx): a level this arm owes with NO pending upload behind it
|
||||
// was dirtied by the GPU (T5), and the dirty answer is the
|
||||
// server's own mark on the staged shadow - the whole level,
|
||||
@@ -9276,7 +9136,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
static_cast<Uint16>(uploadTarget), static_cast<Uint16>(level));
|
||||
return MG_State::GLState::MipmapDirtyRegion{IntVec3{0, 0, 0}, gpuExtent};
|
||||
}
|
||||
#endif
|
||||
return textureMipmapObject->GetStorageDirtyRegion(uploadTarget, level);
|
||||
}
|
||||
// MGPBox is {origin, extent}; MipmapDirtyRegion is {lo, hi}. The
|
||||
@@ -9469,13 +9328,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
region.Z + static_cast<Int32>(region.D)}};
|
||||
}
|
||||
} else
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// tx: with an active transport the rect list is the record's (the
|
||||
// pendingUpload arm above) or nothing - the server's GPU-dirty mark
|
||||
// is whole-level and has no scatter refinement to hand out, and the
|
||||
// frontend's rect model is not this side's to read.
|
||||
if (!MGB_STAGED_TEXTURE_LIVE)
|
||||
#endif
|
||||
dirtyRectCount = textureMipmapObject->GetStorageDirtyRects(
|
||||
uploadTarget, level, dirtyRects,
|
||||
MG_State::GLState::MipmapStorage::kMaxDirtyRects);
|
||||
@@ -9512,14 +9369,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
region.Z + static_cast<Int32>(region.D)}});
|
||||
}
|
||||
} else
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// With an active transport and no record behind the level, the
|
||||
// server's own whole-level GPU-dirty mark is the whole story (the
|
||||
// same reason the rect list above is not read here).
|
||||
if (MGB_STAGED_TEXTURE_LIVE) {
|
||||
dirtyFootprint.clear();
|
||||
} else
|
||||
#endif
|
||||
textureMipmapObject->GetStorageDirtyFootprint(uploadTarget, level, dirtyFootprint);
|
||||
// One box is the union box itself, which the branches below already
|
||||
// upload exactly (as the whole level when it is the whole level).
|
||||
@@ -10052,9 +9907,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
#undef MGB_LEVEL_TEXEL_SIZE
|
||||
#undef MGB_LEVEL_BYTE_SIZE
|
||||
#undef MGB_LEVEL_TEXELS
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
#undef MGB_STAGED_TEXTURE_LIVE
|
||||
#endif
|
||||
|
||||
// P5e (tx2), CONTRACT-P5E §5.2: THIS TWIN'S OWN RECORD. On the by-handle arm the handle
|
||||
// is already known - the caller resolved the record before it resolved this twin and
|
||||
@@ -10066,11 +9919,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Pipe::MGPipeHandle res = m_pushedSyncHandle;
|
||||
if (MG_Pipe::MGPipeHandleIsNull(res)) {
|
||||
if (!stateTextureObject) return nullptr;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed resolution, named debt inside the
|
||||
// scope - the by-handle arm above is what retires it.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
res = g_backendTextureObjects.HandleOf(stateTextureObject.get());
|
||||
}
|
||||
return PipeTextureRecordForHandle(res);
|
||||
@@ -10687,18 +10538,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
storage = record->Desc.ViewOf;
|
||||
}
|
||||
if (auto* twin = ResolveTextureTwin(storage)) twin->NoteDriverSideWrite();
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P8-E: the staged store stops standing for this texture's content (a no-op on a
|
||||
// monolith arm, where the store does not copy).
|
||||
if (!storeFollowsTheWrite && !MG_Pipe::MGPipeHandleIsNull(storage)) {
|
||||
MG_Record::ServerStagedTexture().MarkDriverWritten(
|
||||
MG_Record::StagedTextureStore::KeyForHandle(storage));
|
||||
}
|
||||
#else
|
||||
(void)storeFollowsTheWrite;
|
||||
#endif
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
Bool FollowCopyImageInStagedStore(MG_Pipe::MGPipeHandle source, Uint32 sourceLevel, const IntVec3& sourceOrigin,
|
||||
MG_Pipe::MGPipeHandle destination, Uint32 destinationLevel,
|
||||
const IntVec3& destinationOrigin, const IntVec3& size) {
|
||||
@@ -10737,7 +10583,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
destinationTarget, static_cast<Uint16>(destinationLevel), destinationOrigin,
|
||||
size);
|
||||
}
|
||||
#endif
|
||||
} // namespace TextureImpl
|
||||
|
||||
namespace FramebufferImpl {
|
||||
@@ -10900,11 +10745,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (attachmentObject.IsTexture()) {
|
||||
const auto& textureObject = attachmentObject.GetTexture();
|
||||
SharedPtr<TextureImpl::BackendTextureObject> backendTextureObject;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed twin resolution (and the mint on
|
||||
// a first attach), named debt inside the scope - P3b/P4b rekeys the registry.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
if (auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.Find(textureObject.get())) {
|
||||
backendTextureObject = *backendTextureSlot;
|
||||
} else {
|
||||
@@ -10957,11 +10800,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
} else if (attachmentObject.IsRenderbuffer()) {
|
||||
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed twin resolution (and the mint on
|
||||
// a first attach), named debt inside the scope - P3b/P4b rekeys the registry.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject;
|
||||
if (auto* backendRenderbufferSlot =
|
||||
RenderbufferImpl::g_backendRenderbufferObjects.Find(renderbufferObject.get())) {
|
||||
@@ -11295,14 +11136,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// push-monolith arm keeps the frontend sync it had at f6cfcbd3, token for token,
|
||||
// because tx2's record arm inside SyncMipmapsToBackend is itself selected by
|
||||
// `Transport != Monolith` and cannot answer here.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
backendTextureObject->SyncMipmapsToBackendByHandle(surface.Res);
|
||||
// From here on every draw, clear and blit into this framebuffer can write the
|
||||
// texture behind the staged shadow's back (the frontend arm's note, by handle).
|
||||
TextureImpl::NoteDriverSideTextureWriteByHandle(surface.Res);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
const SharedPtr<MG_State::GLState::ITextureObject> monolithTexture =
|
||||
(monolithAttachment != nullptr && monolithAttachment->IsTexture())
|
||||
@@ -11384,11 +11223,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// GLContext (RecordError) and the by-handle form deliberately does not, because
|
||||
// under a transport there is no application on this side to report it to. On the
|
||||
// push-monolith arm there is, so the monolith arm keeps the object form.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
backendRenderbufferObject->SyncToBackendByHandle(surface.Res);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
const SharedPtr<MG_State::GLState::RenderbufferObject> monolithRenderbuffer =
|
||||
(monolithAttachment != nullptr && monolithAttachment->IsRenderbuffer())
|
||||
@@ -11436,12 +11273,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// (the three-channel colour-renderable widening). GL answers such a read with 1.0, but
|
||||
// the storage holds whatever the draw wrote there, so the readback has to overwrite it.
|
||||
Bool IsAlphaWidenedFallbackReadAttachment() {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
const auto* record = MG_Pipe::MGPipeApplier().ReadFramebuffer();
|
||||
return record && IsAlphaWidenedColorSurface(record->ReadSurface);
|
||||
}
|
||||
#endif
|
||||
const auto* attachmentObject = GetReadColorAttachment();
|
||||
if (attachmentObject == nullptr) {
|
||||
return false;
|
||||
@@ -11450,13 +11285,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
Bool IsFixedPointFallbackReadAttachment() {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
if (MG_Config::DataArmIsRecord()) {
|
||||
const auto* record = MG_Pipe::MGPipeApplier().ReadFramebuffer();
|
||||
return record && record->ReadSurface.Kind != MG_Pipe::kMGPipeSurfaceKindNone &&
|
||||
IsSnormFormat(static_cast<TextureInternalFormat>(record->ReadSurface.InternalFormat));
|
||||
}
|
||||
#endif
|
||||
const auto& readFBO =
|
||||
MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
|
||||
if (!readFBO) {
|
||||
@@ -11623,11 +11456,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// P5c (hd): with an active transport the handle is the caller's
|
||||
// (m_pushedSyncHandle), never the client allocator's - see SyncToBackend.
|
||||
const MG_Pipe::MGPipeHandle fbo =
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
MG_Config::DataArmIsRecord()
|
||||
? m_pushedSyncHandle
|
||||
:
|
||||
#endif
|
||||
g_backendFramebufferObjects.HandleOf(stateFBOObject.get());
|
||||
// ID-19: the OBJECT's record, not "the record of whatever is bound to READ". A
|
||||
// framebuffer whose read buffer is being pushed need not be the read binding at
|
||||
@@ -11801,11 +11632,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// is never probed (T2). A null there means a caller reached this arm without a
|
||||
// record, which the null-record refusal below names.
|
||||
const MG_Pipe::MGPipeHandle fbo =
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
MG_Config::DataArmIsRecord()
|
||||
? m_pushedSyncHandle
|
||||
:
|
||||
#endif
|
||||
g_backendFramebufferObjects.HandleOf(stateFBOObject.get());
|
||||
pushedRecord = PushedFramebufferRecord(fbo);
|
||||
if (pushedRecord == nullptr) {
|
||||
@@ -12083,11 +11912,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// Verify that the backend object's name and parameters match the frontend attachment state
|
||||
if (attachmentObject.IsTexture()) {
|
||||
const auto& textureObject = attachmentObject.GetTexture();
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed twin resolution, named
|
||||
// debt inside the scope - P3b/P4b rekeys the registry.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.Find(textureObject.get());
|
||||
MOBILEGL_ASSERT(backendTextureSlot != nullptr && *backendTextureSlot != nullptr,
|
||||
"No backend texture found while framebuffer reports texture attachment.");
|
||||
@@ -12104,11 +11931,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
"Attachment texture level mismatch between GLES and state object.");
|
||||
} else if (attachmentObject.IsRenderbuffer()) {
|
||||
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): frontend-keyed twin resolution, named
|
||||
// debt inside the scope - P3b/P4b rekeys the registry.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
auto* backendRboSlot =
|
||||
RenderbufferImpl::g_backendRenderbufferObjects.Find(renderbufferObject.get());
|
||||
MOBILEGL_ASSERT(
|
||||
@@ -12253,11 +12078,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
fbo.Slot, fbo.Gen);
|
||||
return;
|
||||
}
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// Kept in step for the monolith-glue overloads that still resolve their record
|
||||
// through it (SyncReadBufferToBackend's push arm).
|
||||
m_pushedSyncHandle = fbo;
|
||||
#endif
|
||||
const GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
||||
Bind(asTarget);
|
||||
|
||||
@@ -13109,7 +12932,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// outside the frontend's array, which cannot be addressed at all.
|
||||
Uint BoundImageUnitFormat(Int unit) {
|
||||
if (unit < 0 || unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) return 0;
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5e (fb, §5.4): the format-less image bake asks what format the APPLICATION
|
||||
// named at this unit, and under a transport the record is the only statement of
|
||||
// it - MGPImageView::InternalFormat is that same GLenum, copied by the client
|
||||
@@ -13120,7 +12942,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (static_cast<SizeT>(unit) >= st.BoundShaderImages.size()) return 0;
|
||||
return static_cast<Uint>(st.BoundShaderImages[static_cast<SizeT>(unit)].InternalFormat);
|
||||
}
|
||||
#endif
|
||||
return static_cast<Uint>(MG_Pipe::gPipeInputs.GetImageTextureBinding(unit).Format);
|
||||
}
|
||||
|
||||
@@ -15241,14 +15062,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// nine-clause rebuild condition reads on the handle arm; the clause COUNT does not
|
||||
// shrink, its inputs move (D-H5).
|
||||
if (ProgramSubsystemEnabled()) {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): MONOLITH GLUE ONLY. This is the frontend-keyed
|
||||
// lookup the phase exists to retire, and it survives here for the reason
|
||||
// ruling 1 (ID-81) gives: under Transport=monolith the push build keeps its
|
||||
// frontend arms token for token, and this arm is only ever reached from them.
|
||||
// The handle half below names no frontend identity at all.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
// The reader hides the composite band, so a program-pipeline composite - which
|
||||
// the server must never learn is one - resolves through the same call.
|
||||
const MG_Pipe::MGPipeHandle cso = g_backendProgramObjects.HandleOf(stateProgramObject.get());
|
||||
@@ -15593,12 +15412,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// the values are taken from the object, which in monolith are the very
|
||||
// values the client content-addressed, so the picture stays right while
|
||||
// the gap is visible rather than silent.
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): the registration probe below resolves the
|
||||
// sampler's handle by frontend identity - frontend-keyed twin resolution,
|
||||
// named debt inside the scope - P3b/P4b rekeys the registry onto handles.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
if (!MG_Pipe::MGPipeHandleIsNull(
|
||||
g_backendSamplerObjects.HandleOf(stateSamplerObject.get()))) {
|
||||
MGLOG_E_ONCE("MGPipe: sampler %u was synced without its unit's SamplerCso handle, so "
|
||||
@@ -15849,12 +15666,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
const MG_Pipe::MGPipeResourceRecord* pushedRecord = nullptr;
|
||||
if (TextureResourceSubsystemEnabled()) {
|
||||
#if MOBILEGL_BUILD_RECORD_ARM
|
||||
// P5c (G6, CONTRACT-P5C §5.4): the renderbuffer's handle is resolved by
|
||||
// frontend identity below - frontend-keyed twin resolution, named debt inside
|
||||
// the scope - P3b/P4b rekeys the registry onto handles.
|
||||
const MG_Pipe::MGPipeFrontendKeyedRegistryScope frontendKeyedRegistry;
|
||||
#endif
|
||||
// MONOLITH GLUE, named as such: the Renderbuffer handle of an object this
|
||||
// backend still arrives holding. Under a real split it rides in the payload.
|
||||
const MG_Pipe::MGPipeHandle res = g_backendRenderbufferObjects.HandleOf(stateRBOObject.get());
|
||||
|
||||
Reference in New Issue
Block a user