mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[MG_Backend, MG_State] (Disaggregated): P5e tx2 - the two the lane found: Magma's blit read and the copy endpoint's own sync
- The widened MipmapStorage rows are backend-kind-keyed (ruling 12's shape): Magma is lockstep through P7 and its named blit still asks a frontend texture IsComplete() (VulkanRenderer's ResolveColorBlitBinding), which the unconditional widening aborted. The MUTATOR rows stay unconditional - no backend may write a frontend texture's storage from the apply thread, and none does. - CopyTexImage2D / CopyTexSubImage2D sync their DESTINATION by handle instead of merely looking its twin up. A copy destination is not sampled by the draw program, so the sampler-view window never brings it across; the pre-P5e frontend walk over every slot of every touched unit happened to sync it as a side effect. This is the "waited texture ops" term of the named narrowing (P5e-5) being made real rather than assumed.
This commit is contained in:
@@ -9775,14 +9775,20 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
||||
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
||||
const auto* dstRecord = PipeTextureRecordForHandle(dstHandle);
|
||||
auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.FindByHandle(dstHandle);
|
||||
if (backendTextureSlot == nullptr || *backendTextureSlot == nullptr || dstRecord == nullptr) {
|
||||
// P5e (tx2): SYNCED, not merely looked up. The destination of a copy is not sampled
|
||||
// by the draw program, so the per-draw unit list - which is the sampler-view window
|
||||
// now - never brings it across; before P5e the frontend walk over every slot of every
|
||||
// touched unit happened to sync it as a side effect. The named narrowing (P5e-5) says
|
||||
// the union that still covers every texture includes "the waited texture ops", and
|
||||
// this is one of them: it syncs its own endpoint by handle.
|
||||
auto& backendTexture = TextureImpl::SyncTextureToBackendByHandle(dstHandle);
|
||||
if (!backendTexture || dstRecord == nullptr) {
|
||||
MGLOG_E_ONCE("CopyTexImage2D: the verb's destination texture {%u, %u} has no twin "
|
||||
"or no applier record on this side",
|
||||
dstHandle.Slot, dstHandle.Gen);
|
||||
return;
|
||||
}
|
||||
dstBackendTexture = backendTextureSlot->get();
|
||||
dstBackendTexture = backendTexture.get();
|
||||
mgInternalFormat = static_cast<TextureInternalFormat>(dstRecord->Desc.InternalFormat);
|
||||
} else
|
||||
#endif
|
||||
@@ -9890,14 +9896,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// client's unit binding slot or the client allocator (T2/T4).
|
||||
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
||||
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
||||
auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.FindByHandle(dstHandle);
|
||||
if (backendTextureSlot == nullptr || *backendTextureSlot == nullptr) {
|
||||
// P5e (tx2): synced by handle - see CopyTexImage2D's note. A copy destination is not
|
||||
// in the sampler-view window, so nothing else on this path would build its twin.
|
||||
auto& backendTexture = TextureImpl::SyncTextureToBackendByHandle(dstHandle);
|
||||
if (!backendTexture) {
|
||||
MGLOG_E_ONCE("CopyTexSubImage2D: the verb's destination texture {%u, %u} has no "
|
||||
"twin on this side",
|
||||
dstHandle.Slot, dstHandle.Gen);
|
||||
return;
|
||||
}
|
||||
dstBackendTexture = backendTextureSlot->get();
|
||||
dstBackendTexture = backendTexture.get();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -65,6 +65,21 @@ namespace MobileGL {
|
||||
surface);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
// P5e (tx2), ruling 12's shape (ID-90): THE NEW READ-ONLY ROWS ARE KEYED ON THE
|
||||
// BACKEND KIND, and that is not a softening - it is the same line §6 draws for
|
||||
// every other P5e guard. MAGMA KEEPS THE LOCKSTEP: a DirectVulkan server's
|
||||
// records are all barriered and its blit path still asks a frontend texture
|
||||
// whether it IsComplete() (VulkanRenderer's ResolveColorBlitBinding), which is a
|
||||
// P7 debt and legal under P5C's rules for a client parked in its own wait. What
|
||||
// P5e retires is ESPRYT's per-draw shape reads, so the new rows abort on a
|
||||
// DirectGLES server and are silent on a DirectVulkan one. The MUTATOR rows above
|
||||
// stay unconditional: no backend may write a frontend texture's storage from the
|
||||
// apply thread, and none does.
|
||||
void RefuseLegacyTextureShapeReadFromApplyThread(const char* surface) {
|
||||
if (MG_Config::ActiveBackendType != BackendType::DirectGLES) return;
|
||||
RefuseLegacyTextureArmFromApplyThread(surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Overlapping OR abutting ([lo, hi) intervals meeting edge-to-edge) in
|
||||
@@ -113,7 +128,7 @@ namespace MobileGL {
|
||||
|
||||
SizeT MipmapStorage::GetLevelCount() const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapLevelCount");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapLevelCount");
|
||||
#endif
|
||||
return m_data.size();
|
||||
}
|
||||
@@ -190,7 +205,7 @@ namespace MobileGL {
|
||||
|
||||
GLenum MipmapStorage::GetCompressedFormat(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetCompressedFormat");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetCompressedFormat");
|
||||
#endif
|
||||
if (level >= m_compressedFormats.size()) return GL_NONE;
|
||||
return m_compressedFormats[level];
|
||||
@@ -198,7 +213,7 @@ namespace MobileGL {
|
||||
|
||||
SizeT MipmapStorage::GetCompressedByteSize(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetCompressedByteSize");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetCompressedByteSize");
|
||||
#endif
|
||||
if (level >= m_compressedData.size()) return 0;
|
||||
return m_compressedData[level].size();
|
||||
@@ -206,7 +221,7 @@ namespace MobileGL {
|
||||
|
||||
const void* MipmapStorage::MapCompressedData(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("MapCompressedMipmapData");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("MapCompressedMipmapData");
|
||||
#endif
|
||||
if (level >= m_compressedData.size()) return nullptr;
|
||||
return m_compressedData[level].data();
|
||||
@@ -219,7 +234,7 @@ namespace MobileGL {
|
||||
|
||||
GLenum MipmapStorage::GetRequestedCompressedFormat(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetRequestedCompressedFormat");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetRequestedCompressedFormat");
|
||||
#endif
|
||||
if (level >= m_requestedCompressedFormats.size()) return GL_NONE;
|
||||
return m_requestedCompressedFormats[level];
|
||||
@@ -270,7 +285,7 @@ namespace MobileGL {
|
||||
|
||||
IntVec3 MipmapStorage::GetTexelSize(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapTexelSize");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapTexelSize");
|
||||
#endif
|
||||
auto& targetTexelSizes = m_texelSizes;
|
||||
if (level >= targetTexelSizes.size()) return {0, 0, 0};
|
||||
@@ -279,7 +294,7 @@ namespace MobileGL {
|
||||
|
||||
SizeT MipmapStorage::GetByteSize(Uint level) const {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapByteSize");
|
||||
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapByteSize");
|
||||
#endif
|
||||
if (level >= m_data.size()) return 0;
|
||||
return m_data[level].size();
|
||||
|
||||
Reference in New Issue
Block a user