diff --git a/MobileGL/MG_Backend/BackendObject.h b/MobileGL/MG_Backend/BackendObject.h index c759e038..2d25fe68 100644 --- a/MobileGL/MG_Backend/BackendObject.h +++ b/MobileGL/MG_Backend/BackendObject.h @@ -38,12 +38,19 @@ namespace MobileGL { SharedPtr Renderbuffer; #if MOBILEGL_BUILD_DISAGGREGATED MG_Pipe::MGPipeHandle TextureHandle = MG_Pipe::kMGPipeNullHandle; + MG_Pipe::MGPipeHandle RenderbufferHandle = MG_Pipe::kMGPipeNullHandle; #endif - Bool IsRenderbuffer() const { return Renderbuffer != nullptr; } + Bool IsRenderbuffer() const { +#if MOBILEGL_BUILD_DISAGGREGATED + if (!MG_Pipe::MGPipeHandleIsNull(RenderbufferHandle)) return true; +#endif + return Renderbuffer != nullptr; + } Bool Exists() const { #if MOBILEGL_BUILD_DISAGGREGATED if (!MG_Pipe::MGPipeHandleIsNull(TextureHandle)) return true; + if (!MG_Pipe::MGPipeHandleIsNull(RenderbufferHandle)) return true; #endif return Texture != nullptr || Renderbuffer != nullptr; } diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 8f234d76..9fdf03ee 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -12508,6 +12508,16 @@ namespace MobileGL::MG_Backend::DirectGLES { static Bool MakeGLESCopyImageEndpoint(const CopyImageEndpoint& endpoint, GLenum appTarget, GLint x, GLint y, GLint z, GLESCopyImageEndpoint& out) { if (endpoint.IsRenderbuffer()) { +#if MOBILEGL_BUILD_DISAGGREGATED + if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { + if (!PipeRenderbufferRecordForHandle(endpoint.RenderbufferHandle)) return false; + auto* slot = RenderbufferImpl::g_backendRenderbufferObjects.GetOrCreateByHandle(endpoint.RenderbufferHandle); + if (!slot) return false; + if (!*slot) *slot = MakeShared(); + out.renderbuffer = *slot; + out.renderbuffer->SyncToBackendByHandle(endpoint.RenderbufferHandle); + } else +#endif out.renderbuffer = SyncRenderbufferObjectToBackend(endpoint.Renderbuffer); if (!out.renderbuffer) return false; out.target = GL_RENDERBUFFER; @@ -12556,7 +12566,9 @@ namespace MobileGL::MG_Backend::DirectGLES { static TextureInternalFormat GetCopyImageEndpointFormat(const CopyImageEndpoint& endpoint) { #if MOBILEGL_BUILD_DISAGGREGATED if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { - const auto* record = PipeTextureRecordForHandle(endpoint.TextureHandle); + const auto* record = endpoint.IsRenderbuffer() + ? PipeRenderbufferRecordForHandle(endpoint.RenderbufferHandle) + : PipeTextureRecordForHandle(endpoint.TextureHandle); return record ? static_cast(record->Desc.InternalFormat) : TextureInternalFormat::Unknown; } diff --git a/MobileGL/MG_Remote/Client/EmitTables.cpp b/MobileGL/MG_Remote/Client/EmitTables.cpp index 4cd7ca40..156b92e5 100644 --- a/MobileGL/MG_Remote/Client/EmitTables.cpp +++ b/MobileGL/MG_Remote/Client/EmitTables.cpp @@ -1274,19 +1274,21 @@ namespace MobileGL::MG_Remote::Client { // way to rebuild one from a name, and none was measured. P7 is where the backend // takes handles and this arm becomes ordinary. The sink refuses the same shape by // the same name if a record ever reaches it (defence on both sides of one wire). - if (src.IsRenderbuffer() || dst.IsRenderbuffer()) { - UnmigratedVerbFatal("CopyImageSubData+RENDERBUFFER"); - } - MG_Pipe::MGPCopyRegion record{}; - record.Src = PublishedTextureHandle(src.Texture); - record.Dst = PublishedTextureHandle(dst.Texture); + const auto handle = [](const MG_Backend::CopyImageEndpoint& endpoint) { + return endpoint.IsRenderbuffer() + ? MG_Pipe::MGPipeSlots().FindByLifetimeId(MG_Pipe::MGPipeKind::Renderbuffer, + endpoint.Renderbuffer->GetLifetimeId()) + : PublishedTextureHandle(endpoint.Texture); + }; + record.Src = handle(src); + record.Dst = handle(dst); // The GL names beside the handles: the key MGB_CTX->GetTextureObject(name) takes on // the far side (a BARRIER-PULLED sticky forward, counted in `rsp`, retired by P7). record.SrcGlName = - src.Texture ? static_cast(src.Texture->GetExternalIndex()) : 0u; + src.IsRenderbuffer() ? src.Renderbuffer->GetExternalIndex() : src.Texture->GetExternalIndex(); record.DstGlName = - dst.Texture ? static_cast(dst.Texture->GetExternalIndex()) : 0u; + dst.IsRenderbuffer() ? dst.Renderbuffer->GetExternalIndex() : dst.Texture->GetExternalIndex(); // The GL targets verbatim, in a Uint16 - every GL texture target fits one. NOT // MGPipeResourceTarget: the sink only ever forwards these to a slot that takes GL // enums, and the tree has no resource-target -> GL-enum inverse to spend on them. diff --git a/MobileGL/MG_Remote/Server/PipeApplier.cpp b/MobileGL/MG_Remote/Server/PipeApplier.cpp index 2e297e56..13c7d133 100644 --- a/MobileGL/MG_Remote/Server/PipeApplier.cpp +++ b/MobileGL/MG_Remote/Server/PipeApplier.cpp @@ -893,16 +893,15 @@ namespace MobileGL::MG_Remote::Server { // record that reached here anyway: no sticky forward hands out a RenderbufferObject, so // there is no honest way to build the endpoint, and guessing an empty one would copy // nothing and say it copied. - if (copy.SrcTarget == GL_RENDERBUFFER || copy.DstTarget == GL_RENDERBUFFER) { - ServerUnmigratedVerbFatal("CopyImageSubData+RENDERBUFFER"); - } // P5f fe: both texture identities already travel in the record. Pass those handles // to the backend's server-owned texture table; GL names are diagnostic data only. MG_Backend::CopyImageEndpoint src{}; MG_Backend::CopyImageEndpoint dst{}; - src.TextureHandle = copy.Src; - dst.TextureHandle = copy.Dst; + if (copy.SrcTarget == GL_RENDERBUFFER) src.RenderbufferHandle = copy.Src; + else src.TextureHandle = copy.Src; + if (copy.DstTarget == GL_RENDERBUFFER) dst.RenderbufferHandle = copy.Dst; + else dst.TextureHandle = copy.Dst; if (MG_Pipe::MGPipeHandleIsNull(copy.Src) || MG_Pipe::MGPipeHandleIsNull(copy.Dst)) { // The monolith's own answer to this, in its own words (DirectGLES.cpp:9067 // "source or destination image failed to sync; declining the copy"): the frontend