diff --git a/MobileGL/MG_Backend/BackendObject.h b/MobileGL/MG_Backend/BackendObject.h index 70cd3c78..552251d3 100644 --- a/MobileGL/MG_Backend/BackendObject.h +++ b/MobileGL/MG_Backend/BackendObject.h @@ -9,6 +9,9 @@ #pragma once #include #include "MG_State/GLState/TextureState/TextureEnum.h" +#if MOBILEGL_BUILD_DISAGGREGATED +#include +#endif namespace MobileGL { namespace MG_State::GLState { @@ -33,6 +36,9 @@ namespace MobileGL { struct CopyImageEndpoint { SharedPtr Texture; SharedPtr Renderbuffer; +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Pipe::MGPipeHandle TextureHandle = MG_Pipe::kMGPipeNullHandle; +#endif Bool IsRenderbuffer() const { return Renderbuffer != nullptr; } Bool Exists() const { return Texture != nullptr || Renderbuffer != nullptr; } diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index f1629990..1c3a26c6 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -64,6 +64,14 @@ #endif namespace MobileGL::MG_Backend::DirectGLES { +#if MOBILEGL_BUILD_DISAGGREGATED + // read_pixels writes the server reply scratch; client-side scatter owns any PBO. + static const SharedPtr& SplitReadbackPackBuffer() { + static const SharedPtr none; + return none; + } +#endif + MG_External::EGLFunctionsTable g_EGLFuncs; MG_External::GLESFunctionsTable g_GLESFuncs; MG_External::GLESCapabilities g_GLESCapabilities; @@ -10757,7 +10765,9 @@ namespace MobileGL::MG_Backend::DirectGLES { ZoneScopedNC(__func__, TRACY_ZONECOLOR_BACKEND); #endif auto unit = MGB_CTX->GetActiveTextureUnit(); +#if !MOBILEGL_BUILD_DISAGGREGATED auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); +#endif auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); if (!TextureImpl::IsSupportedTextureTarget(textureTarget)) { @@ -10789,6 +10799,9 @@ namespace MobileGL::MG_Backend::DirectGLES { } #endif +#if MOBILEGL_BUILD_DISAGGREGATED + auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); +#endif const auto& bindingSlot = textureUnit.GetBindingSlot(textureTarget); { const auto& textureObject = bindingSlot.GetBoundObject(); @@ -12297,8 +12310,15 @@ namespace MobileGL::MG_Backend::DirectGLES { // An endpoint that named nothing is the frontend validator's INVALID_VALUE and never // reaches here - but the assertion that says so is compiled out of a release build, and // SyncTextureObjectToBackend would register a null state object. +#if MOBILEGL_BUILD_DISAGGREGATED + if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { + out.texture = TextureImpl::SyncTextureToBackendByHandle(endpoint.TextureHandle); + } else +#endif + { if (!endpoint.Texture) return false; out.texture = TextureImpl::SyncTextureObjectToBackend(endpoint.Texture); + } if (!out.texture) return false; const TextureTarget stateTarget = MG_Util::ConvertGLEnumToTextureTarget(appTarget); out.target = TextureImpl::ConvertTextureTargetToBackendGLEnum(stateTarget); @@ -12316,6 +12336,13 @@ 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); + return record ? static_cast(record->Desc.InternalFormat) + : TextureInternalFormat::Unknown; + } +#endif if (endpoint.IsRenderbuffer()) return endpoint.Renderbuffer->GetInternalFormat(); return endpoint.Texture ? endpoint.Texture->GetFormat() : TextureInternalFormat::Unknown; } @@ -12596,6 +12623,17 @@ namespace MobileGL::MG_Backend::DirectGLES { // effect by the block's next use. void ShaderStorageBlockBinding(GLuint program, const GLchar* storageBlockName, GLuint storageBlockBinding) { if (!storageBlockName) return; +#if MOBILEGL_BUILD_DISAGGREGATED + if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { + const auto handle = MG_Pipe::MGPipeApplier().VerbStorageBlockProgram; + auto* slot = PrgramImpl::g_backendProgramObjects.FindByHandle(handle); + if (slot && *slot && (*slot)->GetBackendProgramId()) { + PrgramImpl::ApplyShaderStorageBlockBinding((*slot)->GetBackendProgramId(), + storageBlockName, storageBlockBinding); + } + return; + } +#endif if (!MGB_CTX->ValidateProgramName(program)) return; auto& programObject = MGB_CTX->GetProgramObject(program); if (!programObject) return; @@ -12806,6 +12844,11 @@ namespace MobileGL::MG_Backend::DirectGLES { const SizeT rowBytes = static_cast(width) * dstPixelBytes; const SizeT packedSize = dstOffset + static_cast(height - 1) * dstRowStride + rowBytes; const auto& pixelPackBufferObject = + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); const SizeT pboOffset = reinterpret_cast(pixels); if (pixelPackBufferObject && pboOffset + packedSize > pixelPackBufferObject->GetSize()) { @@ -13788,6 +13831,11 @@ namespace MobileGL::MG_Backend::DirectGLES { return true; } const auto& pixelPackBufferObject = + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); if (!pixelPackBufferObject && pixels == nullptr) { return true; @@ -14025,6 +14073,11 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Pipe::MGPipeUnmigratedEmulation("get-tex-image-shadow"); #endif const auto& pixelPackBufferObject = + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); if (!pixelPackBufferObject && pixels == nullptr) { return true; @@ -14335,6 +14388,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // (the driver-level binding used to stay on the user PBO after this call, // capturing subsequent client-memory readbacks into it). auto& pixelPackBufferObject = + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); Bool usePBO = false; GLuint packBufferId = 0; @@ -14766,6 +14824,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // Handle PBO. The pack binding is scoped: it returns to the resting 0 state // on every exit path, so a later readback can never land in a stale PBO. auto& pixelPackBufferObject = + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); Bool usePBO = false; GLuint packBufferId = 0; diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 63c4a9af..f51af4fc 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -10287,6 +10287,12 @@ namespace MobileGL::MG_Backend::DirectGLES { // (the three-channel colour-renderable widening). GL answers such a read with 1.0, but // the storage holds whatever the draw wrote there, so the readback has to overwrite it. Bool IsAlphaWidenedFallbackReadAttachment() { +#if MOBILEGL_BUILD_DISAGGREGATED + if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { + const auto* record = MG_Pipe::MGPipeApplier().ReadFramebuffer(); + return record && IsAlphaWidenedColorSurface(record->ReadSurface); + } +#endif const auto* attachmentObject = GetReadColorAttachment(); if (attachmentObject == nullptr) { return false; @@ -10295,6 +10301,13 @@ namespace MobileGL::MG_Backend::DirectGLES { } Bool IsFixedPointFallbackReadAttachment() { +#if MOBILEGL_BUILD_DISAGGREGATED + if (MG_Config::Transport != MG_Config::TransportMode::Monolith) { + const auto* record = MG_Pipe::MGPipeApplier().ReadFramebuffer(); + return record && record->ReadSurface.Kind != MG_Pipe::kMGPipeSurfaceKindNone && + IsSnormFormat(static_cast(record->ReadSurface.InternalFormat)); + } +#endif const auto& readFBO = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (!readFBO) { diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.cpp b/MobileGL/MG_Backend/DirectGLES/Utils.cpp index 5ad96c6c..e2106c7d 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Utils.cpp @@ -37,6 +37,14 @@ #include namespace MobileGL::MG_Backend::DirectGLES { +#if MOBILEGL_BUILD_DISAGGREGATED + // read_pixels writes the server reply scratch; client-side scatter owns any PBO. + static const SharedPtr& SplitReadbackPackBuffer() { + static const SharedPtr none; + return none; + } +#endif + #if MOBILEGL_BUILD_DISAGGREGATED const FormatCapabilityCache* ActiveBackendFormatCaps() { // Under a live split session the SERVER's private backend is what owns the context on the @@ -2350,7 +2358,12 @@ namespace MobileGL::MG_Backend::DirectGLES { static Bool StoreClientRows(SizeT dstPixelBytes, SizeT swapGroupSize, GLsizei width, GLsizei sliceHeight, GLsizei sliceCount, void* pixels, Bool applyPackImageParams, FillRow&& fillRow) { const auto& pixelPackBufferObject = - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + +#if MOBILEGL_BUILD_DISAGGREGATED + MG_Config::Transport != MG_Config::TransportMode::Monolith + ? SplitReadbackPackBuffer() : +#endif + MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); // Destination layout is computed from the client-side PACK parameters; only the actual pixel // rows are written so skip regions of the destination stay untouched. diff --git a/MobileGL/MG_Pipe/PipeApply.h b/MobileGL/MG_Pipe/PipeApply.h index 7d41d405..7eebcd72 100644 --- a/MobileGL/MG_Pipe/PipeApply.h +++ b/MobileGL/MG_Pipe/PipeApply.h @@ -846,6 +846,7 @@ namespace MobileGL::MG_Pipe { Bool VerbBlitNamedConsumed = false; // copy_framebuffer_to_texture's destination texture (MGPCopyFromFramebuffer::Dst). MGPipeHandle VerbCopyTexDst = kMGPipeNullHandle; + MGPipeHandle VerbStorageBlockProgram = kMGPipeNullHandle; // generate_mipmap's texture (MGPMipPlan::Res). MGPipeHandle VerbMipRes = kMGPipeNullHandle; // The current indirect draw's command buffer and (for the *Count forms) parameter @@ -870,6 +871,7 @@ namespace MobileGL::MG_Pipe { VerbBlitDrawFbo = kMGPipeNullHandle; VerbBlitNamedConsumed = false; VerbCopyTexDst = kMGPipeNullHandle; + VerbStorageBlockProgram = kMGPipeNullHandle; VerbMipRes = kMGPipeNullHandle; VerbIndirectBuffer = kMGPipeNullHandle; VerbIndirectParameterBuffer = kMGPipeNullHandle; diff --git a/MobileGL/MG_Remote/Server/PipeApplier.cpp b/MobileGL/MG_Remote/Server/PipeApplier.cpp index 3c9f557f..6e63780b 100644 --- a/MobileGL/MG_Remote/Server/PipeApplier.cpp +++ b/MobileGL/MG_Remote/Server/PipeApplier.cpp @@ -855,9 +855,9 @@ namespace MobileGL::MG_Remote::Server { // retires them by making the backend take the handles that travel beside the names. MG_Backend::CopyImageEndpoint src{}; MG_Backend::CopyImageEndpoint dst{}; - src.Texture = MG_Pipe::gPipeInputs.GetTextureObject(static_cast(copy.SrcGlName)); - dst.Texture = MG_Pipe::gPipeInputs.GetTextureObject(static_cast(copy.DstGlName)); - if (!src.Exists() || !dst.Exists()) { + src.TextureHandle = copy.Src; + 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 // validator is what keeps it unreachable and what reports the INVALID_VALUE the @@ -921,6 +921,8 @@ namespace MobileGL::MG_Remote::Server { // Both backends resolve the PROGRAM through the barrier-pulled GetProgramObject(GlName) // / TryGetDirectVulkanProgram - `rsp` again, retired by P9. ShaderCso travels beside the // name for the phase that dispatches on it. + MG_Pipe::MGPipeApplier().ClearVerbHandles(); + MG_Pipe::MGPipeApplier().VerbStorageBlockProgram = binding.ShaderCso; table->GL.ShaderStorageBlockBinding(static_cast(binding.GlName), name, static_cast(binding.Binding)); ++m_storageBlockBindings;