mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
[MG_Backend] (Disaggregated): create GLES texture views from server CSO windows
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user