From a0bff7cee1112da1992452a7e7ee2ca6b95adbbc Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 6 Oct 2026 03:22:35 -0400 Subject: [PATCH] [Refactor] (P13 W3b): backends read MG_Pipe::gPipeInputs directly, MGB_CTX and its switch header are gone --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 220 +++++++------- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 50 ++-- MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp | 16 +- MobileGL/MG_Backend/DirectGLES/Utils.cpp | 6 +- .../BackendObject_DirectVulkan.cpp | 10 +- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 100 +++---- .../DirectVulkan/Renderer/UniformManager.cpp | 48 ++-- .../DirectVulkan/Renderer/VkClearManager.cpp | 4 +- .../Renderer/VkRenderPassManager.cpp | 8 +- .../Renderer/VkTextureManager.cpp | 6 +- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 270 +++++++++--------- .../DirectVulkan/Renderer/WireColorBlit.inc | 2 +- .../DirectVulkan/Renderer/WireDraw.inc | 10 +- .../DirectVulkan/Renderer/WireFramebuffer.inc | 16 +- MobileGL/MG_Backend/MGPipe/PipeInputs.h | 24 +- MobileGL/MG_Impl/Pipe/CompositeResolver.h | 2 +- .../ObjectSubsystemControlScenario.cpp | 4 +- MobileGL/MG_Pipe/FieldOwnership.def | 4 +- MobileGL/MG_Pipe/MGPipeTypes.h | 2 +- .../MG_Pipe/generated/PipeFieldOwnership.inc | 2 +- MobileGL/MG_Remote/Client/ClientSession.cpp | 4 +- MobileGL/MG_Remote/Client/EmitTables.cpp | 2 +- MobileGL/MG_Remote/Server/PipeApplier.cpp | 2 +- MobileGL/MG_Remote/Server/SessionRuntime.h | 4 +- MobileGL/MG_Test/SanityTest.cpp | 2 +- MobileGL/MG_Test/ScopedPipeVerb.h | 4 +- scripts/gen_pipe.py | 8 +- 27 files changed, 415 insertions(+), 415 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 446fd954..dead37f8 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include // P3a: the applier's vertex-input records the re-keyed draw-buffer memo is validated against. #include // P5c ev: the surface-changed event's producer callback, installed by the server session. @@ -115,7 +115,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // addresses again - the cached pointers cannot go stale. Invalidation is // exactly the pointer compare below. using FbBindingSlot = - std::remove_reference_tGetFramebufferBindingSlot(FramebufferTarget::Draw))>; + std::remove_reference_t; // P2 step e4. On the {slot, gen} arm this is an ORDINARY read of pushed state and the cache // above is not consulted, which closes the P1 accessor bypass: the cached raw pointer ran // the checked accessor once per context change and then handed out the pointee forever, so @@ -128,14 +128,14 @@ namespace MobileGL::MG_Backend::DirectGLES { // slice, so that MOBILEGL_PIPE_PUSH=0 keeps being the faithful all-subsystems-pull control // ConfigLoader.cpp documents - "reproduces P1's behaviour exactly" has to include this // path, or the integrator's A/B measures e4 on both arms and attributes it to neither. In - // the pull build MGB_CTX is the live GLContext, there is no poison to bypass and the + // the pull build gPipeInputs is the live GLContext, there is no poison to bypass and the // frontend getter still linear-scans, so the cache is exactly the code it was. static inline FbBindingSlot& GetFramebufferBindingSlotChecked(FramebufferTarget target) { if (EsprytSlotTablesEnabled()) { - return MGB_CTX->GetFramebufferBindingSlot(target); + return MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(target); } // No legacy arm compiled: EsprytSlotTablesEnabled() is unconditionally true above. - return MGB_CTX->GetFramebufferBindingSlot(target); + return MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(target); } // A4, TAKEN AT THE VERIFICATION ROUND, AND THE FOUR TEMPORARY LATCHES ARE GONE WITH IT. @@ -401,7 +401,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return nullptr; } #endif - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { drawBuffer->SyncPersistentMappedRange(); const SizeT commandOffset = reinterpret_cast(indirect); @@ -698,7 +698,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif // Only sync up to the high-water mark of app-touched points; the fixed array is 84 // deep but apps bind a handful, so the never-touched tail is already at GL default 0. - auto bindingPointCnt = MGB_CTX->GetTouchedBufferBindingPointCount(target); + auto bindingPointCnt = MG_Pipe::gPipeInputs.GetTouchedBufferBindingPointCount(target); // ...and never past what the ES driver itself can hold. MobileGL advertises the GL 4.5 // minimum of 84 uniform binding points while the ES 3.2 minimum is 72, so a frontend // index in that gap would reach glBindBufferBase as GL_INVALID_VALUE. Nothing is lost @@ -711,7 +711,7 @@ namespace MobileGL::MG_Backend::DirectGLES { static_cast(g_GLESCapabilities.MaxUniformBufferBindings)); } for (SizeT i = 0; i < bindingPointCnt; ++i) { - auto& point = MGB_CTX->GetBufferBindingPoint(target, i); + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(target, i); auto& obj = point.GetBoundObject(); if (!obj) { BindBufferBaseCached(glTarget, static_cast(i), 0); @@ -770,7 +770,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const SizeT pointCount = std::min( bufferCount, MG_State::GLState::GLContext::MAX_TRANSFORM_FEEDBACK_BUFFERS); for (SizeT i = 0; i < pointCount; ++i) { - auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::TransformFeedback, i); + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::TransformFeedback, i); const auto& obj = point.GetBoundObject(); // A stride-0 slot (two consecutive gl_NextBuffer entries) captures nothing and // needs no binding; anything else with no buffer never got past the frontend. @@ -822,10 +822,10 @@ namespace MobileGL::MG_Backend::DirectGLES { if (MG_Config::Transport != MG_Config::TransportMode::Monolith) return; #endif const SizeT bindingPointCnt = - MGB_CTX->GetTouchedBufferBindingPointCount(BufferTarget::ShaderStorage); + MG_Pipe::gPipeInputs.GetTouchedBufferBindingPointCount(BufferTarget::ShaderStorage); for (SizeT i = 0; i < bindingPointCnt; ++i) { const auto& obj = - MGB_CTX->GetBufferBindingPoint(BufferTarget::ShaderStorage, i).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::ShaderStorage, i).GetBoundObject(); // P3a (D-D): announced on the reverse channel on the handle arm, poked into // the object on the legacy one. MarkBufferGpuWritten is the one place that // decides, so the three announcement sites stay one line each. @@ -903,14 +903,14 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } #endif - const SizeT pointCount = MGB_CTX->GetBufferBindingPointCount(BufferTarget::AtomicCounter); + const SizeT pointCount = MG_Pipe::gPipeInputs.GetBufferBindingPointCount(BufferTarget::AtomicCounter); for (const Int glBinding : glBindings) { if (glBinding < 0 || static_cast(glBinding) >= pointCount) continue; const Int esslBinding = esslBindingTop - glBinding; // Already diagnosed once when the block was transpiled; nothing was bound to it // there either, so there is nothing to unbind here. if (esslBinding < 0) continue; - auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::AtomicCounter, + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::AtomicCounter, static_cast(glBinding)); auto& obj = point.GetBoundObject(); if (!obj) { @@ -947,7 +947,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - auto& bufferObject = MGB_CTX->GetBufferBindingSlot(target).GetBoundObject(); + auto& bufferObject = MG_Pipe::gPipeInputs.GetBufferBindingSlot(target).GetBoundObject(); if (!bufferObject) { g_GLESFuncs.glBindBuffer(glTarget, 0); return; @@ -1390,7 +1390,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif { auto& possibleIndirectBuffer = - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (possibleIndirectBuffer) { SyncBoundBuffer(BufferTarget::DrawIndirect, GL_DRAW_INDIRECT_BUFFER); } @@ -1842,7 +1842,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const SizeT packedStride = program->GetTransformFeedbackPackedStride(); const SizeT modelledVertices = - static_cast(MGB_CTX->GetTransformFeedbackCapturedVertices()); + static_cast(MG_Pipe::gPipeInputs.GetTransformFeedbackCapturedVertices()); const SizeT vertices = std::min(modelledVertices, xfb.scatterCapacityVertices); if (packedStride == 0 || vertices == 0) { // The scatter path redirected the DRIVER's capture into the scratch buffer, @@ -2038,10 +2038,10 @@ namespace MobileGL::MG_Backend::DirectGLES { if (record) program.Archive = record->Archive; } } else { - program.Frontend = MGB_CTX->GetTransformFeedbackProgram(); + program.Frontend = MG_Pipe::gPipeInputs.GetTransformFeedbackProgram(); } #else - const auto& program = MGB_CTX->GetTransformFeedbackProgram(); + const auto& program = MG_Pipe::gPipeInputs.GetTransformFeedbackProgram(); #endif if (!program) { // The pending flag is deliberately NOT consumed here. It used to be cleared @@ -2076,7 +2076,7 @@ namespace MobileGL::MG_Backend::DirectGLES { continue; } #endif - auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::TransformFeedback, + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::TransformFeedback, static_cast(i)); const auto& bufferObject = point.GetBoundObject(); if (!bufferObject) continue; @@ -2490,10 +2490,10 @@ namespace MobileGL::MG_Backend::DirectGLES { // MONOLITH ONLY, and the gate is what keeps a live transport's apply thread out of // the frontend VAO: with a transport the CLIENT owns those bytes and snapshots them // from the GL thread (MG_Impl/Pipe/OwnedDrawInputs.h), so there is nothing for the - // server to stage - and reading MGB_CTX there is the role violation this family's + // server to stage - and reading gPipeInputs there is the role violation this family's // other monolith glue is guarded against. if (MG_Config::Transport != MG_Config::TransportMode::Monolith) return true; - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!currentVAO) return true; // A draw whose attributes all come from buffers has nothing to snapshot, and asking @@ -2527,11 +2527,11 @@ namespace MobileGL::MG_Backend::DirectGLES { inputs.WantVertices = clientVertexRate; // The driver does its own restart handling; the plan has to know only that the restart // value is not a vertex, or the snapshot would stage an element no primitive fetches. - inputs.PrimitiveRestart = MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); - inputs.RestartIndex = MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex) + inputs.PrimitiveRestart = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); + inputs.RestartIndex = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex) ? (indexSize == 1 ? 0xffu : indexSize == 2 ? 0xffffu : 0xffffffffu) - : MGB_CTX->GetPrimitiveRestartIndex(); + : MG_Pipe::gPipeInputs.GetPrimitiveRestartIndex(); MG_Pipe::MGPipeClientFetchPlan plan; if (!plan.Build(inputs, &ReadClientSnapshotBytes, &sources)) return false; @@ -2586,7 +2586,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // MONOLITH ONLY - see SyncClientSideVertexArraysForFetch; this wrapper's own read of // the bound VAO is the frontend read that must not happen on an apply thread. if (MG_Config::Transport != MG_Config::TransportMode::Monolith) return true; - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!currentVAO) return true; const Uint8 indexSize = static_cast(MG_Util::GetGLTypeSize(type)); if (indexSize == 0) return true; @@ -2627,13 +2627,13 @@ namespace MobileGL::MG_Backend::DirectGLES { } auto* twin = ResolveVaoTwin(MG_Pipe::MGPipeApplier().BoundVertexElements); if (twin == nullptr) return; - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!currentVAO) return; twin->SyncClientSideAttributesForDrawArrays(currentVAO, first, count); return; } #endif - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!currentVAO) return; auto* backendVAOSlot = g_backendVertexArrayObjects.Find(currentVAO.get()); if (backendVAOSlot && *backendVAOSlot) { @@ -2695,7 +2695,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif const SharedPtr noVao; - const auto& vao = fromRecords ? noVao : MGB_CTX->GetBoundVertexArray(); + const auto& vao = fromRecords ? noVao : MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!fromRecords && !vao) return; const Uint32 activeAttribMask = program->GetActiveAttributeLocationMask(); @@ -2759,7 +2759,7 @@ namespace MobileGL::MG_Backend::DirectGLES { for (Uint32 remaining = memo.pendingMask; remaining != 0; remaining &= remaining - 1) { const Uint32 location = static_cast(std::countr_zero(remaining)); - const auto& currentValue = MGB_CTX->GetCurrentVertexAttribute(location); + const auto& currentValue = MG_Pipe::gPipeInputs.GetCurrentVertexAttribute(location); const auto typeInfo = MG_State::GLState::ClassifyVertexAttribType(program->GetAttribType(location)); switch (typeInfo.baseType) { case MG_State::GLState::VertexAttribBaseType::Float: @@ -2861,7 +2861,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } const SharedPtr noVao; - const auto& vao = fromRecords ? noVao : MGB_CTX->GetBoundVertexArray(); + const auto& vao = fromRecords ? noVao : MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!fromRecords && !vao) return; // ProgramObject::GetActiveAttributeLocationMask, over the archive's own `attribs`: @@ -2922,7 +2922,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // below rather than reading past the end. const GLenum attribType = location < link.attribTypes.size() ? link.attribTypes[location] : 0; - const auto& currentValue = MGB_CTX->GetCurrentVertexAttribute(location); + const auto& currentValue = MG_Pipe::gPipeInputs.GetCurrentVertexAttribute(location); const auto typeInfo = MG_State::GLState::ClassifyVertexAttribType(attribType); switch (typeInfo.baseType) { case MG_State::GLState::VertexAttribBaseType::Float: @@ -3084,7 +3084,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const Bool handleArm = MGB_UNIT_BINDINGS_HANDLE_ARM; out.resize(static_cast(maxTouchedUnit + 1)); for (Int unit = 0; unit <= maxTouchedUnit; ++unit) { - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); auto& snapshot = out[static_cast(unit)]; const auto& slots = textureUnit.GetAllBindingSlots(); for (SizeT i = 0; i < slots.size(); ++i) { @@ -3102,7 +3102,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (snapshots.size() != static_cast(maxTouchedUnit + 1)) return false; const Bool handleArm = MGB_UNIT_BINDINGS_HANDLE_ARM; for (Int unit = 0; unit <= maxTouchedUnit; ++unit) { - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); const auto& snapshot = snapshots[static_cast(unit)]; const auto& slots = textureUnit.GetAllBindingSlots(); for (SizeT i = 0; i < slots.size(); ++i) { @@ -3257,8 +3257,8 @@ namespace MobileGL::MG_Backend::DirectGLES { /*hit=*/false); } } - const Uint64 contextId = MGB_CTX->GetTextureContextId(); - const Uint64 bindGeneration = MGB_CTX->GetTextureBindGeneration(); + const Uint64 contextId = MG_Pipe::gPipeInputs.GetTextureContextId(); + const Uint64 bindGeneration = MG_Pipe::gPipeInputs.GetTextureBindGeneration(); if (MG_Util::PipeStats::Enabled()) { // Two accessor calls whichever way the shutter goes; only the unit WALK is // gated, and that walk reads no GLContext accessor of its own. @@ -3490,7 +3490,7 @@ namespace MobileGL::MG_Backend::DirectGLES { DrawTextureSyncKeys CaptureDrawTextureSyncKeys() { DrawTextureSyncKeys keys; - keys.contextId = MGB_CTX->GetTextureContextId(); + keys.contextId = MG_Pipe::gPipeInputs.GetTextureContextId(); // Units past the frontend's high-water mark have provably-empty slots. // // P4a e2 DELIBERATELY DOES NOT take this off the sampler-view window's Count, and @@ -3503,8 +3503,8 @@ namespace MobileGL::MG_Backend::DirectGLES { // CLIENT as the count argument and says nothing about re-deriving it server-side. // It is one accessor read per draw; the integrator can move it in one line once a // tree exists where the two can be compared. - keys.maxTouchedUnit = MGB_CTX->GetMaxTouchedTextureUnit(); - keys.samplingGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + keys.maxTouchedUnit = MG_Pipe::gPipeInputs.GetMaxTouchedTextureUnit(); + keys.samplingGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); keys.unitBindingsEpoch = CurrentUnitBindingsEpoch(keys.maxTouchedUnit); if (MG_Util::PipeStats::Enabled()) { // The three reads above; CurrentUnitBindingsEpoch counts its own two when it @@ -3802,7 +3802,7 @@ namespace MobileGL::MG_Backend::DirectGLES { g_unitTextureSyncListValid = false; g_unitTextureSyncList.clear(); for (Int index = 0; index <= maxTouchedUnit; ++index) { - auto& unit = MGB_CTX->GetTextureUnitObject(index); + auto& unit = MG_Pipe::gPipeInputs.GetTextureUnitObject(index); for (const auto& bindingSlot : unit.GetAllBindingSlots()) { auto& textureObject = bindingSlot.GetBoundObject(); // An image-less default texture (name 0) is the slot's initial / "unbound" @@ -4185,7 +4185,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - auto& imageBinding = MGB_CTX->GetImageTextureBinding(static_cast(unit)); + auto& imageBinding = MG_Pipe::gPipeInputs.GetImageTextureBinding(static_cast(unit)); TrackWritableImageBufferUnit(unit, IsWritableImageBufferTexture(imageBinding)); if (imageBinding.Texture && unit + 1 > g_imageUnitHighWaterMark) { g_imageUnitHighWaterMark = unit + 1; @@ -4258,7 +4258,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (g_writableImageBufferUnitCount == 0) return; for (Uint unit = 0; unit < g_writableImageBufferUnits.size(); ++unit) { if (!g_writableImageBufferUnits[unit]) continue; - const auto& imageBinding = MGB_CTX->GetImageTextureBinding(static_cast(unit)); + const auto& imageBinding = MG_Pipe::gPipeInputs.GetImageTextureBinding(static_cast(unit)); if (!IsWritableImageBufferTexture(imageBinding)) { TrackWritableImageBufferUnit(unit, false); continue; @@ -5030,7 +5030,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - Uint16 currentRenderStateVersion = MGB_CTX->GetRenderStateParametersVersion(); + Uint16 currentRenderStateVersion = MG_Pipe::gPipeInputs.GetRenderStateParametersVersion(); const Bool forceFullPush = g_forceFullRenderStateResync; g_forceFullRenderStateResync = false; // The alpha discipline for widened colour attachments (see the header comment on @@ -5058,7 +5058,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::PipeStats::AddCalls(MG_Util::PipeStats::CallClass::AccessorCalls, 3); } - const auto& parameters = MGB_CTX->GetRenderStateParameters(); + const auto& parameters = MG_Pipe::gPipeInputs.GetRenderStateParameters(); // The frontend has ONE version for the whole parameter block, so a per-draw blend // toggle used to re-diff all ~40 pieces of state field by field on every draw @@ -5087,7 +5087,7 @@ namespace MobileGL::MG_Backend::DirectGLES { !g_hasSyncedRenderState || std::memcmp(currentBytes + kBlendSpanEnd, syncedBytes + kBlendSpanEnd, sizeof(RenderStateParameters) - kBlendSpanEnd) != 0; - IntVec4 backendViewport = MGB_CTX->GetViewport(); + IntVec4 backendViewport = MG_Pipe::gPipeInputs.GetViewport(); if (backendViewport.z() <= 0 || backendViewport.w() <= 0) { Int surfaceWidth = 0; Int surfaceHeight = 0; @@ -5170,7 +5170,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // never turns it on, so the driver has to be told to write raw. Without this a render // into an sRGB colour buffer comes back encoded once too often (the shader's own // decode on the next fetch then leaves the value one conversion short). - const Bool srgbWrites = MGB_CTX->IsCapabilityEnabled(CapabilityInput::FramebufferSrgb); + const Bool srgbWrites = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::FramebufferSrgb); if (g_GLESCapabilities.SupportsSrgbWriteControl && (forceFullPush || srgbWrites != g_syncedSrgbFramebufferWrites)) { srgbWrites ? g_GLESFuncs.glEnable(GL_FRAMEBUFFER_SRGB) @@ -6148,11 +6148,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // member set it has to be told. (twin->GetPassthroughTessControlPatchVertices() >= 0 && (twin->GetPassthroughTessControlPatchVertices() != - static_cast(MGB_CTX->GetPatchVertices()) || + static_cast(MG_Pipe::gPipeInputs.GetPatchVertices()) || !BitwiseEqual(twin->GetPassthroughTessControlOuterLevel(), - MGB_CTX->GetPatchDefaultOuterLevel()) || + MG_Pipe::gPipeInputs.GetPatchDefaultOuterLevel()) || !BitwiseEqual(twin->GetPassthroughTessControlInnerLevel(), - MGB_CTX->GetPatchDefaultInnerLevel())))) { + MG_Pipe::gPipeInputs.GetPatchDefaultInnerLevel())))) { twin->SyncToBackend(currentProgram); } g_currentDrawFrontendProgram = currentProgram.get(); @@ -6219,11 +6219,11 @@ namespace MobileGL::MG_Backend::DirectGLES { !twin->ImageUnitFormatsStillMatch() || (twin->GetPassthroughTessControlPatchVertices() >= 0 && (twin->GetPassthroughTessControlPatchVertices() != - static_cast(MGB_CTX->GetPatchVertices()) || + static_cast(MG_Pipe::gPipeInputs.GetPatchVertices()) || !BitwiseEqual(twin->GetPassthroughTessControlOuterLevel(), - MGB_CTX->GetPatchDefaultOuterLevel()) || + MG_Pipe::gPipeInputs.GetPatchDefaultOuterLevel()) || !BitwiseEqual(twin->GetPassthroughTessControlInnerLevel(), - MGB_CTX->GetPatchDefaultInnerLevel())))) { + MG_Pipe::gPipeInputs.GetPatchDefaultInnerLevel())))) { twin->SyncToBackendByHandle(cso); } g_currentDrawProgramHandle = cso; @@ -6540,7 +6540,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // frontend VAO always did. const Bool vertexInputFromRecords = BufferImpl::VertexInputReadsRecords(); const SharedPtr noFrontendVao; - const auto& currentVAO = vertexInputFromRecords ? noFrontendVao : MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = vertexInputFromRecords ? noFrontendVao : MG_Pipe::gPipeInputs.GetBoundVertexArray(); VertexArrayImpl::BackendVertexArrayObject* vaoTwin = nullptr; Uint32 vaoConfigVersion = 0; #if MOBILEGL_BUILD_DISAGGREGATED @@ -6570,7 +6570,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // reaches the same "nothing to bind" answers a null frontend program always did. const SharedPtr noFrontendProgram; const Bool programFromRecords = DrawProgramFromRecords(); - const auto& currentProgram = programFromRecords ? noFrontendProgram : MGB_CTX->GetProgramForDraw(); + const auto& currentProgram = programFromRecords ? noFrontendProgram : MG_Pipe::gPipeInputs.GetProgramForDraw(); if (MG_Util::PipeStats::Enabled()) { // THE per-draw denominator for Espryt, plus this function's own two accessor // calls (the VAO and the draw program). Everything the callees below read is @@ -6772,7 +6772,7 @@ namespace MobileGL::MG_Backend::DirectGLES { }; for (Int unit = 0; unit <= maxTouchedUnit; ++unit) { - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); Array boundBackendTargets{}; Array claimedByFrontendTarget{}; claimedByFrontendTarget.fill(TextureTarget::Unknown); @@ -7081,7 +7081,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (!walkedFromRecords) { for (Int unit = 0; unit <= maxTouchedUnit; ++unit) { - const auto& samplerObject = MGB_CTX->GetTextureUnitObject(unit).GetSamplerObject(); + const auto& samplerObject = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit).GetSamplerObject(); if (samplerObject) { if (auto* backendSampler = ResolveUnitSamplerBackend(unit, samplerObject)) { backendSampler->Bind(unit); @@ -7356,7 +7356,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // transport and therefore take the frontend arm below unchanged. const SharedPtr noFrontendProgram; BindCurrentTextures(TextureImpl::CaptureDrawTextureSyncKeys(), - DrawProgramFromRecords() ? noFrontendProgram : MGB_CTX->GetProgramForDraw()); + DrawProgramFromRecords() ? noFrontendProgram : MG_Pipe::gPipeInputs.GetProgramForDraw()); } // Binds the current program's backend object and re-establishes its per-program @@ -7644,7 +7644,7 @@ namespace MobileGL::MG_Backend::DirectGLES { continue; } #endif - auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::Uniform, binding); + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::Uniform, binding); auto& bufferObj = point.GetBoundObject(); auto range = point.GetRange(); @@ -7837,7 +7837,7 @@ namespace MobileGL::MG_Backend::DirectGLES { continue; } #endif - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); auto& samplerObject = textureUnit.GetSamplerObject(); const auto& texture2D = textureUnit.GetBindingSlot(TextureTarget::Texture2D).GetBoundObject(); @@ -7964,7 +7964,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } return PrgramImpl::ResolveProgramTwin(cso); } - const auto& currentProgram = MGB_CTX->GetProgramForDraw(); + const auto& currentProgram = MG_Pipe::gPipeInputs.GetProgramForDraw(); if (!currentProgram || !currentProgram->GetLinkStatus() || !currentProgram->GetSpirvStatus()) { return nullptr; } @@ -8034,7 +8034,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } return program->ReadsDrawID() || (batchCarriesBaseVertices && program->ReadsBaseVertex()); } - const auto& currentProgram = MGB_CTX->GetProgramForDraw(); + const auto& currentProgram = MG_Pipe::gPipeInputs.GetProgramForDraw(); if (!currentProgram || program->GetSyncedLinkVersion() != currentProgram->GetLinkVersion()) { return true; } @@ -8141,12 +8141,12 @@ namespace MobileGL::MG_Backend::DirectGLES { // times; rasterizer discard means there are no fragments to gate at all, so replaying // would be pure cost with nothing to show for it. Both fall back to a single pass with an // open gate, i.e. to the pre-emulation behaviour, rather than to wrong data. - if (MGB_CTX->IsTransformFeedbackActive() || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { + if (MG_Pipe::gPipeInputs.IsTransformFeedbackActive() || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return 1; } - const auto& parameters = MGB_CTX->GetRenderStateParameters(); + const auto& parameters = MG_Pipe::gPipeInputs.GetRenderStateParameters(); Int surfaceWidth = 0; Int surfaceHeight = 0; if (!QueryCurrentSurfaceSize(surfaceWidth, surfaceHeight)) { @@ -8476,7 +8476,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // the 7 strict-lane entries of GetProgramForDispatch@DispatchCompute. const SharedPtr noFrontendProgram; const auto& currentProgram = - DrawProgramFromRecords() ? noFrontendProgram : MGB_CTX->GetProgramForDispatch(); + DrawProgramFromRecords() ? noFrontendProgram : MG_Pipe::gPipeInputs.GetProgramForDispatch(); const TextureImpl::DrawTextureSyncKeys textureKeys = TextureImpl::CaptureDrawTextureSyncKeys(); BufferImpl::SyncComputeBuffers(includeDispatchIndirectBuffer); @@ -8528,12 +8528,12 @@ namespace MobileGL::MG_Backend::DirectGLES { // P5f (fr): no declaration, dispatch-table slot or caller remains for this legacy // helper. Exclude it from the server-capable build; retain non-D-P bytes for G1. GLuint GetBackendProgramId(GLuint program) { - if (!MGB_CTX->ValidateProgramName(program)) { + if (!MG_Pipe::gPipeInputs.ValidateProgramName(program)) { MGLOG_E_ONCE("Invalid frontend program object: %u", program); return 0; } - auto& programObject = MGB_CTX->GetProgramObject(program); + auto& programObject = MG_Pipe::gPipeInputs.GetProgramObject(program); if (!programObject) { MGLOG_E_ONCE("Program object %u is null.", program); return 0; @@ -8602,7 +8602,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // color must go through glClearBufferfv, which GLES does not clamp. GLbitfield remainingMask = mask; if ((mask & GL_COLOR_BUFFER_BIT) != 0) { - const FloatVec4& cc = MGB_CTX->GetRenderStateParameters().ClearColor; + const FloatVec4& cc = MG_Pipe::gPipeInputs.GetRenderStateParameters().ClearColor; const Bool outOfRange = cc.x() < 0.f || cc.x() > 1.f || cc.y() < 0.f || cc.y() > 1.f || cc.z() < 0.f || cc.z() > 1.f || cc.w() < 0.f || cc.w() > 1.f; // A widened attachment's stored alpha has to end up 1.0, and glClear applies ONE @@ -8679,7 +8679,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif { const auto& feFbo = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (feFbo) { feIdx = feFbo->GetExternalIndex(); feVer = feFbo->GetObjectVersion(); @@ -8869,7 +8869,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const SharedPtr& BoundElementArrayBuffer() { static const SharedPtr none; RefuseElementArrayBufferFromTheFrontend("BoundElementArrayBuffer"); - const auto& vao = MGB_CTX->GetBoundVertexArray(); + const auto& vao = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!vao) return none; return vao->GetIndexBufferBindingSlot().GetBoundObject(); } @@ -8886,13 +8886,13 @@ namespace MobileGL::MG_Backend::DirectGLES { } // namespace RestartSubstitutionKind ResolveRestartSubstitution(GLenum indexType) { - if (!MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex)) { + if (!MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex)) { return RestartSubstitutionKind::None; } const Uint32 fixedMax = MG_Util::FixedRestartIndexForGLType(indexType); if (fixedMax == 0) return RestartSubstitutionKind::None; - const Uint32 restartIndex = MGB_CTX->GetPrimitiveRestartIndex(); + const Uint32 restartIndex = MG_Pipe::gPipeInputs.GetPrimitiveRestartIndex(); if (restartIndex == fixedMax) return RestartSubstitutionKind::None; // Strictly greater, never truncated. GL 4.6 core 10.3.6 compares the fetched index // zero-extended against the full 32-bit state, so an index this type cannot hold matches @@ -8932,7 +8932,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } const SizeT sourceIndexSize = MG_Util::GetGLTypeSize(indexType); const Uint32 fixedMax = MG_Util::FixedRestartIndexForGLType(indexType); - const Uint32 applicationRestartIndex = MGB_CTX->GetPrimitiveRestartIndex(); + const Uint32 applicationRestartIndex = MG_Pipe::gPipeInputs.GetPrimitiveRestartIndex(); const Uint8* source = nullptr; SizeT indexCount = 0; @@ -9258,7 +9258,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ? SharedPtr(nullptr) : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); ExecuteIndexedIndirectCommands(mode, type, indexSize, commandBytes, reinterpret_cast(indirect), drawIndirectBuffer, drawcount, stride, "MultiDrawElementsIndirect"); } @@ -9348,8 +9348,8 @@ namespace MobileGL::MG_Backend::DirectGLES { } #endif - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); - auto parameterBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto parameterBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); if (!drawBuffer) { MGLOG_E_ONCE("MultiDrawElementsIndirectCount skipped: no GL_DRAW_INDIRECT_BUFFER is bound"); return; @@ -9427,7 +9427,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ? SharedPtr(nullptr) : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); ExecuteArraysIndirectCommands(mode, commandBytes, reinterpret_cast(indirect), drawIndirectBuffer, drawcount, stride, "MultiDrawArraysIndirect"); } @@ -9512,8 +9512,8 @@ namespace MobileGL::MG_Backend::DirectGLES { } #endif - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); - auto parameterBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto parameterBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); if (!drawBuffer) { MGLOG_E_ONCE("MultiDrawArraysIndirectCount skipped: no GL_DRAW_INDIRECT_BUFFER is bound"); return; @@ -9698,7 +9698,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ? SharedPtr(nullptr) : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); ExecuteIndexedIndirectCommands(mode, type, indexSize, commandBytes, reinterpret_cast(indirect), drawIndirectBuffer, 1, sizeof(DrawElementsIndirectCommand), "DrawElementsIndirect"); @@ -9747,7 +9747,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ? SharedPtr(nullptr) : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); ExecuteArraysIndirectCommands(mode, commandBytes, reinterpret_cast(indirect), drawIndirectBuffer, 1, sizeof(DrawArraysIndirectCommand), "DrawArraysIndirect"); } @@ -9995,8 +9995,8 @@ namespace MobileGL::MG_Backend::DirectGLES { // restore. Drop the flag so it is not misattributed to the emulation's own work. DrainBlitErrors(); - if (MGB_CTX->IsTransformFeedbackActive() && - !MGB_CTX->IsTransformFeedbackPaused() && g_GLESFuncs.glPauseTransformFeedback) { + if (MG_Pipe::gPipeInputs.IsTransformFeedbackActive() && + !MG_Pipe::gPipeInputs.IsTransformFeedbackPaused() && g_GLESFuncs.glPauseTransformFeedback) { g_GLESFuncs.glPauseTransformFeedback(); m_pausedTransformFeedback = true; DrainBlitErrors(); @@ -11055,8 +11055,8 @@ namespace MobileGL::MG_Backend::DirectGLES { } else #endif mask &= ~BlitLayeredDestinationAspects( - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(), - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(), srcX0, srcY0, + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(), + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask); if (mask != 0) { IssueBlitWithResolveFallback(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); @@ -11118,9 +11118,9 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedNC(__func__, TRACY_ZONECOLOR_BACKEND); #endif - auto unit = MGB_CTX->GetActiveTextureUnit(); + auto unit = MG_Pipe::gPipeInputs.GetActiveTextureUnit(); #if !MOBILEGL_BUILD_DISAGGREGATED - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); #endif auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); @@ -11154,7 +11154,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif #if MOBILEGL_BUILD_DISAGGREGATED - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); #endif const auto& bindingSlot = textureUnit.GetBindingSlot(textureTarget); { @@ -11224,7 +11224,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The frontend's current PACK parameters, for readbacks the ES driver serves // directly with the client's layout. static PixelStoreImpl::PackState PackStateFromContext() { - const auto packParams = MGB_CTX->GetPixelStoreParameters(false); + const auto packParams = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false); return {static_cast(packParams.Alignment), static_cast(packParams.RowLength), static_cast(packParams.SkipRows), static_cast(packParams.SkipPixels)}; } @@ -11497,7 +11497,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::ConvertGLEnumToString(err).c_str(), MG_Util::ConvertGLEnumToString(target).c_str(), MG_Util::ConvertTextureInternalFormatToString(format).c_str()); - MGB_CTX->RecordError( + MG_Pipe::gPipeInputs.RecordError( ConvertGLESErrorToErrorCode(err), MakeUnique("DirectGLES", operation, MG_Util::ConvertGLEnumToString(err))); @@ -12316,7 +12316,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Bind necessary FBO and texture BindCurrentFBO(FramebufferTarget::Read); - Uint activeTextureUnit = MGB_CTX->GetActiveTextureUnit(); + Uint activeTextureUnit = MG_Pipe::gPipeInputs.GetActiveTextureUnit(); TextureImpl::BackendTextureObject* dstBackendTexture = nullptr; TextureInternalFormat mgInternalFormat{}; #if MOBILEGL_BUILD_DISAGGREGATED @@ -12346,7 +12346,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } else #endif { - const auto& textureObject = MGB_CTX->GetTextureUnitObject((Int)activeTextureUnit) + const auto& textureObject = MG_Pipe::gPipeInputs.GetTextureUnitObject((Int)activeTextureUnit) .GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)) .GetBoundObject(); if (textureObject) TextureImpl::NoteDriverSideTextureWrite(textureObject); @@ -12443,7 +12443,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Bind necessary FBO and texture BindCurrentFBO(FramebufferTarget::Read); - auto activeTextureUnit = MGB_CTX->GetActiveTextureUnit(); + auto activeTextureUnit = MG_Pipe::gPipeInputs.GetActiveTextureUnit(); TextureImpl::BackendTextureObject* dstBackendTexture = nullptr; #if MOBILEGL_BUILD_DISAGGREGATED // P5c (hd, CONTRACT-P5C §3.4): see CopyTexImage2D - the record's Dst handle, never the @@ -12464,7 +12464,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } else #endif { - const auto& textureObject = MGB_CTX->GetTextureUnitObject(activeTextureUnit) + const auto& textureObject = MG_Pipe::gPipeInputs.GetTextureUnitObject(activeTextureUnit) .GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)) .GetBoundObject(); if (textureObject) TextureImpl::NoteDriverSideTextureWrite(textureObject); @@ -12910,8 +12910,8 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } #endif - auto unitIndex = MGB_CTX->GetActiveTextureUnit(); - auto& unit = MGB_CTX->GetTextureUnitObject(unitIndex); + auto unitIndex = MG_Pipe::gPipeInputs.GetActiveTextureUnit(); + auto& unit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unitIndex); auto& slot = unit.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)); auto& texture = slot.GetBoundObject(); MOBILEGL_ASSERT(texture != nullptr, "GenerateMipmap requires a bound texture."); @@ -13450,8 +13450,8 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } #endif - if (!MGB_CTX->ValidateProgramName(program)) return; - auto& programObject = MGB_CTX->GetProgramObject(program); + if (!MG_Pipe::gPipeInputs.ValidateProgramName(program)) return; + auto& programObject = MG_Pipe::gPipeInputs.GetProgramObject(program); if (!programObject) return; #if MOBILEGL_BUILD_DISAGGREGATED @@ -13652,7 +13652,7 @@ namespace MobileGL::MG_Backend::DirectGLES { template static Bool StoreReadbackRowsToClient(GLsizei width, GLsizei height, SizeT dstPixelBytes, void* pixels, const char* what, FillRow&& fillRow) { - const auto packParams = MGB_CTX->GetPixelStoreParameters(false); + const auto packParams = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false); const SizeT rowPixels = static_cast(packParams.RowLength > 0 ? packParams.RowLength : width); const SizeT dstRowStride = AlignPixelRow(rowPixels * dstPixelBytes, packParams.Alignment); const SizeT dstOffset = static_cast(std::max(packParams.SkipRows, 0)) * dstRowStride + @@ -13664,7 +13664,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); const SizeT pboOffset = reinterpret_cast(pixels); if (pixelPackBufferObject && pboOffset + packedSize > pixelPackBufferObject->GetSize()) { MGLOG_E_ONCE("ReadPixels: %s readback PBO is too small", what); @@ -14685,7 +14685,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); if (!pixelPackBufferObject && pixels == nullptr) { return true; } @@ -14941,7 +14941,7 @@ namespace MobileGL::MG_Backend::DirectGLES { "active transport there is no client shadow to fall back to - the read is " "DECLINED and the destination keeps its bytes", static_cast(uploadTarget), level); - MGB_CTX->RecordError( + MG_Pipe::gPipeInputs.RecordError( ErrorCode::InvalidOperation, MakeUnique( "DirectGLES", "GetTexImage", @@ -14956,7 +14956,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); if (!pixelPackBufferObject && pixels == nullptr) { return true; } @@ -15232,7 +15232,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // and legacy GL_RED reads) goes through the wide-format conversion, which picks a wide type // the driver accepts for the current attachment. GL_PACK_SWAP_BYTES has no ES equivalent, so // it always takes the conversion path (which swaps on the CPU). - const Bool packSwapBytes = MGB_CTX->GetPixelStoreParameters(false).SwapBytes; + const Bool packSwapBytes = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false).SwapBytes; // The read buffer is what glReadPixels reads, so the frontend's READ binding is exactly // the right thing to ask here. const Bool forceOpaqueAlpha = FramebufferImpl::IsAlphaWidenedFallbackReadAttachment(); @@ -15279,7 +15279,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); Bool usePBO = false; GLuint packBufferId = 0; if (pixelPackBufferObject) { @@ -15389,10 +15389,10 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("GetTexImage: SyncCurrentFBO()"); FramebufferImpl::SyncCurrentFBO(); - auto activeTextureUnit = MGB_CTX->GetActiveTextureUnit(); + auto activeTextureUnit = MG_Pipe::gPipeInputs.GetActiveTextureUnit(); MGLOG_D("GetTexImage: active texture unit = %u", activeTextureUnit); - const auto& textureObject = MGB_CTX->GetTextureUnitObject(activeTextureUnit) + const auto& textureObject = MG_Pipe::gPipeInputs.GetTextureUnitObject(activeTextureUnit) .GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)) .GetBoundObject(); @@ -15625,7 +15625,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Each slice is packed as its own 2D image, so the per-slice call must not apply // GL_PACK_SKIP_IMAGES / GL_PACK_IMAGE_HEIGHT itself - this walks the destination // over them, using the same layout StoreWideRowsToClient computes. - const auto packParams = MGB_CTX->GetPixelStoreParameters(false); + const auto packParams = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false); const SizeT dstPixelBytes = GetReadbackDstPixelSize(conversionMapping, type); const SizeT rowPixels = static_cast(packParams.RowLength > 0 ? packParams.RowLength : size.x()); @@ -15726,7 +15726,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); Bool usePBO = false; GLuint packBufferId = 0; if (pixelPackBufferObject) { diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 4dd19c41..649bc2b4 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -7,7 +7,7 @@ // End of Source File Header #include "Managers.h" -#include +#include // P3a: the handle-shaped resource op table, the applier's records and the reverse channel. // Both headers are compiled into the library only under push, so they are included here // under the same condition - a pull build must gain no declaration it cannot link. @@ -7767,9 +7767,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // that needs no work costs the same nothing per draw that any other synced texture does. void BackendTextureObject::StampViewSyncKeys( const SharedPtr& stateTextureObject) { - if (MGB_CTX_LIVE) { - m_syncedShapeContextId = MGB_CTX->GetTextureContextId(); - m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + if (MG_Pipe::gPipeInputs.IsLive()) { + m_syncedShapeContextId = MG_Pipe::gPipeInputs.GetTextureContextId(); + m_syncedShapeGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion(); } m_syncedContentVersion = stateTextureObject->GetContentVersion(); @@ -8453,9 +8453,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // LEGACY ARM ONLY from P4a on: the memos it reads are the pre-handle ones and the // record above answers the same question in one compare. if (pushedStorage == nullptr) - if (m_isInitialized && m_syncedShapeContextId != 0 && MGB_CTX_LIVE && - m_syncedShapeContextId == MGB_CTX->GetTextureContextId() && - m_syncedShapeGeneration == MGB_CTX->GetSamplingResolutionGeneration() && + if (m_isInitialized && m_syncedShapeContextId != 0 && MG_Pipe::gPipeInputs.IsLive() && + m_syncedShapeContextId == MG_Pipe::gPipeInputs.GetTextureContextId() && + m_syncedShapeGeneration == MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration() && m_syncedContentVersion == stateTextureObject->GetContentVersion() && m_syncedShapeParamsVersion == stateTextureObject->GetTextureParamsVersion() && stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) { @@ -8573,9 +8573,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // The probe just proved "fully synced" from the real state, so the cheap // gate may be (re)stamped here: the coarse generation only ever goes stale // from OTHER textures' churn, and this draw re-validated this one. - if (MGB_CTX_LIVE) { - m_syncedShapeContextId = MGB_CTX->GetTextureContextId(); - m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + if (MG_Pipe::gPipeInputs.IsLive()) { + m_syncedShapeContextId = MG_Pipe::gPipeInputs.GetTextureContextId(); + m_syncedShapeGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion(); } return; @@ -9878,9 +9878,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // Same instant, so the cheap gate's keys describe exactly this synced state. // Only Mipmap storage may arm it - the gate refuses other storage types anyway, // but a stale trio must not linger on an object that later switches type. - if (MGB_CTX_LIVE && stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) { - m_syncedShapeContextId = MGB_CTX->GetTextureContextId(); - m_syncedShapeGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + if (MG_Pipe::gPipeInputs.IsLive() && stateTextureObject->GetStorageType() == TextureStorageType::Mipmap) { + m_syncedShapeContextId = MG_Pipe::gPipeInputs.GetTextureContextId(); + m_syncedShapeGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); m_syncedShapeParamsVersion = stateTextureObject->GetTextureParamsVersion(); } else { m_syncedShapeContextId = 0; @@ -10895,7 +10895,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // read buffer names no colour attachment at all. static const MG_State::GLState::FramebufferAttachmentObject* GetReadColorAttachment() { const auto& readFBO = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (!readFBO) { return nullptr; } @@ -11306,7 +11306,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } #endif const auto& readFBO = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (!readFBO) { return false; } @@ -12969,7 +12969,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return static_cast(st.BoundShaderImages[static_cast(unit)].InternalFormat); } #endif - return static_cast(MGB_CTX->GetImageTextureBinding(unit).Format); + return static_cast(MG_Pipe::gPipeInputs.GetImageTextureBinding(unit).Format); } // Combines one (unit, format) pair into a running digest. Commutative, so the order @@ -13932,19 +13932,19 @@ namespace MobileGL::MG_Backend::DirectGLES { // patch size - so a program built for one value is stale for another. Recorded here // and compared on the draw path (SyncCurrentProgram), the same shape as the // storage-block and image-format signatures next to it. - const Uint patchVertices = MGB_CTX_LIVE - ? MGB_CTX->GetPatchVertices() + const Uint patchVertices = MG_Pipe::gPipeInputs.IsLive() + ? MG_Pipe::gPipeInputs.GetPatchVertices() : 3u; m_passthroughTessControlPatchVertices = static_cast(patchVertices); // PATCH_DEFAULT_{OUTER,INNER}_LEVEL are the same kind of dynamic state and are baked // into the same stage (ES has no such state and no entry point to forward them to), so // they are recorded and compared alongside the patch size - the two move together, as // BuildPassthroughTessControlEssl's contract says. - m_passthroughTessControlOuterLevel = MGB_CTX_LIVE - ? MGB_CTX->GetPatchDefaultOuterLevel() + m_passthroughTessControlOuterLevel = MG_Pipe::gPipeInputs.IsLive() + ? MG_Pipe::gPipeInputs.GetPatchDefaultOuterLevel() : FloatVec4(1.0f, 1.0f, 1.0f, 1.0f); - m_passthroughTessControlInnerLevel = MGB_CTX_LIVE - ? MGB_CTX->GetPatchDefaultInnerLevel() + m_passthroughTessControlInnerLevel = MG_Pipe::gPipeInputs.IsLive() + ? MG_Pipe::gPipeInputs.GetPatchDefaultInnerLevel() : FloatVec2(1.0f, 1.0f); if (tessEvalShaderIndex < 0 || @@ -15777,8 +15777,8 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_E_ONCE("Renderbuffer %u storage allocation ran out of memory: %dx%d, samples=%d, format=%s", stateRBOObject->GetExternalIndex(), width, height, samples, MG_Util::ConvertGLEnumToString(glInternalFormat).c_str()); - if (MGB_CTX_LIVE) { - MGB_CTX->RecordError( + if (MG_Pipe::gPipeInputs.IsLive()) { + MG_Pipe::gPipeInputs.RecordError( ErrorCode::OutOfMemory, MakeUnique("DirectGLES", "BackendRenderbufferObject::SyncToBackend", "The ES driver could not allocate the renderbuffer storage.")); @@ -15868,7 +15868,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::ConvertGLEnumToString(glInternalFormat).c_str()); // NO RecordError HERE. The object form reports the OOM to the application // through the live GLContext; on this arm there is no application on this side - // of the wire to report it to, and MGB_CTX->RecordError is itself one of the + // of the wire to report it to, and gPipeInputs->RecordError is itself one of the // BARRIER-PULLED rows (FieldOwnership.def) that rule F forbids an unbarriered // apply to touch. The client raises its own errors from its own validator. } diff --git a/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp b/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp index 0c07d93d..72abc1f5 100644 --- a/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp +++ b/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp @@ -9,7 +9,7 @@ #include "MultiDraw.h" #include "Managers.h" #include -#include +#include #include #include #include @@ -44,14 +44,14 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { // verbatim is already "this batch restarts nowhere". Uint32 RestartSentinelFor(GLenum type) { if (ResolveRestartSubstitution(type) != RestartSubstitutionKind::None) { - return MGB_CTX->GetPrimitiveRestartIndex(); + return MG_Pipe::gPipeInputs.GetPrimitiveRestartIndex(); } return MG_Util::FixedRestartIndexForGLType(type); } Bool RestartActive() { - return MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); + return MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); } // Vertices per primitive for the modes whose sub-draws may be concatenated into a @@ -95,7 +95,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { // PrepareForDraw leave on GL_ELEMENT_ARRAY_BUFFER (and how big is its store)", and // "give me its bytes on the CPU" - and until now it asked all three of the FRONTEND // VAO, on the apply thread, once per indexed multi-draw. That was the last unguarded - // `MGB_CTX->GetBoundVertexArray()` in the backend: package vi retired the ordinary + // `gPipeInputs->GetBoundVertexArray()` in the backend: package vi retired the ordinary // draw path's copy (DirectGLES.cpp's SyncCurrentVertexAttributeValues / PrepareForDraw) // and this one survived only because these batches used to die earlier, on the // framebuffer row fb has since retired. @@ -221,7 +221,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { } #endif // MONOLITH GLUE from here down, token for token what each call site did before. - const auto& vao = MGB_CTX->GetBoundVertexArray(); + const auto& vao = MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (!vao) return view; const auto& ibo = vao->GetIndexBufferBindingSlot().GetBoundObject(); if (!ibo) return view; @@ -269,7 +269,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { // // This was the LAST unguarded frontend read on the multi-draw apply path, and it sat // twenty lines above the function that retired its neighbour. It asked - // `MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect)` and then + // `gPipeInputs->GetBufferBindingSlot(BufferTarget::DrawIndirect)` and then // `EnsureBufferResource()` - a registry lookup keyed by the client's // identity, which is §4.4's rule and not only the allocator's. Under run-ahead that is // `Fatal{UnmigratedPipeInput, "GetBufferBindingSlot@DrawArrays"}` on every batch the @@ -306,7 +306,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { #endif // MONOLITH GLUE from here down, token for token what this function did before. const auto& indirect = - MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!indirect) return 0; const auto* resource = BufferImpl::EnsureBufferResource(indirect); return resource ? resource->id : 0; diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.cpp b/MobileGL/MG_Backend/DirectGLES/Utils.cpp index 2bf0a766..8d866b29 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Utils.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -2366,11 +2366,11 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Config::Transport != MG_Config::TransportMode::Monolith ? SplitReadbackPackBuffer() : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + MG_Pipe::gPipeInputs.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. - const auto packParams = MGB_CTX->GetPixelStoreParameters(false); + const auto packParams = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false); const SizeT rowPixels = static_cast(packParams.RowLength > 0 ? packParams.RowLength : width); const SizeT dstRowStride = AlignReadbackRow(rowPixels * dstPixelBytes, packParams.Alignment); const SizeT imageRows = diff --git a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp index b600d744..f4ade587 100644 --- a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp @@ -12,7 +12,7 @@ #include "SubgroupSupportPolicy.h" #include "MG_State/GLState/FramebufferState/FramebufferObject.h" #include "MG_State/GLState/Core.h" -#include +#include #include "MG_State/GLState/TextureState/TextureState.h" #include "MG_Util/Classifiers/TextureEnumClassifier.h" #include "MG_Util/Converters/MGToGL/TextureEnumConverter.h" @@ -462,8 +462,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } UpdateDynamicBackendParameters(); UpdateAdvertisedExtensions(); - if (MGB_CTX_LIVE) { - MGB_CTX->InvalidateCompileEnv(); + if (MG_Pipe::gPipeInputs.IsLive()) { + MG_Pipe::gPipeInputs.InvalidateCompileEnv(); } PopulateFormatCapabilities(physicalDevice.handle, vkGetPhysicalDeviceFormatProperties, m_vulkanCaps, MutableFormatCapabilities()); @@ -1079,8 +1079,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { m_vulkanCaps = capabilities; UpdateDynamicBackendParameters(); UpdateAdvertisedExtensions(); - if (MGB_CTX_LIVE) { - MGB_CTX->InvalidateCompileEnv(); + if (MG_Pipe::gPipeInputs.IsLive()) { + MG_Pipe::gPipeInputs.InvalidateCompileEnv(); } MutableFormatCapabilities().Clear(); } diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index 385e7ed6..11775400 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -10,7 +10,7 @@ #include "DirectVulkanResourceState.h" #include "MG_Backend/BackendObjects.h" #include "MG_State/GLState/Core.h" -#include +#include #include "MG_State/GLState/ErrorState/ErrorInfo.h" #include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h" #include "MG_Util/Converters/GLToMG/TextureEnumConverter.h" @@ -459,15 +459,15 @@ namespace MobileGL::MG_Backend::DirectVulkan { #endif MG_State::GLState::ProgramObject* TryGetDirectVulkanProgram(GLuint program) { - if (!MGB_CTX->ValidateProgramName(program)) { + if (!MG_Pipe::gPipeInputs.ValidateProgramName(program)) { return nullptr; } - auto& programObject = MGB_CTX->GetProgramObject(program); + auto& programObject = MG_Pipe::gPipeInputs.GetProgramObject(program); return programObject.get(); } const Uint8* ResolveIndirectCommandBytes(const void* indirect, SizeT requiredBytes, const char* label) { - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { drawBuffer->SyncPersistentMappedRange(); // A command block a compute shader wrote is the case this whole shape exists @@ -595,53 +595,53 @@ namespace MobileGL::MG_Backend::DirectVulkan { void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferfi called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearBufferfi called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearBufferfi called with null GL context"); pVulkanRenderer->ClearBufferfi(buffer, drawbuffer, depth, stencil); } void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferfv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearBufferfv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearBufferfv called with null GL context"); pVulkanRenderer->ClearBufferfv(buffer, drawbuffer, value); } void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferuiv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearBufferuiv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearBufferuiv called with null GL context"); pVulkanRenderer->ClearBufferuiv(buffer, drawbuffer, value); } void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearBufferiv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearBufferiv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearBufferiv called with null GL context"); pVulkanRenderer->ClearBufferiv(buffer, drawbuffer, value); } void ClearNamedFramebufferfv(const SharedPtr& framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferfv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearNamedFramebufferfv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearNamedFramebufferfv called with null GL context"); pVulkanRenderer->ClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); } void ClearNamedFramebufferiv(const SharedPtr& framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferiv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearNamedFramebufferiv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearNamedFramebufferiv called with null GL context"); pVulkanRenderer->ClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); } void ClearNamedFramebufferuiv(const SharedPtr& framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferuiv called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearNamedFramebufferuiv called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearNamedFramebufferuiv called with null GL context"); pVulkanRenderer->ClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); } void ClearNamedFramebufferfi(const SharedPtr& framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ClearNamedFramebufferfi called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearNamedFramebufferfi called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ClearNamedFramebufferfi called with null GL context"); pVulkanRenderer->ClearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil); } @@ -653,7 +653,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsIndirect called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawElementsIndirect called with null GL context"); pVulkanRenderer->MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); } void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { @@ -664,7 +664,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirect called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawArraysIndirect called with null GL context"); if (drawcount <= 0) { return; @@ -672,7 +672,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // With a bound GL_DRAW_INDIRECT_BUFFER the command parameters may be GPU-written // (e.g. by a compute shader), so consume them natively on the GPU. - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawArraysIndirect(mode, indirect, drawcount, stride); return; @@ -721,7 +721,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirectCount called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsIndirectCount called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawElementsIndirectCount called with null GL context"); pVulkanRenderer->MultiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount, stride); } void MultiDrawArraysIndirectCount(GLenum mode, const void* indirect, GLintptr drawcount, @@ -733,7 +733,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirectCount called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirectCount called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawArraysIndirectCount called with null GL context"); if (maxdrawcount <= 0) { return; @@ -747,7 +747,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return; } - auto parameterBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto parameterBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); if (!parameterBuffer || drawcount < 0 || static_cast(drawcount) + sizeof(Uint32) > parameterBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawArraysIndirectCount skipped: invalid GL_PARAMETER_BUFFER binding or range"); return; @@ -778,7 +778,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsInstancedBaseVertexBaseInstance called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsInstancedBaseVertexBaseInstance called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawElementsInstancedBaseVertexBaseInstance called with null GL context"); DrawIndexedCmd payload{}; payload.mode = mode; @@ -811,7 +811,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsIndirect called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawElementsIndirect called with null GL context"); const SizeT indexSize = MG_Util::GetGLTypeSize(type); if (indexSize == 0) { @@ -821,7 +821,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // With a bound GL_DRAW_INDIRECT_BUFFER the command parameters may be GPU-written // (e.g. by a compute shader), so consume them natively on the GPU. - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawElementsIndirect(mode, type, indirect, 1, 0); return; @@ -855,7 +855,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArraysInstancedBaseInstance called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArraysInstancedBaseInstance called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawArraysInstancedBaseInstance called with null GL context"); DrawCmd payload{}; payload.mode = mode; @@ -876,11 +876,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArraysIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArraysIndirect called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawArraysIndirect called with null GL context"); // With a bound GL_DRAW_INDIRECT_BUFFER the command parameters may be GPU-written // (e.g. by a compute shader), so consume them natively on the GPU. - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawArraysIndirect(mode, indirect, 1, 0); return; @@ -910,13 +910,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::CopyTexImage2D called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::CopyTexImage2D called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::CopyTexImage2D called with null GL context"); pVulkanRenderer->CopyTexSubImage2D(target, level, 0, 0, x, y, width, height); } void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::CopyTexSubImage2D called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::CopyTexSubImage2D called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::CopyTexSubImage2D called with null GL context"); pVulkanRenderer->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } void CopyImageSubData(const CopyImageEndpoint& src, @@ -925,20 +925,20 @@ namespace MobileGL::MG_Backend::DirectVulkan { GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::CopyImageSubData called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::CopyImageSubData called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::CopyImageSubData called with null GL context"); pVulkanRenderer->CopyImageSubData(src, srcTarget, srcLevel, srcX, srcY, srcZ, dst, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); } void GenerateMipmap(GLenum target) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GenerateMipmap called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::GenerateMipmap called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::GenerateMipmap called with null GL context"); pVulkanRenderer->GenerateMipmap(target); } void DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DispatchCompute called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DispatchCompute called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DispatchCompute called with null GL context"); pVulkanRenderer->DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); } @@ -954,13 +954,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DispatchComputeIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DispatchComputeIndirect called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DispatchComputeIndirect called with null GL context"); pVulkanRenderer->DispatchComputeIndirect(indirect); } void MemoryBarrier(GLbitfield barriers) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MemoryBarrier called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MemoryBarrier called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MemoryBarrier called with null GL context"); pVulkanRenderer->MemoryBarrier(barriers); } @@ -1053,7 +1053,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ? pActiveBackendObject->GetDynamicParameters().MaxShaderStorageBufferBindings : 0; if (storageBlockBinding >= static_cast(maxBindings)) { - MGB_CTX->RecordError( + MG_Pipe::gPipeInputs.RecordError( ErrorCode::InvalidValue, MakeUnique("DirectVulkan", __func__, "Shader storage binding is out of range.")); return; @@ -1100,24 +1100,24 @@ namespace MobileGL::MG_Backend::DirectVulkan { #endif void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::ReadPixels called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ReadPixels called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::ReadPixels called with null GL context"); pVulkanRenderer->ReadPixels(x, y, width, height, format, type, pixels); } void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetTexImage called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::GetTexImage called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::GetTexImage called with null GL context"); pVulkanRenderer->GetTexImage(target, level, format, type, pixels); } void GetTextureImage(const SharedPtr& texture, TextureUploadTarget uploadTarget, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid* pixels) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetTextureImage called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::GetTextureImage called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::GetTextureImage called with null GL context"); pVulkanRenderer->GetTextureImage(texture, uploadTarget, level, format, type, bufSize, pixels); } void Clear(GLbitfield mask) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::Clear called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::Clear called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::Clear called with null GL context"); pVulkanRenderer->Clear(mask); } @@ -1169,7 +1169,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } const Uint8* indexBytes = nullptr; - const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); const auto& indexBufferShared = vao.GetIndexBufferBindingSlot().GetBoundObject(); if (indexBufferShared != nullptr) { const SizeT offset = reinterpret_cast(indices); @@ -1200,7 +1200,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void DrawArrays(GLenum mode, GLint first, GLsizei count) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArrays called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArrays called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawArrays called with null GL context"); if (mode == GL_LINE_LOOP) { if (count < 2) { @@ -1225,7 +1225,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElements called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElements called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawElements called with null GL context"); if (mode == GL_LINE_LOOP) { Vector closedIndices; @@ -1250,7 +1250,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // the next vkCmd* records into a command buffer that is no longer the frame's. Reconciling // HERE, before SetupDraw starts recording, keeps the wait out of the recording. if (MG_Config::Transport == MG_Config::TransportMode::Monolith) { - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); Bool clientArray = false; if (currentVAO) { for (const auto& attribute : currentVAO->GetAllAttributes()) { @@ -1272,7 +1272,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void MultiDrawArrays(GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArrays called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArrays called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawArrays called with null GL context"); if (drawcount <= 0) { return; } @@ -1321,10 +1321,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { #if MOBILEGL_BUILD_DISAGGREGATED const Bool noIndexBuffer = MG_Config::Transport != MG_Config::TransportMode::Monolith ? MG_Pipe::MGPipeHandleIsNull(MG_Pipe::MGPipeApplier().IndexBuffer.Res) - : MGB_CTX->GetBoundVertexArray()->GetIndexBufferBindingSlot().GetBoundObject() == nullptr; + : MG_Pipe::gPipeInputs.GetBoundVertexArray()->GetIndexBufferBindingSlot().GetBoundObject() == nullptr; if (noIndexBuffer) { #else - const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); if (vao.GetIndexBufferBindingSlot().GetBoundObject() == nullptr) { #endif for (GLsizei i = 0; i < drawcount; ++i) { @@ -1386,13 +1386,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei drawcount) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElements called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElements called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawElements called with null GL context"); MultiDrawElementsImpl(mode, count, type, indices, drawcount, nullptr); } void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsBaseVertex called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsBaseVertex called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::DrawElementsBaseVertex called with null GL context"); if (mode == GL_LINE_LOOP) { Vector closedIndices; if (BuildClosedLineLoopIndices(count, type, indices, closedIndices)) { @@ -1416,14 +1416,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, GLsizei drawcount, const GLint* basevertex) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsBaseVertex called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsBaseVertex called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::MultiDrawElementsBaseVertex called with null GL context"); MultiDrawElementsImpl(mode, count, type, indices, drawcount, basevertex); } void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::BlitFramebuffer called with null VulkanRenderer"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::BlitFramebuffer called with null GL context"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "DirectVulkan::BlitFramebuffer called with null GL context"); pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } @@ -1660,8 +1660,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { #if MOBILEGL_BUILD_DISAGGREGATED MG_Config::Transport == MG_Config::TransportMode::Monolith && #endif - MGB_CTX_LIVE) { - primitives += MGB_CTX->GetTransformFeedbackPausedPrimitiveCounter() - + MG_Pipe::gPipeInputs.IsLive()) { + primitives += MG_Pipe::gPipeInputs.GetTransformFeedbackPausedPrimitiveCounter() - query->pausedPrimitiveSnapshot; } *outNanoseconds = primitives; @@ -1711,7 +1711,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { #if MOBILEGL_BUILD_DISAGGREGATED MG_Config::Transport == MG_Config::TransportMode::Monolith && #endif - MGB_CTX_LIVE ? MGB_CTX->GetTransformFeedbackPausedPrimitiveCounter() : 0; + MG_Pipe::gPipeInputs.IsLive() ? MG_Pipe::gPipeInputs.GetTransformFeedbackPausedPrimitiveCounter() : 0; // Read AFTER StartXfbQueryCapture, which is where a failed reroute-pool creation // disarms: the answer is then what this span will actually do for every draw. query->pausedPrimitivesCountedByGpu = generated && pVulkanRenderer->ArePausedDrawsGpuCounted(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp index 06c7d40a..2222bf94 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp @@ -11,7 +11,7 @@ #include "MG_Backend/DirectVulkan/DirectVulkanResourceState.h" #include "MG_State/GLState/Core.h" -#include +#include // P5c ev: the GPU-write announcement routes through the reverse channel (R2). #include #include "MG_State/GLState/ProgramState/ProgramObject.h" @@ -946,7 +946,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // alive through the draw via GL binding state. Only the fallback path needs a SharedPtr to // keep the fallback texture alive for the rest of this call. MG_State::GLState::ITextureObject* texture = ResolveSamplerTextureRaw(program, programObj, binding, element); - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); const auto& samplerOverride = textureUnit.GetSamplerObject(); const auto preferredTarget = programObj.samplerTextureTargetByBinding[binding]; SharedPtr fallbackHolder; @@ -995,7 +995,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } if (!IsValidSampledImageLayout(resource->layout)) { - auto drawFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + auto drawFbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); FramebufferAttachmentType attachmentType = FramebufferAttachmentType::None; Int attachmentLevel = 0; if (drawFbo && @@ -1225,7 +1225,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // filtering - which a single-level view can still have. Resolve the sampler exactly // the way ResolveSamplerDescriptor does and bail if anisotropy would apply. const Int unit = ResolveSamplerUnitIndex(program, location, binding); - const auto& samplerOverride = MGB_CTX->GetTextureUnitObject(unit).GetSamplerObject(); + const auto& samplerOverride = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit).GetSamplerObject(); const auto* effectiveSampler = samplerOverride ? samplerOverride.get() : texture->GetSamplerObject().get(); if (effectiveSampler == nullptr) return false; @@ -1255,7 +1255,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const ProgramFactory::VkProgramObject& programObj, Uint32 binding, SharedPtr& outTexture) { outTexture.reset(); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveSamplerTexture: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveSamplerTexture: GL context is null"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), "ResolveSamplerTexture: sampler location binding %u out of range", binding); MOBILEGL_ASSERT(binding < programObj.samplerTextureTargetByBinding.size(), @@ -1264,7 +1264,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const Int location = programObj.samplerUniformLocationByBinding[binding]; const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding]; outTexture = textureUnit.GetBindingSlot(preferredTarget).GetBoundObject(); // The slot always holds at least the target's default texture (name 0). While that @@ -1280,7 +1280,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MG_State::GLState::ITextureObject* UniformManager::ResolveSamplerTextureRaw( const MagmaProgramSource& program, const ProgramFactory::VkProgramObject& programObj, Uint32 binding, Uint32 element) { - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveSamplerTextureRaw: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveSamplerTextureRaw: GL context is null"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), "ResolveSamplerTextureRaw: sampler location binding %u out of range", binding); MOBILEGL_ASSERT(binding < programObj.samplerTextureTargetByBinding.size(), @@ -1290,7 +1290,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ResolveDescriptorElementLocation(program, programObj.samplerUniformLocationByBinding[binding], element); const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding]; // GetBoundObject() returns the SharedPtr by const ref; .get() reads the pointer without // touching the refcount (no atomic inc/dec per binding per draw). @@ -1547,7 +1547,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { #endif outBufferView = VK_NULL_HANDLE; MOBILEGL_ASSERT(m_bufferManager != nullptr, "ResolveStorageTexelBufferDescriptor: buffer manager is null"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageTexelBufferDescriptor: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveStorageTexelBufferDescriptor: GL context is null"); MOBILEGL_ASSERT(frameIndex < m_frames.size(), "ResolveStorageTexelBufferDescriptor: frame index out of range"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), @@ -1571,7 +1571,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MOBILEGL_ASSERT(binding < programObj.samplerNumericDomainByBinding.size(), "ResolveStorageTexelBufferDescriptor: numeric domain binding %u out of range", binding); - auto& imageBinding = MGB_CTX->GetImageTextureBinding(imageUnit); + auto& imageBinding = MG_Pipe::gPipeInputs.GetImageTextureBinding(imageUnit); const auto& texture = imageBinding.Texture; if (texture == nullptr) { // An image unit with no texture on it is legal GL (4.6 core 8.26): loads return zero @@ -1709,7 +1709,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkDescriptorBufferInfo& outBufferInfo) const { outBufferInfo = {}; MOBILEGL_ASSERT(m_bufferManager != nullptr, "ResolveStorageBufferDescriptor: buffer manager is null"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageBufferDescriptor: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveStorageBufferDescriptor: GL context is null"); MOBILEGL_ASSERT(binding < programObj.storageBlockIndexByBinding.size(), "ResolveStorageBufferDescriptor: binding %u out of range", binding); #if MOBILEGL_BUILD_DISAGGREGATED @@ -1837,12 +1837,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { } #endif const Uint32 bindingPointCount = - static_cast(MGB_CTX->GetBufferBindingPointCount(bufferTarget)); + static_cast(MG_Pipe::gPipeInputs.GetBufferBindingPointCount(bufferTarget)); MOBILEGL_ASSERT(frontendBinding < bindingPointCount, "ResolveStorageBufferDescriptor: frontend binding %u out of range for block '%s'", frontendBinding, blockName.c_str()); - auto& bindingPoint = MGB_CTX->GetBufferBindingPoint(bufferTarget, frontendBinding); + auto& bindingPoint = MG_Pipe::gPipeInputs.GetBufferBindingPoint(bufferTarget, frontendBinding); const auto& bufferObject = bindingPoint.GetBoundObject(); if (bufferObject == nullptr) { // NOT an error, and above all not a reason to lose the draw. GL 4.6 core 7.8 lets a @@ -1919,7 +1919,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { #endif outImageInfo = {}; MOBILEGL_ASSERT(m_textureManager != nullptr, "ResolveStorageImageDescriptor: texture manager is null"); - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageImageDescriptor: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveStorageImageDescriptor: GL context is null"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), "ResolveStorageImageDescriptor: binding %u out of range", binding); @@ -1948,7 +1948,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } - auto& imageBinding = MGB_CTX->GetImageTextureBinding(imageUnit); + auto& imageBinding = MG_Pipe::gPipeInputs.GetImageTextureBinding(imageUnit); if (imageBinding.Texture == nullptr) { // Legal GL: an image unit with no texture bound makes loads return zero and discards // stores (4.6 core 8.26). It is not a reason to lose the draw, which is what returning @@ -2304,7 +2304,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Open-coded ResolveSamplerTextureRaw so the unit is resolved once for both the // texture and the sampler override - this runs per binding per full-path draw, // and program-alternating draw streams take the full path on every draw. - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveSampledBinding: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveSampledBinding: GL context is null"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), "ResolveSampledBinding: sampler location binding %u out of range", binding); MOBILEGL_ASSERT(binding < programObj.samplerTextureTargetByBinding.size(), @@ -2315,7 +2315,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(unit); const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding]; MG_State::GLState::ITextureObject* texture = textureUnit.GetBindingSlot(preferredTarget).GetBoundObject().get(); @@ -2468,7 +2468,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (program.IsWire()) { outTextures.clear(); return true; } #endif outTextures.clear(); - MOBILEGL_ASSERT(MGB_CTX_LIVE, + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "CollectStorageImageTextures: GL context is null"); // Same as the sampled walk: a declined program is refused at bind time, and its declined // binding has no uniform location to reach an image unit through. @@ -2512,7 +2512,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } - auto* texture = MGB_CTX->GetImageTextureBinding(imageUnit).Texture.get(); + auto* texture = MG_Pipe::gPipeInputs.GetImageTextureBinding(imageUnit).Texture.get(); if (texture == nullptr) { // ResolveStorageImageDescriptor will substitute the placeholder image for this // binding; include it here for the same reason the sampled walk includes the @@ -2553,7 +2553,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (program.IsWire()) { outBindings.clear(); return true; } #endif outBindings.clear(); - MOBILEGL_ASSERT(MGB_CTX_LIVE, + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "CollectSamplerImageFeedback: GL context is null"); if (programObj.declinedDescriptors) return true; @@ -2603,7 +2603,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (imageUnit < 0 || imageUnit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) { return false; } - const auto& image = MGB_CTX->GetImageTextureBinding(imageUnit); + const auto& image = MG_Pipe::gPipeInputs.GetImageTextureBinding(imageUnit); // A sampler view exposes all layers of its target; equal texture plus an // overlapping mip therefore aliases the writable image subresource. if (image.Texture.get() == sampledTexture && @@ -2730,7 +2730,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const void* outData = nullptr; VkDeviceSize outSize = 0; - MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveUniformBufferPayload: GL context is null"); + MOBILEGL_ASSERT(MG_Pipe::gPipeInputs.IsLive(), "ResolveUniformBufferPayload: GL context is null"); MOBILEGL_ASSERT(binding < programObj.bindingKinds.size(), "ResolveUniformBufferPayload: binding %u out of range", binding); MOBILEGL_ASSERT(programObj.bindingKinds[binding] == ProgramFactory::DescriptorBindingKind::UniformBufferDynamic, @@ -2787,12 +2787,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { return ResolveWireUniformBufferPayload(program, static_cast(blockIndex), frontendBinding, out); #endif const Uint32 uniformBindingPointCount = - static_cast(MGB_CTX->GetBufferBindingPointCount(BufferTarget::Uniform)); + static_cast(MG_Pipe::gPipeInputs.GetBufferBindingPointCount(BufferTarget::Uniform)); MOBILEGL_ASSERT(frontendBinding < uniformBindingPointCount, "ResolveUniformBufferPayload: frontend UBO binding %u out of range for block '%s'", frontendBinding, program.GetUniformBlockName(static_cast(blockIndex)).c_str()); - auto& bindingPoint = MGB_CTX->GetBufferBindingPoint(BufferTarget::Uniform, frontendBinding); + auto& bindingPoint = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::Uniform, frontendBinding); const auto& bufferObject = bindingPoint.GetBoundObject(); static thread_local Vector paddedUbo; if (bufferObject == nullptr) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp index 744f1e85..fee95ad2 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -13,7 +13,7 @@ #include "VkTextureManager.h" #include "MG_State/GLState/Core.h" -#include +#include #include "MG_Util/Converters/MGToStr/FramebufferEnumConverter.h" #include "MG_Util/Converters/MGToStr/TextureEnumConverter.h" @@ -55,7 +55,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (payload.colorEncoding != ClearColorEncoding::Float) return; // With GL_FRAMEBUFFER_SRGB enabled GL performs the encoding itself, so the driver doing it // is exactly right and there is nothing to undo. - if (MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)) return; + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)) return; if (ResolveSrgbAttachmentWriteFormat(destinationFormat, false) == destinationFormat) return; // sRGB -> linear (GL 4.6 core 8.24), applied to the colour channels only: alpha is stored diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp index 56402ede..73a875d2 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp @@ -15,7 +15,7 @@ #include "MG_Util/Converters/MGToStr/FramebufferEnumConverter.h" #include "MG_Util/Converters/MGToVk/TextureEnumConverter.h" #include "MG_Util/Metrics/TextureMetrics.h" -#include +#include namespace MobileGL::MG_Backend::DirectVulkan { static Bool TryResolveSampleCountFlagBits(Int requestedSamples, VkSampleCountFlagBits& outSampleCount) { @@ -614,7 +614,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // sRGB attachments switch between their sRGB and UNORM-twin views with this // capability (ResolveSrgbAttachmentWriteFormat), changing the render pass formats. const Bool framebufferSrgbEnabled = - MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); XXHASH_VERIFY(XXH64_update(m_hashState, &framebufferSrgbEnabled, sizeof(framebufferSrgbEnabled))); auto& drawBuffers = fbo.GetDrawBuffers(); XXHASH_VERIFY(XXH64_update(m_hashState, drawBuffers.data(), drawBuffers.size() * sizeof(drawBuffers[0]))); @@ -966,7 +966,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const VkImageLayout trackedRbLayout = rbResource->layout; const Bool rbFramebufferSrgb = - MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); const VkFormat rbAttachmentFormat = ResolveSrgbAttachmentWriteFormat(rbResource->format, rbFramebufferSrgb); rbDesc.flags = 0; @@ -1112,7 +1112,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { textureResources.emplace_back(textureResource); desc.format = ResolveSrgbAttachmentWriteFormat( textureResource->format, - MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)); attachmentSampleCount = textureResource->sampleCount; trackedColorLayout = textureResource->layout; trackedAttachmentLayouts.emplace_back(TrackedAttachmentLayoutInfo { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp index 98fcd886..b611c3a0 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -12,7 +12,7 @@ #include "ProgramFactory.h" #include "MG_State/GLState/Core.h" -#include +#include #include "MG_Util/Converters/MGToStr/TextureEnumConverter.h" #include "MG_Util/Converters/MGToVk/TextureEnumConverter.h" #include "MG_Util/Metrics/PipeStats.h" @@ -873,7 +873,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // sampled-texture sync scan the entire alive-texture map per draw. if (aliveIt == m_aliveObjects.end()) { WeakPtr aliveTexture; - const auto& liveTexture = MGB_CTX->GetTextureObject(texture.GetExternalIndex()); + const auto& liveTexture = MG_Pipe::gPipeInputs.GetTextureObject(texture.GetExternalIndex()); if (liveTexture && liveTexture.get() == &texture) { aliveTexture = liveTexture; } else { @@ -1016,7 +1016,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } const Bool framebufferSrgbEnabled = - MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); const VkFormat baseAttachmentFormat = viewFormatOverride != VK_FORMAT_UNDEFINED ? viewFormatOverride : resource->format; const VkFormat attachmentFormat = diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index a7886223..f8ca412c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -18,7 +18,7 @@ #include "VertexInputStateBuilder.h" #include "MG_State/GLState/Core.h" -#include +#include // P5c ev: the GPU-write announcement routes through the reverse channel (R2). #include #include "MG_State/GLState/ProgramState/ProgramObject.h" @@ -596,12 +596,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { // round trip), which is why the honest-but-lossy path was kept over widening every // default-framebuffer Y-flip/pre-transform helper to floats. See the KNOWN INFIDELITY // note in MG_IntegrationTest/Scenarios/AdvertisedLimitsScenario.cpp. - const FloatVec4& stored = MGB_CTX->GetViewportIndexed(index); + const FloatVec4& stored = MG_Pipe::gPipeInputs.GetViewportIndexed(index); const IntVec4 viewportState(static_cast(std::lround(stored.x())), static_cast(std::lround(stored.y())), static_cast(std::lround(stored.z())), static_cast(std::lround(stored.w()))); - const FloatVec2& depthRange = MGB_CTX->GetDepthRangeIndexed(index); + const FloatVec2& depthRange = MG_Pipe::gPipeInputs.GetDepthRangeIndexed(index); const IntVec2 logicalExtent = isDefaultFramebuffer ? ResolveDefaultFramebufferLogicalExtent(preTransform, framebufferExtent) : framebufferExtent; @@ -656,7 +656,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyBlendConstants(VkCommandBuffer commandBuffer) { - const FloatVec4& blendColor = MGB_CTX->GetBlendColor(); + const FloatVec4& blendColor = MG_Pipe::gPipeInputs.GetBlendColor(); const float blendConstants[4] = { blendColor.x(), blendColor.y(), @@ -689,8 +689,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyPolygonOffsetState(VkCommandBuffer commandBuffer) { - const Float constantFactor = MGB_CTX->GetPolygonOffsetUnits(); - const Float slopeFactor = MGB_CTX->GetPolygonOffsetFactor(); + const Float constantFactor = MG_Pipe::gPipeInputs.GetPolygonOffsetUnits(); + const Float slopeFactor = MG_Pipe::gPipeInputs.GetPolygonOffsetFactor(); auto& shadow = *g_dynamicStateShadow; if (shadow.depthBiasValid && shadow.depthBiasConstantFactor == constantFactor && shadow.depthBiasSlopeFactor == slopeFactor) { @@ -703,7 +703,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyLineWidthState(VkCommandBuffer commandBuffer) { - Float lineWidth = MGB_CTX->GetLineWidth(); + Float lineWidth = MG_Pipe::gPipeInputs.GetLineWidth(); #if MOBILEGL_BUILD_DISAGGREGATED // P5c (hd, CONTRACT-P5C §3.7): with an active transport the dynamic parameters are the // SERVER's own backend's - the client caps mirror is client memory (rule E). Monolith @@ -806,8 +806,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyStencilState(VkCommandBuffer commandBuffer) { - const StencilFaceState& frontStencil = MGB_CTX->GetStencilState(StencilFace::Front); - const StencilFaceState& backStencil = MGB_CTX->GetStencilState(StencilFace::Back); + const StencilFaceState& frontStencil = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front); + const StencilFaceState& backStencil = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Back); const Uint32 frontReference = static_cast(std::max(frontStencil.Ref, 0)); const Uint32 backReference = static_cast(std::max(backStencil.Ref, 0)); @@ -1400,11 +1400,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void RecordClearBufferError(const char* func, ErrorCode code, const char* message) { - MGB_CTX->RecordError(code, MakeUnique("DirectVulkan", func, message)); + MG_Pipe::gPipeInputs.RecordError(code, MakeUnique("DirectVulkan", func, message)); } static void RecordTextureCopyError(const char* func, ErrorCode code, const char* message) { - MGB_CTX->RecordError(code, MakeUnique("DirectVulkan", func, message)); + MG_Pipe::gPipeInputs.RecordError(code, MakeUnique("DirectVulkan", func, message)); } static Bool HasDistinctCompleteDepthStencilTextureAttachments( @@ -1460,7 +1460,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void RecordUnsupportedFramebufferError(const char* func) { - MGB_CTX->RecordError( + MG_Pipe::gPipeInputs.RecordError( ErrorCode::InvalidFramebufferOperation, MakeUnique( "DirectVulkan", func, @@ -3000,7 +3000,7 @@ void main() { // glReadPixels final conversion: GL_CLAMP_READ_COLOR defaults to GL_FIXED_ONLY, // clamping fixed-point (normalized) buffers to [0,1] - visible for SNORM reads. if (applyReadColorClamp && wideType == GL_FLOAT) { - const GLenum clampMode = MGB_CTX->GetClampReadColor(); + const GLenum clampMode = MG_Pipe::gPipeInputs.GetClampReadColor(); const Bool clamp = clampMode == GL_TRUE || (clampMode == GL_FIXED_ONLY && !IsFloatingPointReadbackFormat(srcFormat)); if (clamp) { @@ -3223,11 +3223,11 @@ void main() { const Bool wire = MG_Config::Transport != MG_Config::TransportMode::Monolith; const auto* wireFbo = wire ? MG_Pipe::MGPipeApplier().DrawFramebuffer() : nullptr; const auto currentDrawFBO = wire ? SharedPtr{} : - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); const Bool isDefault = wire ? (wireFbo && wireFbo->IsDefault) : (currentDrawFBO && currentDrawFBO->IsDefaultFramebuffer()); #else - const auto& currentDrawFBO = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + const auto& currentDrawFBO = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); const Bool isDefault = currentDrawFBO != nullptr && currentDrawFBO->IsDefaultFramebuffer(); #endif if (isDefault) { @@ -3732,8 +3732,8 @@ void main() { // with restart off it is a legitimate index and excluding it would truncate the // converted stream by exactly that vertex. const Bool primitiveRestartActive = - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); const Uint32 restartSentinel = indexSize == 1 ? 0xFFu : indexSize == 2 ? 0xFFFFu : 0xFFFFFFFFu; Uint32 maxIndex = 0; Bool sawIndex = false; @@ -4307,7 +4307,7 @@ void main() { } const auto glType = programObj.vertexInputTypes[location]; - const auto& currentValue = MGB_CTX->GetCurrentVertexAttribute(location); + const auto& currentValue = MG_Pipe::gPipeInputs.GetCurrentVertexAttribute(location); VkFormat format = VK_FORMAT_UNDEFINED; const void* sourceData = nullptr; VkDeviceSize sourceSize = 0; @@ -4441,7 +4441,7 @@ void main() { Bool substituteRestart = false; // One bulk parameters fetch instead of up to three accessor calls per indexed // draw; all three inputs are pure reads of these fields. - const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); + const RenderStateParameters& rsp = MG_Pipe::gPipeInputs.GetRenderStateParameters(); if (rsp.PrimitiveRestartEnabled && !rsp.PrimitiveRestartFixedIndexEnabled) { const Uint32 restartIndex = rsp.PrimitiveRestartIndex; const Uint32 fixedMax = MG_Util::FixedRestartIndexForGLType(pIndexBufferView->indexType); @@ -5297,9 +5297,9 @@ void main() { Uint32 VulkanRenderer::ResolveEffectiveSampleMask(VkSampleCountFlagBits rasterizationSamples) const { constexpr Uint32 kFullCoverage = 0xffffffffu; if (rasterizationSamples == VK_SAMPLE_COUNT_1_BIT) return kFullCoverage; - if (!MGB_CTX->IsCapabilityEnabled(CapabilityInput::Multisample)) return kFullCoverage; - if (!MGB_CTX->IsCapabilityEnabled(CapabilityInput::SampleMask)) return kFullCoverage; - return MGB_CTX->GetRenderStateParameters().SampleMaskValue; + if (!MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::Multisample)) return kFullCoverage; + if (!MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::SampleMask)) return kFullCoverage; + return MG_Pipe::gPipeInputs.GetRenderStateParameters().SampleMaskValue; } @@ -5314,7 +5314,7 @@ void main() { // // Only reached with no render-state CSO bound, and only in a build with no pre-handle // arm to fall back to instead. - return MG_Pipe::MGPipeComputePipelineSubsetHash(MGB_CTX->GetRenderStateParameters()); + return MG_Pipe::MGPipeComputePipelineSubsetHash(MG_Pipe::gPipeInputs.GetRenderStateParameters()); } // A program that runs a geometry shader AND captures transform feedback. Both halves are @@ -5346,7 +5346,7 @@ void main() { if (!(aspects & DrawSetupAspect::IndexBuffer) || pIndexBufferView == nullptr) { return false; } - const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); + const RenderStateParameters& rsp = MG_Pipe::gPipeInputs.GetRenderStateParameters(); if (rsp.PrimitiveRestartFixedIndexEnabled) { return true; } @@ -5422,7 +5422,7 @@ void main() { // the VALUE hash of that subset, never the version itself: the version is monotonic, so // per-draw state flips (GL_BLEND toggles) would otherwise miss entries the memo holds. // The version only guards recomputing the hash - unchanged version, unchanged bytes. - const Uint renderStateVersion = MGB_CTX->GetPipelineStateVersion(); + const Uint renderStateVersion = MG_Pipe::gPipeInputs.GetPipelineStateVersion(); // P2 D12.1. Non-null means the client's render-state CSO handle is this draw's state // key and the hash below is not computed at all; null means the pre-handle arm. The // two arms' entries can never match each other: the handle arm stores hash 0 and a @@ -5617,16 +5617,16 @@ void main() { syntheticVertexInputState.pNext = vis.state.pNext; pipelineVertexInputState = &syntheticVertexInputState; } - auto cullFaceEnabled = MGB_CTX->IsCapabilityEnabled(CapabilityInput::CullFace); - auto depthTestEnabled = MGB_CTX->IsCapabilityEnabled(CapabilityInput::DepthTest); + auto cullFaceEnabled = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::CullFace); + auto depthTestEnabled = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::DepthTest); auto polygonOffsetFillEnabled = - MGB_CTX->IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) && + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) && DrawModeUsesPolygonFill(mode); auto rasterizerDiscardEnabled = - MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::RasterizerDiscard); auto colorLogicOpEnabled = - MGB_CTX->IsCapabilityEnabled(CapabilityInput::ColorLogicOp) && m_logicOpFeatureEnabled; - auto stencilTestEnabled = MGB_CTX->IsCapabilityEnabled(CapabilityInput::StencilTest); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ColorLogicOp) && m_logicOpFeatureEnabled; + auto stencilTestEnabled = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::StencilTest); // A framebuffer without a depth (stencil) attachment behaves as if the depth // (stencil) test always passes and nothing is written - even when the bound // image is a packed depth-stencil texture attached through only one half. @@ -5642,7 +5642,7 @@ void main() { #endif { const auto& gatingFbo = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (gatingFbo != nullptr && !gatingFbo->IsDefaultFramebuffer()) { const auto& depthAtt = gatingFbo->GetAttachment(MobileGL::FramebufferAttachmentType::Depth); const auto& stencilAtt = gatingFbo->GetAttachment(MobileGL::FramebufferAttachmentType::Stencil); @@ -5655,10 +5655,10 @@ void main() { } } } - const StencilFaceState& frontStencil = MGB_CTX->GetStencilState(StencilFace::Front); - const StencilFaceState& backStencil = MGB_CTX->GetStencilState(StencilFace::Back); + const StencilFaceState& frontStencil = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front); + const StencilFaceState& backStencil = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Back); const VkPolygonMode requestedPolygonMode = - MG_Util::ConvertPolygonModeToVkEnum(MGB_CTX->GetPolygonModeFront()); + MG_Util::ConvertPolygonModeToVkEnum(MG_Pipe::gPipeInputs.GetPolygonModeFront()); // VK_POLYGON_MODE_LINE/_POINT require the fillModeNonSolid device feature; fall back to // VK_POLYGON_MODE_FILL when the device lacks it. const VkPolygonMode effectivePolygonMode = @@ -5746,18 +5746,18 @@ void main() { // driver's own rate. Both halves move the render state's PIPELINE version, so a cached // pipeline built at the old rate cannot be handed back for the new one. .sampleShadingEnable = m_sampleRateShadingFeatureEnabled && - MGB_CTX->IsCapabilityEnabled(CapabilityInput::SampleShading), - .minSampleShading = MGB_CTX->GetMinSampleShadingValue(), + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::SampleShading), + .minSampleShading = MG_Pipe::gPipeInputs.GetMinSampleShadingValue(), // Word 1 keeps its all-ones initialiser: GL has no state for samples 32..63. .sampleMask = {ResolveEffectiveSampleMask(renderPassEntry.sampleCount), 0xffffffffu}, .subpass = 0, .topology = vkTopology, .primitiveRestartEnable = primitiveRestartEnabled, - .patchControlPoints = static_cast(MGB_CTX->GetPatchVertices()), + .patchControlPoints = static_cast(MG_Pipe::gPipeInputs.GetPatchVertices()), .viewportCount = ResolveDrawViewportCount(programObj.writesViewportIndexBuiltin), .polygonMode = effectivePolygonMode, .cullMode = cullFaceEnabled - ? MG_Util::ConvertCullFaceModeToVkEnum(MGB_CTX->GetCullFaceMode(), invertClockwise) + ? MG_Util::ConvertCullFaceModeToVkEnum(MG_Pipe::gPipeInputs.GetCullFaceMode(), invertClockwise) : VK_CULL_MODE_NONE, .frontFace = VK_FRONT_FACE_CLOCKWISE, // Read the geometry stage off the program's own shader list rather than @@ -5771,13 +5771,13 @@ void main() { .provokingVertexMode = SelectProvokingVertexMode( vkTopology, ProgramCapturesXfbFromGeometryStage(program)), .depthTestEnable = depthTestEnabled, - .depthWriteEnable = depthTestEnabled && MGB_CTX->GetDepthMask(), + .depthWriteEnable = depthTestEnabled && MG_Pipe::gPipeInputs.GetDepthMask(), .depthBiasEnable = polygonOffsetFillEnabled, .rasterizerDiscardEnable = rasterizerDiscardEnabled, .logicOpEnable = colorLogicOpEnabled, .stencilTestEnable = stencilTestEnabled, - .depthCompareOp = MG_Util::ConvertDepthTestFuncToVkEnum(MGB_CTX->GetDepthFunc()), - .logicOp = MG_Util::ConvertLogicOperationToVkEnum(MGB_CTX->GetLogicOp()), + .depthCompareOp = MG_Util::ConvertDepthTestFuncToVkEnum(MG_Pipe::gPipeInputs.GetDepthFunc()), + .logicOp = MG_Util::ConvertLogicOperationToVkEnum(MG_Pipe::gPipeInputs.GetLogicOp()), .frontStencilFailOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.FailOp), .frontStencilPassOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.PassDepthPassOp), .frontStencilDepthFailOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.PassDepthFailOp), @@ -5813,8 +5813,8 @@ void main() { // handed back after the application changed them. if (programObj.needsPassthroughTessControl && programObj.passthroughTessControlEmulatable && vkTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { - const FloatVec4& defaultOuterLevel = MGB_CTX->GetPatchDefaultOuterLevel(); - const FloatVec2& defaultInnerLevel = MGB_CTX->GetPatchDefaultInnerLevel(); + const FloatVec4& defaultOuterLevel = MG_Pipe::gPipeInputs.GetPatchDefaultOuterLevel(); + const FloatVec2& defaultInnerLevel = MG_Pipe::gPipeInputs.GetPatchDefaultInnerLevel(); payload.passthroughTessControlKey = ProgramFactory::ComputePassthroughTessControlKey( payload.patchControlPoints, defaultOuterLevel, defaultInnerLevel, programObj.passthroughPerVertexMembers); @@ -5869,10 +5869,10 @@ void main() { const auto* wireFbo = MG_Config::Transport != MG_Config::TransportMode::Monolith ? MG_Pipe::MGPipeApplier().DrawFramebuffer() : nullptr; const auto drawFboBinding = wireFbo ? SharedPtr{} : - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); #else const auto& drawFboBinding = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); #endif #if MOBILEGL_BUILD_DISAGGREGATED MOBILEGL_ASSERT(wireFbo != nullptr || drawFboBinding != nullptr, "GetOrCreatePipeline: draw framebuffer is null"); @@ -5917,14 +5917,14 @@ void main() { BlendFactor dstAlpha = BlendFactor::Zero; BlendEquation colorEquation = BlendEquation::Add; BlendEquation alphaEquation = BlendEquation::Add; - MGB_CTX->GetBlendFuncIndexed(i, srcRGB, dstRGB, srcAlpha, dstAlpha); - MGB_CTX->GetBlendEquationIndexed(i, colorEquation, alphaEquation); - const Bool blendEnabled = MGB_CTX->IsCapabilityEnabledIndexed(CapabilityInput::Blend, i); + MG_Pipe::gPipeInputs.GetBlendFuncIndexed(i, srcRGB, dstRGB, srcAlpha, dstAlpha); + MG_Pipe::gPipeInputs.GetBlendEquationIndexed(i, colorEquation, alphaEquation); + const Bool blendEnabled = MG_Pipe::gPipeInputs.IsCapabilityEnabledIndexed(CapabilityInput::Blend, i); // Per-draw-buffer color write mask (glColorMaski). Divergent per-attachment masks require // the independentBlend device feature; when it is absent, fall back to draw buffer 0's // mask for every attachment (matching the non-indexed glColorMask broadcast). const BoolVec4 bufferMask = - MGB_CTX->GetColorMaskIndexed(m_independentBlendFeatureEnabled ? i : 0); + MG_Pipe::gPipeInputs.GetColorMaskIndexed(m_independentBlendFeatureEnabled ? i : 0); VkColorComponentFlags attachmentColorWriteMask = static_cast( (bufferMask.r() ? VK_COLOR_COMPONENT_R_BIT : 0u) | (bufferMask.g() ? VK_COLOR_COMPONENT_G_BIT : 0u) | @@ -6375,7 +6375,7 @@ void main() { VkRect2D VulkanRenderer::ComputeGLScissorRect(Uint32 index, const IntVec2& extent, VkSurfaceTransformFlagBitsKHR preTransform, Bool isDefaultFbo) const { - const auto& parameters = MGB_CTX->GetRenderStateParameters(); + const auto& parameters = MG_Pipe::gPipeInputs.GetRenderStateParameters(); if ((parameters.ScissorTestEnabledMask & (1u << index)) == 0) { VkRect2D full{}; full.offset = {0, 0}; @@ -6451,7 +6451,7 @@ void main() { // counter still would make Espryt skip re-syncing the blend state it just changed. // The second-level DynamicTailKey compare below is therefore what actually absorbs a // pipeline-only change, exactly as it did before P2: one key build, no vkCmd*. - const Uint paramsVersion = MGB_CTX->GetRenderStateParametersVersion(); + const Uint paramsVersion = MG_Pipe::gPipeInputs.GetRenderStateParametersVersion(); if (shadow.dynamicTailValid && shadow.dynamicTailParamsVersion == paramsVersion && shadow.dynamicTailExtentX == extent.x() && shadow.dynamicTailExtentY == extent.y() && shadow.dynamicTailIsDefaultFbo == isDefaultFbo) { @@ -6475,7 +6475,7 @@ void main() { // re-derive the value its shadow already holds. DynamicStateShadow::DynamicTailKey key; { - const RenderStateParameters& p = MGB_CTX->GetRenderStateParameters(); + const RenderStateParameters& p = MG_Pipe::gPipeInputs.GetRenderStateParameters(); // Viewport 0 and its depth range: ApplyGLViewportState reads exactly those two // (per-index state for indices > 0 is keyed separately, see multiViewportKey below). key.viewport[0] = p.Viewports[0].x(); @@ -6557,7 +6557,7 @@ void main() { } #endif const auto& fbo = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); return isDefaultFbo == (fbo != nullptr && fbo->IsDefaultFramebuffer()); }(), "GetBaseTransformFlagsRaw: isDefaultFbo does not match the bound draw framebuffer"); @@ -6581,7 +6581,7 @@ void main() { // Entry select: by the draw program's lifetime id, MRU first (the id pins // the entry; every other fact is re-guarded below, so probing a stale // entry can only decline, never serve stale state). - const auto& program = *MGB_CTX->GetProgramForDraw(); + const auto& program = *MG_Pipe::gPipeInputs.GetProgramForDraw(); const Uint64 programLifetimeId = program.GetLifetimeId(); SetupDrawSnapshot* snapPtr = nullptr; { @@ -6629,7 +6629,7 @@ void main() { // captured draw after glBeginTransformFeedback would bind the undecorated // variant and silently capture nothing while the CPU bookkeeping advances. const Bool wantsXfbCapture = m_transformFeedbackFeatureEnabled && - MGB_CTX->IsTransformFeedbackActive() && + MG_Pipe::gPipeInputs.IsTransformFeedbackActive() && program.GetTransformFeedbackVaryingCount() > 0; const Bool snapHasXfbCapture = static_cast(ProgramFactory::CompileOptionFlags(snap.resolvedTransformFlags) & @@ -6643,7 +6643,7 @@ void main() { // buffer binds (re-run every draw anyway). Declining here would send every // draw of a VAO-cycling stream (Minecraft chunk rendering) through the full // path, re-resolving descriptors and texture layouts nothing invalidated. - const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); // P2 D12.4: the handle replaces the (address, lifetime id) pair here too - one // compare instead of two, and the same identity the VAO draw memo is keyed on, so // the two cannot disagree about whether "the VAO moved". The config version stays: @@ -6656,7 +6656,7 @@ void main() { vao.GetLifetimeId() != snap.vaoLifetimeId || vao.GetConfigVersion() != snap.vaoConfigVersion); const auto& drawFbo = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (static_cast(drawFbo.get()) != snap.drawFbo || drawFbo->GetLifetimeId() != snap.drawFboLifetimeId || drawFbo->GetObjectVersion() != snap.fboVersion) { @@ -6667,8 +6667,8 @@ void main() { // back on what the snapshot already describes (a GL_BLEND toggle between // two draws, a redundant glBindSampler), and declining here sends every // such draw through the full SetupDraw. - const Uint renderStateVersion = MGB_CTX->GetPipelineStateVersion(); - const Uint64 bindGeneration = MGB_CTX->GetTextureBindGeneration(); + const Uint renderStateVersion = MG_Pipe::gPipeInputs.GetPipelineStateVersion(); + const Uint64 bindGeneration = MG_Pipe::gPipeInputs.GetTextureBindGeneration(); const Bool renderStateMoved = renderStateVersion != snap.renderStateVersion; const Bool bindsMoved = bindGeneration != snap.bindGeneration; if (renderStateMoved) { @@ -6676,7 +6676,7 @@ void main() { // flavor input (depth/stencil participation); a flip of that must take // the full path's pass selection. One bulk parameters fetch instead of // two capability-accessor calls; both are pure reads of the same fields. - const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); + const RenderStateParameters& rsp = MG_Pipe::gPipeInputs.GetRenderStateParameters(); const Bool drawUsesDepthStencil = rsp.DepthTestEnabled || rsp.StencilTestEnabled; if (drawUsesDepthStencil != snap.drawUsesDepthStencil) { return false; @@ -6850,7 +6850,7 @@ void main() { if (contentSum != snap.sampledContentSum || paramsSum != snap.sampledParamsSum) { return false; } - const Uint64 samplingResolutionGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + const Uint64 samplingResolutionGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); if (samplingResolutionGeneration != snap.samplingResolutionGeneration) { // Decline, not re-arm: snap.resolvedTransformFlags bakes the // ExplicitLod0Sampling verdict, which reads the effective sampler's @@ -7004,7 +7004,7 @@ void main() { // was cancelled has no usable optimized module - and on an in-place // SanitizeAndOptimizeBinary failure GetGeneratedSpirv() still holds the RAW // glslang words, which must never reach vkCreateShaderModule. Drop the draw. - const auto& drawProgram = *MGB_CTX->GetProgramForDraw(); + const auto& drawProgram = *MG_Pipe::gPipeInputs.GetProgramForDraw(); if (!drawProgram.GetLinkStatus() || !drawProgram.GetSpirvStatus()) { MGLOG_D("SetupDraw skipped: program=%u is linked=%d spirv=%d", drawProgram.GetExternalIndex(), static_cast(drawProgram.GetLinkStatus()), @@ -7034,15 +7034,15 @@ void main() { MG_Util::PipeStats::AddCalls(MG_Util::PipeStats::CallClass::AccessorCalls, 3); } const auto& drawFbo = - MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (drawFbo != nullptr && IsUnsupportedFramebufferForDirectVulkan(*drawFbo)) { // Nothing was mutated: other entries' per-probe guards (FBO identity + // version among them) stay authoritative, so none need invalidating. RecordUnsupportedFramebufferError(__func__); return false; } - const auto& vao = *MGB_CTX->GetBoundVertexArray(); - const auto& program = *MGB_CTX->GetProgramForDraw(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); + const auto& program = *MG_Pipe::gPipeInputs.GetProgramForDraw(); // The fast path declined (or had no entry for this program): whatever THIS // program's entry saw may be stale, and the full path below mutates state as // it goes, so the entry must not stay matchable if that path fails mid-way. @@ -7082,7 +7082,7 @@ void main() { ProgramFactory::CompileOptionFlags transformFlags = ProgramFactory::CompileOptionFlags(GetBaseTransformFlagsRaw(drawFboIsDefault)); // Captured draws take the xfb-decorated program variant. - if (m_transformFeedbackFeatureEnabled && MGB_CTX->IsTransformFeedbackActive() && + if (m_transformFeedbackFeatureEnabled && MG_Pipe::gPipeInputs.IsTransformFeedbackActive() && program.GetTransformFeedbackVaryingCount() > 0) { transformFlags |= ProgramFactory::CompileOptionBit::XfbCapture; } @@ -7096,13 +7096,13 @@ void main() { { const Uint64 lodProgramLifetimeId = program.GetLifetimeId(); const Uint32 lodProgramVersion = program.GetBackendStateVersion(); - const Uint64 lodBindGeneration = MGB_CTX->GetTextureBindGeneration(); + const Uint64 lodBindGeneration = MG_Pipe::gPipeInputs.GetTextureBindGeneration(); // The probe also reads the EFFECTIVE sampler's filters/aniso/LOD range // (ProgramSamplesOnlySingleLevelTextures), and those setters bump ONLY the // sampling-resolution generation - not the texture params version the sum // below covers. Without this key a filter/aniso change would keep serving // the stale verdict. - const Uint64 lodSamplingGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + const Uint64 lodSamplingGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); Bool lodMemoHit = false; if (m_lastLodDecisionValid && m_lastSampledSetValid && m_lastLodProgramLifetimeId == lodProgramLifetimeId && @@ -7220,7 +7220,7 @@ void main() { { const Uint64 programLifetimeId = program.GetLifetimeId(); const Uint32 programVersion = program.GetBackendStateVersion(); - const Uint64 bindGeneration = MGB_CTX->GetTextureBindGeneration(); + const Uint64 bindGeneration = MG_Pipe::gPipeInputs.GetTextureBindGeneration(); // The bind generation alone stopped covering this set the moment ResolveSampledBinding // started asking SamplesAsIncompleteTexture: membership now depends on the effective // sampler PARAMETERS (MIN_FILTER decides whether the mip chain is read at all) and on @@ -7239,7 +7239,7 @@ void main() { // object a unit carries goes through TextureUnit::SetSamplerObject and moves the bind // generation instead. Same term the SetupDrawSnapshot fast path and the LOD memo // already carry. - const Uint64 samplingGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + const Uint64 samplingGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); const Bool sampledSetUnchanged = m_lastSampledSetValid && m_lastSampledSetProgramLifetimeId == programLifetimeId && m_lastSampledSetProgramVersion == programVersion && @@ -7409,8 +7409,8 @@ void main() { // pass flavor (GL: a disabled depth/stencil test neither reads nor writes // its buffer). const Bool drawUsesDepthStencil = - MGB_CTX->IsCapabilityEnabled(CapabilityInput::DepthTest) || - MGB_CTX->IsCapabilityEnabled(CapabilityInput::StencilTest); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::DepthTest) || + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::StencilTest); auto* renderPassEntry = m_renderPassManager->GetOrCreateRenderPass( *drawFbo, DefaultFramebufferWriteIndex(drawFbo->IsDefaultFramebuffer()), drawUsesDepthStencil); // nullptr: the framebuffer has an attachment DirectVulkan cannot represent (a texture the @@ -7556,8 +7556,8 @@ void main() { snap.fboVersion = drawFbo->GetObjectVersion(); snap.drawFboIsDefault = drawFboIsDefault; snap.viewportCount = ResolveDrawViewportCount(programObj.writesViewportIndexBuiltin); - snap.renderStateVersion = MGB_CTX->GetPipelineStateVersion(); - snap.bindGeneration = MGB_CTX->GetTextureBindGeneration(); + snap.renderStateVersion = MG_Pipe::gPipeInputs.GetPipelineStateVersion(); + snap.bindGeneration = MG_Pipe::gPipeInputs.GetTextureBindGeneration(); snap.baseTransformFlags = GetBaseTransformFlagsRaw(drawFboIsDefault); snap.resolvedTransformFlags = transformFlags.GetRaw(); snap.renderPassHash = nowActiveRenderPass->hash; @@ -7583,7 +7583,7 @@ void main() { snap.programObj = nullptr; snap.programFactoryEpoch = 0; } - snap.samplingResolutionGeneration = MGB_CTX->GetSamplingResolutionGeneration(); + snap.samplingResolutionGeneration = MG_Pipe::gPipeInputs.GetSamplingResolutionGeneration(); Uint64 snapContentSum = 0; Uint64 snapParamsSum = 0; // Per-entry copies of this draw's sampled set (the scratch vectors @@ -7630,7 +7630,7 @@ void main() { auto& frame = m_frameContext.GetCurrent(); // The DISPATCH accessor: with a pipeline bound this is its compute stage program // itself, never the graphics composite (which carries no compute stage at all). - const auto& program = *MGB_CTX->GetProgramForDispatch(); + const auto& program = *MG_Pipe::gPipeInputs.GetProgramForDispatch(); if (!program.GetLinkStatus() || !program.GetSpirvStatus()) { MGLOG_E_ONCE("DispatchCompute skipped: program=%u has no optimized SPIR-V", program.GetExternalIndex()); @@ -7695,7 +7695,7 @@ void main() { m_textureManager->CollectGarbage(); auto& frame = m_frameContext.GetCurrent(); // See DispatchCompute: the dispatch accessor, not the draw one. - const auto& program = *MGB_CTX->GetProgramForDispatch(); + const auto& program = *MG_Pipe::gPipeInputs.GetProgramForDispatch(); if (!program.GetLinkStatus() || !program.GetSpirvStatus()) { MGLOG_E_ONCE("DispatchComputeIndirect skipped: program=%u has no optimized SPIR-V", program.GetExternalIndex()); @@ -7741,7 +7741,7 @@ void main() { return; } - auto indirectBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DispatchIndirect).GetBoundObject(); + auto indirectBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DispatchIndirect).GetBoundObject(); if (!indirectBuffer) { MGLOG_E_ONCE("DispatchComputeIndirect skipped: GL_DISPATCH_INDIRECT_BUFFER is not bound"); return; @@ -7826,10 +7826,10 @@ void main() { VkClearRect clearRect{}; clearRect.rect = framebuffer.IsDefaultFramebuffer() - ? MakeDefaultFramebufferScissorRect(MGB_CTX->GetScissorBox(), + ? MakeDefaultFramebufferScissorRect(MG_Pipe::gPipeInputs.GetScissorBox(), renderPassEntry->extent, m_swapchainObject.GetPreTransform()) - : MakeClampedScissorRect(MGB_CTX->GetScissorBox(), renderPassEntry->extent); + : MakeClampedScissorRect(MG_Pipe::gPipeInputs.GetScissorBox(), renderPassEntry->extent); clearRect.baseArrayLayer = 0; // GL 3.3 §4.4.7: clearing a layered framebuffer clears every layer. clearRect.layerCount = renderPassEntry->layers; @@ -7968,9 +7968,9 @@ void main() { if (!fbo) MagmaWireFatal("clear-framebuffer-record"); ClearAttachmentPayload payload{}; payload.mask = mask; - payload.color = MGB_CTX->GetClearColor(); - payload.depth = MGB_CTX->GetClearDepth(); - payload.stencil = MGB_CTX->GetClearStencil(); + payload.color = MG_Pipe::gPipeInputs.GetClearColor(); + payload.depth = MG_Pipe::gPipeInputs.GetClearDepth(); + payload.stencil = MG_Pipe::gPipeInputs.GetClearStencil(); ClearWireFramebuffer(*fbo, payload); return; } @@ -7980,10 +7980,10 @@ void main() { return; } // GL 3.3 §3.1: when RASTERIZER_DISCARD is enabled, Clear and ClearBuffer* are ignored. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return; } - auto* fbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); + auto* fbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); MOBILEGL_ASSERT(fbo, "VulkanRenderer::Clear: draw framebuffer not found (fbo == nullptr)"); if (IsUnsupportedFramebufferForDirectVulkan(*fbo)) { RecordUnsupportedFramebufferError(__func__); @@ -7991,16 +7991,16 @@ void main() { } ClearFramebufferPayload payload { - .color = MGB_CTX->GetClearColor(), - .depth = MGB_CTX->GetClearDepth(), - .stencil = MGB_CTX->GetClearStencil() + .color = MG_Pipe::gPipeInputs.GetClearColor(), + .depth = MG_Pipe::gPipeInputs.GetClearDepth(), + .stencil = MG_Pipe::gPipeInputs.GetClearStencil() }; // A render-pass loadOp clear always covers the complete attachment, while // OpenGL glClear is clipped by GL_SCISSOR_TEST. Blaze3D relies on this for // GuiItemAtlas: animated items clear only their atlas slot before being // redrawn. Queueing that clear as a loadOp erases every cached static item. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ScissorTest)) { VkClearRect clearRect{}; switch (PrepareScissoredClear(*fbo, clearRect)) { case ScissoredClearPrep::NoOp: @@ -8023,7 +8023,7 @@ void main() { continue; } - const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(drawBufferIndex); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { continue; } @@ -8050,7 +8050,7 @@ void main() { } VkImageAspectFlags depthStencilAspects = 0; - if ((mask & GL_DEPTH_BUFFER_BIT) != 0 && MGB_CTX->GetDepthMask()) { + if ((mask & GL_DEPTH_BUFFER_BIT) != 0 && MG_Pipe::gPipeInputs.GetDepthMask()) { const auto& depthAttachment = fbo->GetAttachment(FramebufferAttachmentType::Depth); if (depthAttachment.IsComplete()) { depthStencilAspects |= VK_IMAGE_ASPECT_DEPTH_BIT; @@ -8063,7 +8063,7 @@ void main() { // vkCmdClearAttachments writes every bit, so only a full (8-bit stencil) or // zero mask can be expressed; treat a partial mask like a partial color mask. const Uint32 stencilWriteMask = - MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; + MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { depthStencilAspects |= VK_IMAGE_ASPECT_STENCIL_BIT; } else if (stencilWriteMask != 0) { @@ -8092,11 +8092,11 @@ void main() { // gating for the deferred path: drop fully-masked planes, warn on partial // masks vkCmdClear*/loadOp clears cannot express. GLbitfield deferredMask = mask; - if ((deferredMask & GL_DEPTH_BUFFER_BIT) != 0 && !MGB_CTX->GetDepthMask()) { + if ((deferredMask & GL_DEPTH_BUFFER_BIT) != 0 && !MG_Pipe::gPipeInputs.GetDepthMask()) { deferredMask &= ~static_cast(GL_DEPTH_BUFFER_BIT); } if ((deferredMask & GL_STENCIL_BUFFER_BIT) != 0) { - const Uint32 stencilWriteMask = MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; + const Uint32 stencilWriteMask = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) != 0xFFu) { if (stencilWriteMask != 0) { MGLOG_W_ONCE("DirectVulkan: deferred glClear with a partial stencil write mask is not supported"); @@ -8112,7 +8112,7 @@ void main() { if (drawBuffers[drawBufferIndex] == FramebufferAttachmentType::None) { continue; } - const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(drawBufferIndex); const Bool full = colorMask.r() && colorMask.g() && colorMask.b() && colorMask.a(); if (full) { anyFullMask = true; @@ -8133,7 +8133,7 @@ void main() { if (attachmentType == FramebufferAttachmentType::None) { continue; } - const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(drawBufferIndex); if (!(colorMask.r() && colorMask.g() && colorMask.b() && colorMask.a())) { continue; } @@ -8176,7 +8176,7 @@ void main() { const ClearAttachmentPayload& clearPayload) { m_clearManager->CollectGarbage(); // GL 3.3 §3.1: when RASTERIZER_DISCARD is enabled, Clear and ClearBuffer* are ignored. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return; } if (IsUnsupportedFramebufferForDirectVulkan(framebuffer)) { @@ -8218,7 +8218,7 @@ void main() { } // GL 3.3 §4.2.3: ClearBuffer* is clipped by GL_SCISSOR_TEST exactly like Clear. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ScissorTest)) { VkClearRect clearRect{}; switch (PrepareScissoredClear(framebuffer, clearRect)) { case ScissoredClearPrep::NoOp: @@ -8250,9 +8250,9 @@ void main() { // GL 3.3 §4.2.3: ClearBuffer* honors the write masks like Clear. Deferred // clears cannot express partial masks; warn and skip those. - const auto depthClearAllowed = [&]() -> Bool { return MGB_CTX->GetDepthMask(); }; + const auto depthClearAllowed = [&]() -> Bool { return MG_Pipe::gPipeInputs.GetDepthMask(); }; const auto stencilClearAllowed = [&]() -> Bool { - const Uint32 stencilWriteMask = MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; + const Uint32 stencilWriteMask = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { return true; } @@ -8264,7 +8264,7 @@ void main() { switch (buffer) { case GL_COLOR: { - const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(static_cast(drawbuffer)); + const BoolVec4 colorMask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(static_cast(drawbuffer)); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { return; } @@ -8321,7 +8321,7 @@ void main() { if (!attachment.IsComplete()) { return; } - const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(static_cast(drawbuffer)); + const BoolVec4 colorMask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(static_cast(drawbuffer)); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { return; } @@ -8339,7 +8339,7 @@ void main() { MakeVkClearColorValue(clearPayload, ColorFormatLacksAlpha(colorTexture)); } else { VkImageAspectFlags aspects = 0; - if ((clearPayload.mask & GL_DEPTH_BUFFER_BIT) != 0 && MGB_CTX->GetDepthMask() && + if ((clearPayload.mask & GL_DEPTH_BUFFER_BIT) != 0 && MG_Pipe::gPipeInputs.GetDepthMask() && framebuffer.GetAttachment(FramebufferAttachmentType::Depth).IsComplete()) { aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; } @@ -8347,7 +8347,7 @@ void main() { framebuffer.GetAttachment(FramebufferAttachmentType::Stencil).IsComplete()) { // GL 3.3 §4.2.3: the clear is masked by the front stencil write mask (see Clear). const Uint32 stencilWriteMask = - MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; + MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; } else if (stencilWriteMask != 0) { @@ -8374,7 +8374,7 @@ void main() { return; } #endif - auto* fbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); + auto* fbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); if (!fbo) { return; } @@ -9511,8 +9511,8 @@ void main() { return; } #endif - auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); - auto drawFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + auto readFbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto drawFbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); BlitNamedFramebuffer(readFbo, drawFbo, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } @@ -9544,8 +9544,8 @@ void main() { // The scissor test clips blit writes: intersect the destination rectangle with // the scissor box and shrink the source proportionally. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { - const IntVec4& scissor = MGB_CTX->GetScissorBox(); + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + const IntVec4& scissor = MG_Pipe::gPipeInputs.GetScissorBox(); const auto clipAxis = [](GLint& d0, GLint& d1, GLint& s0, GLint& s1, GLint clipLo, GLint clipHi) -> Bool { const Bool dstFlipped = d1 < d0; GLint lo = dstFlipped ? d1 : d0; @@ -10169,7 +10169,7 @@ void main() { return; } - auto& textureUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->GetActiveTextureUnit()); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(MG_Pipe::gPipeInputs.GetActiveTextureUnit()); auto destinationTexture = textureUnit.GetBindingSlot(textureTarget).GetBoundObject(); if (destinationTexture == nullptr) { RecordTextureCopyError(__func__, ErrorCode::InvalidOperation, @@ -10177,7 +10177,7 @@ void main() { return; } - auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto readFbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (readFbo == nullptr) { RecordTextureCopyError(__func__, ErrorCode::InvalidOperation, "CopyTexSubImage2D requires a framebuffer bound to GL_READ_FRAMEBUFFER."); @@ -11076,7 +11076,7 @@ void main() { return; } - auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto readFbo = MG_Pipe::gPipeInputs.GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (readFbo == nullptr) { MGLOG_E_ONCE("DirectVulkan::ReadPixels skipped: no read framebuffer is bound"); return; @@ -11771,8 +11771,8 @@ void main() { #if MOBILEGL_BUILD_DISAGGREGATED MG_Config::Transport != MG_Config::TransportMode::Monolith ? wireReplyHasNoPackBuffer : #endif - MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); - const auto packParams = MGB_CTX->GetPixelStoreParameters(false); + MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + const auto packParams = MG_Pipe::gPipeInputs.GetPixelStoreParameters(false); const SizeT rowPixels = static_cast(packParams.RowLength > 0 ? packParams.RowLength : width); const SizeT packAlignment = packParams.Alignment > 0 ? static_cast(packParams.Alignment) : 1; const SizeT dstRowStride = ((rowPixels * dstPixelBytes) + packAlignment - 1) / packAlignment * packAlignment; @@ -11802,7 +11802,7 @@ void main() { void VulkanRenderer::GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { const auto textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); const auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - auto& activeUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->GetActiveTextureUnit()); + auto& activeUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(MG_Pipe::gPipeInputs.GetActiveTextureUnit()); auto textureObject = activeUnit.GetBindingSlot(textureTarget).GetBoundObject(); GetTextureImage(textureObject, textureUploadTarget, level, format, type, -1, pixels); } @@ -12074,7 +12074,7 @@ void main() { return; } - auto& textureUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->GetActiveTextureUnit()); + auto& textureUnit = MG_Pipe::gPipeInputs.GetTextureUnitObject(MG_Pipe::gPipeInputs.GetActiveTextureUnit()); auto texture = textureUnit.GetBindingSlot(textureTarget).GetBoundObject(); MOBILEGL_ASSERT(texture != nullptr, "GenerateMipmap requires a bound texture."); MOBILEGL_ASSERT(texture->IsComplete(), "GenerateMipmap requires a complete texture."); @@ -12380,7 +12380,7 @@ void main() { // resets its counter state, because those bytes describe the previous owner's span. Uint32 VulkanRenderer::CurrentXfbCounterSlot() { constexpr Uint32 kNoSlot = static_cast(kXfbCounterObjectSlots); - const Uint64 identity = MGB_CTX->GetBoundTransformFeedbackLifetimeId(); + const Uint64 identity = MG_Pipe::gPipeInputs.GetBoundTransformFeedbackLifetimeId(); MOBILEGL_ASSERT(identity != 0, "transform feedback object reported the free-slot sentinel (0) as its identity - " "every slot would then read as 'mine' without ever being claimed"); @@ -12397,7 +12397,7 @@ void main() { Uint32 slot = freeSlot; if (slot == kNoSlot) { for (Uint32 candidate = 0; candidate < kNoSlot; ++candidate) { - if (MGB_CTX->HasOpenTransformFeedbackSpan(m_xfbCounterSlotOwner[candidate])) { + if (MG_Pipe::gPipeInputs.HasOpenTransformFeedbackSpan(m_xfbCounterSlotOwner[candidate])) { continue; } if (slot == kNoSlot || m_xfbCounterSlotLastUse[candidate] < m_xfbCounterSlotLastUse[slot]) { @@ -12428,14 +12428,14 @@ void main() { } Bool VulkanRenderer::BeginXfbCaptureForDraw(FrameContext::FrameData& frame) { - if (!m_transformFeedbackFeatureEnabled || !MGB_CTX_LIVE || - !MGB_CTX->IsTransformFeedbackActive()) { + if (!m_transformFeedbackFeatureEnabled || !MG_Pipe::gPipeInputs.IsLive() || + !MG_Pipe::gPipeInputs.IsTransformFeedbackActive()) { return false; } // A paused span captures nothing, and the counter buffers keep their values, so the // next resumed draw appends exactly where the last captured one stopped - which is // what pause/resume means (ARB_transform_feedback2). - if (MGB_CTX->IsTransformFeedbackPaused()) { + if (MG_Pipe::gPipeInputs.IsTransformFeedbackPaused()) { return false; } // The bound pipeline's last pre-rasterization stage has to have been declared with Xfb @@ -12455,7 +12455,7 @@ void main() { if (MG_Config::Transport != MG_Config::TransportMode::Monolith) return BeginWireXfbCaptureForDraw(frame); #endif - const auto& program = MGB_CTX->GetTransformFeedbackProgram(); + const auto& program = MG_Pipe::gPipeInputs.GetTransformFeedbackProgram(); if (!program || program->GetTransformFeedbackVaryingCount() == 0) { return false; } @@ -12469,7 +12469,7 @@ void main() { VkDeviceSize sizes[4] = {}; for (SizeT i = 0; i < bufferCount; ++i) { if (!program->GetTransformFeedbackStride(static_cast(i))) continue; - auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::TransformFeedback, + auto& point = MG_Pipe::gPipeInputs.GetBufferBindingPoint(BufferTarget::TransformFeedback, static_cast(i)); const auto& bufferObject = point.GetBoundObject(); if (bufferObject == nullptr) { @@ -12525,7 +12525,7 @@ void main() { } const Uint32 counterSlot = CurrentXfbCounterSlot(); - const Uint64 generation = MGB_CTX->GetTransformFeedbackGeneration(); + const Uint64 generation = MG_Pipe::gPipeInputs.GetTransformFeedbackGeneration(); const Bool resume = m_xfbCountersValid[counterSlot] && m_xfbLastSeenGeneration[counterSlot] == generation; m_xfbLastSeenGeneration[counterSlot] = generation; @@ -13199,7 +13199,7 @@ void main() { default: break; } if (mergeGranularity != 0) { - const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); + const RenderStateParameters& rsp = MG_Pipe::gPipeInputs.GetRenderStateParameters(); if (rsp.PrimitiveRestartEnabled || rsp.PrimitiveRestartFixedIndexEnabled) { mergeGranularity = 0; } @@ -13277,7 +13277,7 @@ void main() { return; } - const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); const auto* indexBuffer = vao.GetIndexBufferBindingSlot().GetBoundObject().get(); if (!indexBuffer) { MGLOG_E_ONCE("MultiDrawElementsIndirectCount skipped: no element array buffer is bound"); @@ -13287,13 +13287,13 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(maxdrawcount - 1) + kGLDrawElementsIndirectCommandBytes; - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!drawBuffer || commandBytes > drawBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawElementsIndirectCount skipped: invalid GL_DRAW_INDIRECT_BUFFER binding or range"); return; } - auto parameterBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto parameterBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); if (!parameterBuffer || static_cast(drawcount) + sizeof(Uint32) > parameterBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawElementsIndirectCount skipped: invalid GL_PARAMETER_BUFFER binding or range"); return; @@ -13378,7 +13378,7 @@ void main() { return; } - const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& vao = *MG_Pipe::gPipeInputs.GetBoundVertexArray(); const auto* indexBuffer = vao.GetIndexBufferBindingSlot().GetBoundObject().get(); if (!indexBuffer) { MGLOG_E_ONCE("MultiDrawElementsIndirect skipped: no element array buffer is bound"); @@ -13388,7 +13388,7 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(drawcount - 1) + kGLDrawElementsIndirectCommandBytes; - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!drawBuffer || commandBytes > drawBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawElementsIndirect skipped: invalid GL_DRAW_INDIRECT_BUFFER binding or range"); return; @@ -13458,7 +13458,7 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(drawcount - 1) + kGLDrawArraysIndirectCommandBytes; - auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MG_Pipe::gPipeInputs.GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!drawBuffer || commandBytes > drawBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawArraysIndirect skipped: invalid GL_DRAW_INDIRECT_BUFFER binding or range"); return; @@ -13475,7 +13475,7 @@ void main() { // MONOLITH ONLY: with a transport the frontend VAO is not this side's to read at all // (the client owns those bytes and stages them itself), and this runs on the apply thread. if (MG_Config::Transport == MG_Config::TransportMode::Monolith) { - const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + const auto& currentVAO = MG_Pipe::gPipeInputs.GetBoundVertexArray(); Bool clientArray = false; if (currentVAO) { for (const auto& attribute : currentVAO->GetAllAttributes()) { @@ -14347,8 +14347,8 @@ void main() { if (!m_provokingVertexModePerPipeline) { return VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; } - return (MGB_CTX_LIVE && - MGB_CTX->GetProvokingVertexMode() == ProvokingVertexMode::FirstVertex) + return (MG_Pipe::gPipeInputs.IsLive() && + MG_Pipe::gPipeInputs.GetProvokingVertexMode() == ProvokingVertexMode::FirstVertex) ? VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT : VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.inc b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.inc index f0f2999a..c71f6781 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.inc +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.inc @@ -176,7 +176,7 @@ // Mip generation samples and writes the texture's own color space; // GL_FRAMEBUFFER_SRGB only controls framebuffer operations. if (!mipmap) destination.format = ResolveSrgbAttachmentWriteFormat(destination.format, - MGB_CTX->IsCapabilityEnabled(CapabilityInput::FramebufferSrgb)); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::FramebufferSrgb)); VkFormatProperties destinationProperties{}; vkGetPhysicalDeviceFormatProperties(m_physicalDevice.handle, destination.format, &destinationProperties); if (!(destinationProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) return false; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc index c7fe2c5e..e5ea0767 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc @@ -225,7 +225,7 @@ ProgramFactory::CompileOptionFlags flags = ProgramFactory::CompileOptionFlags(GetBaseTransformFlagsRaw(fbo->IsDefault)); - if (m_transformFeedbackFeatureEnabled && MGB_CTX->IsTransformFeedbackActive() && + if (m_transformFeedbackFeatureEnabled && MG_Pipe::gPipeInputs.IsTransformFeedbackActive() && program.GetTransformFeedbackVaryingCount() > 0) flags |= ProgramFactory::CompileOptionBit::XfbCapture; const auto* programObject = &m_programFactory->GetOrCreateProgram(program, flags); @@ -399,7 +399,7 @@ return false; } indexType = width == 4 ? VK_INDEX_TYPE_UINT32 : width == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT8; - const auto& restart = MGB_CTX->GetRenderStateParameters(); + const auto& restart = MG_Pipe::gPipeInputs.GetRenderStateParameters(); const Uint32 fixed = MG_Util::FixedRestartIndexForGLType(indices->indexType); const Bool replaceRestart = restart.PrimitiveRestartEnabled && !restart.PrimitiveRestartFixedIndexEnabled && restart.PrimitiveRestartIndex < fixed; @@ -485,7 +485,7 @@ Uint64 passHash = 0; WireDrawPassKey passKey{}; passKey.isDefault = fbo->IsDefault; - passKey.framebufferSrgb = MGB_CTX->IsCapabilityEnabled(CapabilityInput::FramebufferSrgb); + passKey.framebufferSrgb = MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::FramebufferSrgb); if (fbo->IsDefault) { passKey.swapchain = m_swapchainObject.GetHandle(); // A drawing pass on the default framebuffer is what makes the freshly acquired @@ -500,7 +500,7 @@ m_textureManager->FlushPendingUploads(); if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) image.format = ResolveSrgbAttachmentWriteFormat(image.format, - MGB_CTX->IsCapabilityEnabled(CapabilityInput::FramebufferSrgb)); + MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::FramebufferSrgb)); const VkImageLayout layout = aspect == VK_IMAGE_ASPECT_COLOR_BIT ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_GENERAL; // Already in its attachment layout: its barrier (which closes any open pass) waits until @@ -632,7 +632,7 @@ VkFormat format = VK_FORMAT_UNDEFINED; const void* data = nullptr; VkDeviceSize size = 0; - if (!TryGetCurrentVertexAttributeUploadPayload(MGB_CTX->GetCurrentVertexAttribute(location), + if (!TryGetCurrentVertexAttributeUploadPayload(MG_Pipe::gPipeInputs.GetCurrentVertexAttribute(location), programObj.vertexInputTypes[location], format, data, size)) { MGL_WIRE_DECLINE_AT(CurrentAttributePayload, "a disabled array's current attribute value has no upload payload"); return false; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc index f79d6fe6..fd020cfe 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc @@ -240,12 +240,12 @@ if (m_wireRetiredObjects.size() >= kRetiredObjectsBeforeSubmit && m_wirePreparationDepth == 0 && HasPendingRecordedWork()) (void)FlushPendingCommands(); - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) return; + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) return; const auto clearSurface = [&](const MG_Pipe::MGPSurface& surface, VkImageAspectFlags aspect, Uint32 colorIndex) { if (!fbo.IsDefault && surface.Kind == MG_Pipe::kMGPipeSurfaceKindNone) return; if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) { - const auto mask = MGB_CTX->GetColorMaskIndexed(colorIndex); + const auto mask = MG_Pipe::gPipeInputs.GetColorMaskIndexed(colorIndex); if (!mask.r() && !mask.g() && !mask.b() && !mask.a()) return; if (!mask.r() || !mask.g() || !mask.b() || !mask.a()) { MGLOG_W_ONCE("DirectVulkan: glClear with a partial color mask is not supported"); @@ -253,10 +253,10 @@ } } if (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) { - if (!MGB_CTX->GetDepthMask()) aspect &= ~VK_IMAGE_ASPECT_DEPTH_BIT; + if (!MG_Pipe::gPipeInputs.GetDepthMask()) aspect &= ~VK_IMAGE_ASPECT_DEPTH_BIT; } if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) { - const Uint32 mask = MGB_CTX->GetStencilState(StencilFace::Front).WriteMask & 255u; + const Uint32 mask = MG_Pipe::gPipeInputs.GetStencilState(StencilFace::Front).WriteMask & 255u; if (!mask) aspect &= ~VK_IMAGE_ASPECT_STENCIL_BIT; else if (mask != 255u) { MGLOG_W_ONCE("DirectVulkan: glClear with a partial stencil write mask is not supported"); @@ -268,8 +268,8 @@ if (!image.image) return; m_textureManager->FlushPendingUploads(); VkRect2D area{{0, 0}, image.extent}; - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { - const auto& box = MGB_CTX->GetScissorBox(); + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + const auto& box = MG_Pipe::gPipeInputs.GetScissorBox(); const Int32 x0 = std::max(box.x(), 0), y0 = std::max(box.y(), 0); const Int32 x1 = std::min(box.x() + box.z(), static_cast(image.extent.width)); const Int32 y1 = std::min(box.y() + box.w(), static_cast(image.extent.height)); @@ -917,8 +917,8 @@ RetireWireDrawPass(); // The scissor test clips blit writes: intersect the destination rectangle with // the scissor box and shrink the source proportionally. - if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { - const IntVec4& scissor = MGB_CTX->GetScissorBox(); + if (MG_Pipe::gPipeInputs.IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + const IntVec4& scissor = MG_Pipe::gPipeInputs.GetScissorBox(); const auto clipAxis = [](GLint& d0, GLint& d1, GLint& s0, GLint& s1, GLint clipLo, GLint clipHi) -> Bool { const Bool dstFlipped = d1 < d0; GLint lo = dstFlipped ? d1 : d0; diff --git a/MobileGL/MG_Backend/MGPipe/PipeInputs.h b/MobileGL/MG_Backend/MGPipe/PipeInputs.h index 3f3f3dee..b70a15ef 100644 --- a/MobileGL/MG_Backend/MGPipe/PipeInputs.h +++ b/MobileGL/MG_Backend/MGPipe/PipeInputs.h @@ -37,9 +37,9 @@ namespace MobileGL::MG_Pipe { // TABLE 2 (CONTRACT-P5.md section 3, R-7): the four ownership classes, one per field, plus // the seven sticky forwards' own rows. Included HERE rather than from MG_Pipe/MGPipe.h with // gen_pipe.py's seven outputs, deliberately: MGPipe.h is in the PULL build's include closure -// and G1 admits no symbol motion there, while this header is reached only through -// PipeInputsSwitch.h's MOBILEGL_PIPE_PUSH arm. It is also exactly the header the poison check -// below and the server's verb stamp both already see. +// and G1 admitted no symbol motion there (until P13 retired the pull build), while this header is +// what the backends include directly. It is also exactly the header the poison check below and the +// server's verb stamp both already see. #include // PipeInputs.cpp. The poison Fatal with the verb's name ("" before the first @@ -255,11 +255,11 @@ namespace MobileGL::MG_Pipe { }; // ---- identity / liveness (not fields) ---- - // Whether a live GLContext exists. Forwarded (PipeFill.cpp): under push MGB_CTX_LIVE + // Whether a live GLContext exists. Forwarded (PipeFill.cpp): under push gPipeInputs // must be true as soon as a context exists, fill or no fill, which is what today's // null-context guards test. Bool IsLive() const; - // The live GLContext's address at the last fill; serves MGB_CTX_IDENTITY. + // The live GLContext's address at the last fill; serves gPipeInputs. const void* ContextIdentity() const { return m_contextIdentity; } // The verb of the last fill, kVerbCount before the first one. MGPipeVerb CurrentVerb() const { return m_currentVerb; } @@ -442,7 +442,7 @@ namespace MobileGL::MG_Pipe { // BufferTarget, and Coverage.def:62-69 already rules that such a field stays ONE row. // Only [0] (pack) has a carrier - set_pixel_pack_state, which the applier writes // (PipeApply.cpp:1373) - so the field is APPLIER-DERIVED and the UNPACK half is FATAL: - // every MGB_CTX->GetPixelStoreParameters site in the tree passes false + // every gPipeInputs->GetPixelStoreParameters site in the tree passes false // (DirectGLES.cpp:7924, :9399, :10893, :11272, Utils.cpp:2302, // VulkanRenderer.cpp:10980), and PipeFill.cpp's EmitPixelPackState says the same from // the other side: "nothing on the far side of the boundary reads unpack state". @@ -822,7 +822,7 @@ namespace MobileGL::MG_Pipe { TextureUnit* m_textureUnitBase = nullptr; }; - // The single global the backends read through MGB_CTX (ARCHITECTURE.md 9.2). An inline + // The single global the backends read through gPipeInputs (ARCHITECTURE.md 9.2). An inline // variable: no .cpp is needed for the definition. // // P14 S2: IT IS THE PROCESS-WIDE BLOCK, and `gPipeInputs` below is the name every reader @@ -850,15 +850,15 @@ namespace MobileGL::MG_Pipe { // ============================================================================ // // ONE PROCESS, SEVERAL SERVED SESSIONS. The applier writes this block and the backend reads it - // through MGB_CTX, both on the SAME apply thread - the block IS "the state the record in hand + // through gPipeInputs, both on the SAME apply thread - the block IS "the state the record in hand // carries". Two sessions applying concurrently on two apply threads through one block would // read each other's render state, which is the cross-talk a multi-session server must not // have. Nothing about the block's contents changed; what changed is that the name resolves to // the SESSION'S block on a thread that belongs to one. // - // WHY A THREAD-LOCAL REFERENCE, AND NOT SOMETHING CLEVERER. MGB_CTX is - // `(&::MobileGL::MG_Pipe::gPipeInputs)` (MG_Pipe/PipeInputsSwitch.h) and is spelled at ~380 - // sites in MG_Backend/MG_Impl; a reference whose TARGET varies with the calling thread is the + // WHY A THREAD-LOCAL REFERENCE, AND NOT SOMETHING CLEVERER. gPipeInputs is spelled at ~380 + // sites in MG_Backend/MG_Impl (they read `MG_Pipe::gPipeInputs.` directly since P13 retired the + // pull/push switch macro); a reference whose TARGET varies with the calling thread is the // only shape that keeps all of them compiling and all of them correct. The cost is one TLS // address computation per access site - not one per field, and with no guard: the reference is // bound once per thread on its first use. @@ -902,7 +902,7 @@ namespace MobileGL::MG_Pipe { // dual-block arm, PipeInputs.cpp) instead of a silent cross-role answer. // // THE READ SIDE'S SPELLING DOES NOT MOVE. gPipeInputs remains the server-role block, so the - // 379 MGB_CTX sites and PipeApply.cpp's applier writes are untouched; the only new spelling + // 379 gPipeInputs sites and PipeApply.cpp's applier writes are untouched; the only new spelling // is on the fill side (MG_Impl/Pipe/PipeFill.cpp), which asks MGPipeClientInputs(). Under // monolith transport - every unit and integration-gpu lane of a split build - the selection // folds back to the single shared block and behaviour is byte-for-byte the old one. diff --git a/MobileGL/MG_Impl/Pipe/CompositeResolver.h b/MobileGL/MG_Impl/Pipe/CompositeResolver.h index b964c397..18c7656d 100644 --- a/MobileGL/MG_Impl/Pipe/CompositeResolver.h +++ b/MobileGL/MG_Impl/Pipe/CompositeResolver.h @@ -54,7 +54,7 @@ // THE CONTEXT ID IS GLContext::GetTextureContextId() AND NOTHING ELSE - the tree's existing // never-reused per-context id (TextureState::AllocateContextId; PipeInputs carries it as // m_textureContextId at seven fill points and the backends' own per-context memos key on it). -// Deliberately NOT the GLContext ADDRESS that MGB_CTX_IDENTITY and MGPipeTracker::m_context +// Deliberately NOT the GLContext ADDRESS that gPipeInputs and MGPipeTracker::m_context // compare, because Core.h states the reason that id exists at all: a context freed and remade // lands on the old heap address, which would put this same defect back one context recreation // later. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp index cce3474a..1614461c 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp @@ -34,7 +34,7 @@ // emit[fbe= sve= sse= sie= ctu=] bracket therefore carries a NON-ZERO total. // // off (MOBILEGL_PIPE_PUSH=0x1ff, P3a's default = P4a's four subsystems cleared) -// The frontend dispatch falls through to the legacy MGB_CTX-reading arms, nothing is emitted +// The frontend dispatch falls through to the legacy gPipeInputs-reading arms, nothing is emitted // through any of the four families, and every one of those five counters must read ZERO. // This is the reading a dead switch fails: with the bits ignored, this lane would report the // same non-zero counts as the other one. @@ -540,7 +540,7 @@ void main() { oColor = texture(uTex, vUv); } } else if (m_lane == kLaneOff) { EXPECT_EQ(total, 0) << "with bits 9|10|11|12 CLEARED (MOBILEGL_PIPE_PUSH=0x1ff, P3a's default) the " - "frontend dispatch must fall through to the legacy MGB_CTX-reading arms and " + "frontend dispatch must fall through to the legacy (&MG_Pipe::gPipeInputs)-reading arms and " "emit nothing through any of the four P4a families, so every counter in the " "emit[] bracket must be zero. A non-zero count here is the dead-switch " "reading: the bits are being ignored, both arms run the same code, and every " diff --git a/MobileGL/MG_Pipe/FieldOwnership.def b/MobileGL/MG_Pipe/FieldOwnership.def index 136e878c..d121b167 100644 --- a/MobileGL/MG_Pipe/FieldOwnership.def +++ b/MobileGL/MG_Pipe/FieldOwnership.def @@ -70,7 +70,7 @@ // as GetBufferBindingSlot is m_bufferBindingSlot[15] indexed by its BufferTarget. Only [0] // (pack) has a carrier, and the applier writes it. // -// AND THE UNPACK HALF HAS NO BACKEND READER AT ALL. Every MGB_CTX->GetPixelStoreParameters +// AND THE UNPACK HALF HAS NO BACKEND READER AT ALL. Every gPipeInputs->GetPixelStoreParameters // call site in the tree passes `false`: DirectGLES.cpp:7924, :9399, :10893, :11272, // Utils.cpp:2302 and VulkanRenderer.cpp:10980 - six, not the five the scout named, and the // scout did not open them. PipeFill.cpp's own EmitPixelPackState says the same thing from @@ -80,7 +80,7 @@ // way it is a named abort on the first read. #define MGP_FIELD_OWNERSHIP_ARG_LIST(X) \ X(GetPixelStoreParameters, 1, FATAL, \ - "the unpack half has no carrier AND no backend reader; all six MGB_CTX sites pass false") + "the unpack half has no carrier AND no backend reader; all six (&MG_Pipe::gPipeInputs) sites pass false") // X(WireOp, Verb) - WHERE THE SERVER STAMPS. // diff --git a/MobileGL/MG_Pipe/MGPipeTypes.h b/MobileGL/MG_Pipe/MGPipeTypes.h index 7ad7feb4..339e8d7b 100644 --- a/MobileGL/MG_Pipe/MGPipeTypes.h +++ b/MobileGL/MG_Pipe/MGPipeTypes.h @@ -1538,7 +1538,7 @@ namespace MobileGL::MG_Pipe { // DstGlName CopyImageSubData takes two CopyImageEndpoints, each a frontend SharedPtr, // and the server has none. Under inproc and the verb barrier the server // rebuilds a TEXTURE endpoint from the GL name through the barrier-pulled - // sticky forward MGB_CTX->GetTextureObject(name) (counted in `rsp`, + // sticky forward gPipeInputs->GetTextureObject(name) (counted in `rsp`, // retired by P7 / P3b-P4b when the backend takes handles). A GL name is // NEVER an identity (section 4.2.1); it is the lookup key of a pull the // handle beside it will replace. No forward hands out a renderbuffer, diff --git a/MobileGL/MG_Pipe/generated/PipeFieldOwnership.inc b/MobileGL/MG_Pipe/generated/PipeFieldOwnership.inc index 3bade0c6..77739635 100644 --- a/MobileGL/MG_Pipe/generated/PipeFieldOwnership.inc +++ b/MobileGL/MG_Pipe/generated/PipeFieldOwnership.inc @@ -218,7 +218,7 @@ struct MGPipeFieldArgumentOwnership { inline constexpr SizeT kMGPipeFieldArgumentOwnershipCount = 1; inline constexpr MGPipeFieldArgumentOwnership kMGPipeFieldArgumentOwnership[kMGPipeFieldArgumentOwnershipCount] = { - {MGPipeInputField::GetPixelStoreParameters, 1u, MGPipeFieldOwnership::kFatal}, // the unpack half has no carrier AND no backend reader; all six MGB_CTX sites pass false + {MGPipeInputField::GetPixelStoreParameters, 1u, MGPipeFieldOwnership::kFatal}, // the unpack half has no carrier AND no backend reader; all six gPipeInputs sites pass false }; constexpr MGPipeFieldOwnership MGPipeFieldOwnershipOf(MGPipeInputField field) { diff --git a/MobileGL/MG_Remote/Client/ClientSession.cpp b/MobileGL/MG_Remote/Client/ClientSession.cpp index f7874900..84841e5b 100644 --- a/MobileGL/MG_Remote/Client/ClientSession.cpp +++ b/MobileGL/MG_Remote/Client/ClientSession.cpp @@ -2308,7 +2308,7 @@ namespace MobileGL::MG_Remote::Client { // // WITH ONE NAMED EXCEPTION, FOUND BY ITS OWN FATAL (P5d round 3): generate_mipmap is // catalogued kCtxObject, but its sink is the backend's GenerateMipmap, which reads - // MGB_CTX->GetActiveTextureUnit() and the unit's binding slot - residual inputs whose + // gPipeInputs->GetActiveTextureUnit() and the unit's binding slot - residual inputs whose // freshness is the CLIENT's verb serial. Published without a wait, the record sits in // the ring while this thread runs the next verb's MGPipeValidateForVerb, which moves // that serial and withdraws the server stamp; the apply thread then reads the unit @@ -2317,7 +2317,7 @@ namespace MobileGL::MG_Remote::Client { // spin no longer read the clock). So it waits, exactly as the four stamping verbs // do. The rule this encodes: a record may skip its wait only if its apply reads // nothing the residual fill writes - the value carried in the payload is the whole - // input. No other kCtxObject row has a backend body behind it that reads MGB_CTX + // input. No other kCtxObject row has a backend body behind it that reads gPipeInputs // (set_texture_params, resource_subdata, resource_readback and get_texture_image // own reply slots and wait anyway; the resource_* transfers and object_death resolve // by handle). diff --git a/MobileGL/MG_Remote/Client/EmitTables.cpp b/MobileGL/MG_Remote/Client/EmitTables.cpp index f6a8d7c2..10e9eddb 100644 --- a/MobileGL/MG_Remote/Client/EmitTables.cpp +++ b/MobileGL/MG_Remote/Client/EmitTables.cpp @@ -1266,7 +1266,7 @@ namespace MobileGL::MG_Remote::Client { // The unit's binding is the frontend's and has just been written by the caller, so // the texture this record names is the one the server's SyncImageTextureBinding // will pull for the same unit. Read from MG_State::pGLContext and NOT through - // MGB_CTX: on this side of a split MGB_CTX is gPipeInputs, which is the SERVER's + // gPipeInputs: on this side of a split gPipeInputs is gPipeInputs, which is the SERVER's // view, and the client asking it a question is how the two halves come to disagree. if (MG_State::pGLContext != nullptr) { record.Res = PublishedTextureHandle( diff --git a/MobileGL/MG_Remote/Server/PipeApplier.cpp b/MobileGL/MG_Remote/Server/PipeApplier.cpp index 47923a5b..afa771af 100644 --- a/MobileGL/MG_Remote/Server/PipeApplier.cpp +++ b/MobileGL/MG_Remote/Server/PipeApplier.cpp @@ -573,7 +573,7 @@ namespace MobileGL::MG_Remote::Server { // Save the server-visible pack state, force neutral for the read, restore. Both go through // the applier's own set_pixel_pack_state entry point (MGPipeApplySetPixelPackState writes // gPipeInputs.m_pixelStore[0], which the backend's ReadPixels reads via - // MGB_CTX->GetPixelStoreParameters); the read is synchronous on this thread, so the window + // gPipeInputs->GetPixelStoreParameters); the read is synchronous on this thread, so the window // in which the pack state is neutral does not outlive the call. const MG_Pipe::PixelStoreParameters savedPack = MG_Pipe::gPipeInputs.GetPixelStoreParameters(/*isUnpack=*/false); diff --git a/MobileGL/MG_Remote/Server/SessionRuntime.h b/MobileGL/MG_Remote/Server/SessionRuntime.h index c7f7aec8..a8e05893 100644 --- a/MobileGL/MG_Remote/Server/SessionRuntime.h +++ b/MobileGL/MG_Remote/Server/SessionRuntime.h @@ -13,7 +13,7 @@ // session per process was a property of every file that named them. This slice gives each served // session its own {ServerSession, ServerLoop, PipeInputs} triple, held here, and resolves the two // singleton accessors through the CALLING THREAD's session - which is what makes the ~900 sites -// that spell gPipeInputs, MGB_CTX, ServerSession::Active() or ServerLoopInstance() find the right +// that spell gPipeInputs, gPipeInputs, ServerSession::Active() or ServerLoopInstance() find the right // one without one line of any of them moving. // // WHO IS A SESSION THREAD. Two threads per session, both created by the session itself: @@ -78,7 +78,7 @@ namespace MobileGL::MG_Remote::Server { void InstallSessionRuntimeHooks(); // THE SCOPE. Makes `runtime` the calling thread's session for as long as it lives: the - // session/loop the singleton accessors answer with, the PipeInputs block MGB_CTX reads, + // session/loop the singleton accessors answer with, the PipeInputs block gPipeInputs reads, // this session's segment resolver and this session's latch domain. Restores what was there // before on the way out (two nested scopes are not a shape anything uses, but a thread that // served one session and is then reused must not keep answering with the dead one). diff --git a/MobileGL/MG_Test/SanityTest.cpp b/MobileGL/MG_Test/SanityTest.cpp index 1d0a5df2..f93d06a7 100644 --- a/MobileGL/MG_Test/SanityTest.cpp +++ b/MobileGL/MG_Test/SanityTest.cpp @@ -5262,7 +5262,7 @@ TEST(DirectGLESVertexInputDraw, TheAttributeWalkTakesItsBuffersFromTheRecordNotT // THE FRONTEND, MOVED ON: every enabled attribute now points at C, and nothing was // re-emitted. A walk that read GetAllAttributes() answers {C}. The VAO is BOUND IN A REAL // CONTEXT rather than free-standing, because that is the only shape in which the revert - // this case exists to catch - MGB_CTX->GetBoundVertexArray()->GetAllAttributes() - has + // this case exists to catch - gPipeInputs->GetBoundVertexArray()->GetAllAttributes() - has // anything to read at all; a free-standing object would make the revert crash instead of // disagree, which is a red for the wrong reason. SharedPtr previousContext = Move(MG_State::pGLContext); diff --git a/MobileGL/MG_Test/ScopedPipeVerb.h b/MobileGL/MG_Test/ScopedPipeVerb.h index 1befd849..6b9d95d2 100644 --- a/MobileGL/MG_Test/ScopedPipeVerb.h +++ b/MobileGL/MG_Test/ScopedPipeVerb.h @@ -15,7 +15,7 @@ namespace MobileGL::MG_Test { // // A unit test that constructs a GLContext by hand and then calls a BACKEND helper // directly enters through no GL entry point, so no MGP_FILL ever fires (P1 brief D7) and - // in a push build the PipeInputs block the helper's MGB_CTX reads is empty and unstamped: + // in a push build the PipeInputs block the helper's gPipeInputs reads is empty and unstamped: // its first accessor read is Fatal{UnmigratedPipeInput, "Field@"}. The test is // right and the poison is right - what was missing is the verb, and this object is how a // test states it. Constructing it runs the real filler for `verb`, exactly the call @@ -30,7 +30,7 @@ namespace MobileGL::MG_Test { // scope ends. That matters when the suite runs as one process (a developer running // the test binary directly, rather than one ctest entry per case): without it, one // case's declaration would cover a later case that forgot to make one; - // - it is a no-op in the pull build, where MGB_CTX is the live context and there is + // - it is a no-op in the pull build, where gPipeInputs is the live context and there is // nothing to fill, so the pull build stays byte-identical. // // Place it the way MGP_FILL is placed in production (P1 brief D7): immediately BEFORE the diff --git a/scripts/gen_pipe.py b/scripts/gen_pipe.py index 562ca3bc..e36b7f08 100644 --- a/scripts/gen_pipe.py +++ b/scripts/gen_pipe.py @@ -32,7 +32,7 @@ from the catalogue (they all consume the same .def). Both modes refuse a catalogue whose call payload has no field list in PipeFields.def: a payload the G4 comparator cannot see is a payload MOBILEGL_PIPE_VERIFY is blind to. Both also refuse a field list that does not name every data member of its struct (or names one -that is not a member), and a backend accessor read through MGB_CTX-> / pGLContext-> that +that is not a member), and a backend accessor read through gPipeInputs-> / pGLContext-> that has no Coverage.def row (P1 brief D8, D12). """ @@ -463,10 +463,10 @@ def check_field_lists_cover_struct_members(field_lists, payloads, header_texts=N sys.exit("PipeFields.def does not cover its structs:\n " + "\n ".join(problems)) -ACCESSOR_READ_RE = re.compile(r"\b(?:MGB_CTX|pGLContext)\s*->\s*(\w+)") +ACCESSOR_READ_RE = re.compile(r"\b(?:gPipeInputs\.|pGLContext)\s*->\s*(\w+)") -# The scanner's NAMED exemptions: accessors a backend reads through MGB_CTX-> / pGLContext-> +# The scanner's NAMED exemptions: accessors a backend reads through gPipeInputs-> / pGLContext-> # that are NOT PipeInputs fields and never will be, each with the reason written down. A name # here is a DEBT ENTRY, not a silence: it exists so the gate can tell "scoped, named, phased" # from "forgot the row". @@ -486,7 +486,7 @@ SCAN_EXEMPT_ACCESSORS = { def scan_live_accessors(accessors, backend_dir=None, verbose=True): - """Every accessor a backend reads through MGB_CTX-> or pGLContext-> (comments and + """Every accessor a backend reads through gPipeInputs-> or pGLContext-> (comments and strings masked) must have a Coverage.def row - a read without a row is a PipeInputs field that does not exist. Rows no backend reads are printed, not refused (the dead GetBoundTransformFeedbackName row is deliberate). Returns the set of names read."""