mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-15 22:13: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) {
|
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
||||||
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
||||||
const auto* dstRecord = PipeTextureRecordForHandle(dstHandle);
|
const auto* dstRecord = PipeTextureRecordForHandle(dstHandle);
|
||||||
auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.FindByHandle(dstHandle);
|
// P5e (tx2): SYNCED, not merely looked up. The destination of a copy is not sampled
|
||||||
if (backendTextureSlot == nullptr || *backendTextureSlot == nullptr || dstRecord == nullptr) {
|
// 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 "
|
MGLOG_E_ONCE("CopyTexImage2D: the verb's destination texture {%u, %u} has no twin "
|
||||||
"or no applier record on this side",
|
"or no applier record on this side",
|
||||||
dstHandle.Slot, dstHandle.Gen);
|
dstHandle.Slot, dstHandle.Gen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dstBackendTexture = backendTextureSlot->get();
|
dstBackendTexture = backendTexture.get();
|
||||||
mgInternalFormat = static_cast<TextureInternalFormat>(dstRecord->Desc.InternalFormat);
|
mgInternalFormat = static_cast<TextureInternalFormat>(dstRecord->Desc.InternalFormat);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
@@ -9890,14 +9896,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// client's unit binding slot or the client allocator (T2/T4).
|
// client's unit binding slot or the client allocator (T2/T4).
|
||||||
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
if (MG_Config::Transport != MG_Config::TransportMode::Monolith) {
|
||||||
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
const MG_Pipe::MGPipeHandle dstHandle = MG_Pipe::MGPipeApplier().VerbCopyTexDst;
|
||||||
auto* backendTextureSlot = TextureImpl::g_backendTextureObjects.FindByHandle(dstHandle);
|
// P5e (tx2): synced by handle - see CopyTexImage2D's note. A copy destination is not
|
||||||
if (backendTextureSlot == nullptr || *backendTextureSlot == nullptr) {
|
// 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 "
|
MGLOG_E_ONCE("CopyTexSubImage2D: the verb's destination texture {%u, %u} has no "
|
||||||
"twin on this side",
|
"twin on this side",
|
||||||
dstHandle.Slot, dstHandle.Gen);
|
dstHandle.Slot, dstHandle.Gen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dstBackendTexture = backendTextureSlot->get();
|
dstBackendTexture = backendTexture.get();
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,6 +65,21 @@ namespace MobileGL {
|
|||||||
surface);
|
surface);
|
||||||
std::abort();
|
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
|
#endif
|
||||||
|
|
||||||
// Overlapping OR abutting ([lo, hi) intervals meeting edge-to-edge) in
|
// Overlapping OR abutting ([lo, hi) intervals meeting edge-to-edge) in
|
||||||
@@ -113,7 +128,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
SizeT MipmapStorage::GetLevelCount() const {
|
SizeT MipmapStorage::GetLevelCount() const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapLevelCount");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapLevelCount");
|
||||||
#endif
|
#endif
|
||||||
return m_data.size();
|
return m_data.size();
|
||||||
}
|
}
|
||||||
@@ -190,7 +205,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
GLenum MipmapStorage::GetCompressedFormat(Uint level) const {
|
GLenum MipmapStorage::GetCompressedFormat(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetCompressedFormat");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetCompressedFormat");
|
||||||
#endif
|
#endif
|
||||||
if (level >= m_compressedFormats.size()) return GL_NONE;
|
if (level >= m_compressedFormats.size()) return GL_NONE;
|
||||||
return m_compressedFormats[level];
|
return m_compressedFormats[level];
|
||||||
@@ -198,7 +213,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
SizeT MipmapStorage::GetCompressedByteSize(Uint level) const {
|
SizeT MipmapStorage::GetCompressedByteSize(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetCompressedByteSize");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetCompressedByteSize");
|
||||||
#endif
|
#endif
|
||||||
if (level >= m_compressedData.size()) return 0;
|
if (level >= m_compressedData.size()) return 0;
|
||||||
return m_compressedData[level].size();
|
return m_compressedData[level].size();
|
||||||
@@ -206,7 +221,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
const void* MipmapStorage::MapCompressedData(Uint level) const {
|
const void* MipmapStorage::MapCompressedData(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("MapCompressedMipmapData");
|
RefuseLegacyTextureShapeReadFromApplyThread("MapCompressedMipmapData");
|
||||||
#endif
|
#endif
|
||||||
if (level >= m_compressedData.size()) return nullptr;
|
if (level >= m_compressedData.size()) return nullptr;
|
||||||
return m_compressedData[level].data();
|
return m_compressedData[level].data();
|
||||||
@@ -219,7 +234,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
GLenum MipmapStorage::GetRequestedCompressedFormat(Uint level) const {
|
GLenum MipmapStorage::GetRequestedCompressedFormat(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetRequestedCompressedFormat");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetRequestedCompressedFormat");
|
||||||
#endif
|
#endif
|
||||||
if (level >= m_requestedCompressedFormats.size()) return GL_NONE;
|
if (level >= m_requestedCompressedFormats.size()) return GL_NONE;
|
||||||
return m_requestedCompressedFormats[level];
|
return m_requestedCompressedFormats[level];
|
||||||
@@ -270,7 +285,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
IntVec3 MipmapStorage::GetTexelSize(Uint level) const {
|
IntVec3 MipmapStorage::GetTexelSize(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapTexelSize");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapTexelSize");
|
||||||
#endif
|
#endif
|
||||||
auto& targetTexelSizes = m_texelSizes;
|
auto& targetTexelSizes = m_texelSizes;
|
||||||
if (level >= targetTexelSizes.size()) return {0, 0, 0};
|
if (level >= targetTexelSizes.size()) return {0, 0, 0};
|
||||||
@@ -279,7 +294,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
SizeT MipmapStorage::GetByteSize(Uint level) const {
|
SizeT MipmapStorage::GetByteSize(Uint level) const {
|
||||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||||
RefuseLegacyTextureArmFromApplyThread("GetMipmapByteSize");
|
RefuseLegacyTextureShapeReadFromApplyThread("GetMipmapByteSize");
|
||||||
#endif
|
#endif
|
||||||
if (level >= m_data.size()) return 0;
|
if (level >= m_data.size()) return 0;
|
||||||
return m_data[level].size();
|
return m_data[level].size();
|
||||||
|
|||||||
Reference in New Issue
Block a user