[MG_Backend] (Disaggregated): create GLES texture views from server CSO windows

This commit is contained in:
2026-09-20 11:32:51 -04:00
parent beba025618
commit 57e0f6bee5
2 changed files with 42 additions and 22 deletions
+39 -15
View File
@@ -7293,22 +7293,46 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_syncedResourceSerial = record.Serial;
return;
}
// TRAILING (tx2 report, "left barriered"): the glTextureView CALL needs the view
// window and MGPResourceDesc has no carrier for it. The frontend object is taken when
// the monolith-glue note still reaches one - which is every case a single-process
// split has - and the refusal is NAMED rather than silent for the case that does not.
if (stateTextureObject) {
SyncTextureViewToBackend(stateTextureObject);
m_syncedResourceSerial = record.Serial;
return;
// The view window is a sampler-view CSO, created even when this
// texture is only image-bound or attached to an FBO. It is not part
// of the resource descriptor, and needs no frontend fallback.
(void)stateTextureObject;
const auto& applier = MG_Pipe::MGPipeApplier();
const auto handle = record.ViewCso;
if (MG_Pipe::MGPipeHandleIsNull(handle) || handle.Slot >= applier.SamplerViewCsos.size()) {
MGLOG_F("MGPipe: Fatal{ProtocolCorruption, \"texture-view-cso\"} {%u,%u}", res.Slot, res.Gen);
std::abort();
}
MGLOG_E_ONCE("MGPipe: texture view {%u, %u} (GL %u) has to be (re-)created as a view of "
"{%u, %u}, and MGPResourceDesc carries no view window - minLevel, "
"numLevels, minLayer, numLayers have no wire field - so the by-handle arm "
"cannot issue glTextureView. P5e leaves view CREATION on the frontend arm; "
"this name will sample empty until it gets one.",
res.Slot, res.Gen, record.Desc.GlNameForDiag, record.Desc.ViewOf.Slot,
record.Desc.ViewOf.Gen);
const auto& cso = applier.SamplerViewCsos[handle.Slot];
const auto& view = cso.View;
if (!cso.Live || cso.Gen != handle.Gen || view.Texture != res || !view.NumLevels || !view.NumLayers) {
MGLOG_F("MGPipe: Fatal{ProtocolCorruption, \"texture-view-window\"} {%u,%u}", res.Slot, res.Gen);
std::abort();
}
const auto viewTarget = BufferImpl::StagedTextureTargetForPipeTarget(record.Desc.Target);
const GLenum nativeTarget = ConvertTextureTargetToBackendGLEnum(viewTarget);
GLenum internalFormat = 0, transferFormat = 0, transferType = 0;
GenerateTextureFormatInfo(static_cast<TextureInternalFormat>(view.InternalFormat),
&internalFormat, &transferFormat, &transferType, viewTarget);
// A name already bound or used as a view cannot be redefined by
// glTextureView. This also invalidates native binding/FBO caches.
RecreateBackendTexture();
DebugImpl::ErrorLopper::Clear();
ResolveTextureViewEntryPoint()(m_backendTextureId, nativeTarget, storageBackendTextureId,
internalFormat, view.MinLevel, view.NumLevels, view.MinLayer, view.NumLayers);
const GLenum error = g_GLESFuncs.glGetError();
if (error != GL_NO_ERROR) {
MGLOG_F("MGPipe: Fatal{ResourceUnavailable, \"texture-view-native\"} {%u,%u} error=0x%x",
res.Slot, res.Gen, error);
std::abort();
}
m_viewSourceBackendTextureId = storageBackendTextureId;
m_isInitialized = true;
m_backendStorageImmutable = true;
m_prevTextureInfo = {static_cast<TextureInternalFormat>(record.Desc.InternalFormat),
record.Desc.Width, record.Desc.Height, record.Desc.Depth, view.NumLevels, 0,
record.Desc.Samples, record.Desc.FixedSampleLocations != 0};
m_syncedResourceSerial = record.Serial;
}
#endif
+3 -7
View File
@@ -1827,13 +1827,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
// stamp the record's Serial. That is the per-draw cost of every already-synced view
// and it reads nothing from the client.
//
// The CREATION of the view is the gap and it is named rather than papered over: the
// glTextureView call needs (minLevel, numLevels, minLayer, numLayers) and MGPResourceDesc
// carries none of the four - `ViewOf` is the only view field on the wire. So a view whose
// ES name has not been made a view YET, or whose storage was re-minted underneath it,
// still needs the frontend object and takes it when one is reachable; with no object it
// declines LOUDLY and the view samples its own (empty) name. Listed as trailing in the
// tx2 report with the wire fields it needs.
// Creation/recreation resolves record.ViewCso's complete view window
// and issues the native view call against that server-owned storage.
// No frontend texture is used to recover the level/layer range.
void SyncTextureViewToBackendByRecord(
MG_Pipe::MGPipeHandle res, const MG_Pipe::MGPipeResourceRecord& record,
const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);