From bf8b39a86745c89dcda9f23464056e2775ec151e Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 6 Sep 2026 01:46:50 -0400 Subject: [PATCH] [Refactor] (Magma): route every frontend read through MGB_CTX - 164 arrow sites sed'd, 49 non-arrow lines converted (43 asserts keep their meaning as MGB_CTX_LIVE); pull build byte-identical - Every MG_State::pGLContext-> in the seven DirectVulkan TUs becomes MGB_CTX-> (DirectVulkan.cpp 12, BackendObject_DirectVulkan.cpp 2, UniformManager.cpp 14, VkClearManager.cpp 1, VkRenderPassManager.cpp 3, VkTextureManager.cpp 2, VulkanRenderer.cpp 130 occurrences on 127 lines); each TU includes right after its MG_State/GLState/Core.h include (VkRenderPassManager.cpp after its include block, it never included Core.h). - The 43 MOBILEGL_ASSERT(pGLContext) / (pGLContext != nullptr) lines become MOBILEGL_ASSERT(MGB_CTX_LIVE, ...): identical in every INFO build (the macro is empty there) and still a null-context assert in a DEBUG build. - The six code-bearing guards are like-for-like pointer tests in the pull arm: if (MGB_CTX_LIVE) at the two InvalidateCompileEnv sites, MGB_CTX_LIVE in the XFB query counter condition and the ternary that snapshots the paused-primitive counter, !MGB_CTX_LIVE in BeginXfbCaptureForDraw, MGB_CTX_LIVE && in the provoking-vertex resolve. No semantic rewrite: under push MGB_CTX_LIVE is simply "a context exists", the real meaning of these guards is P2's business. - VertexInputStateFactory.h's comment stops naming pGLContext so purity gate C (grep -rc pGLContext MobileGL/MG_Backend/DirectVulkan) reads 0 in every file. - The 12 SyncPersistentMappedRange and 3 SyncGpuWrites sites of the D10 table are untouched; PipeStats AddCalls literals unchanged. - Proof on the pull build (Release/INFO, LTO off, vs feat/disaggregated@087685d1): symbol_report --threshold 0 -> 27799 symbols, 0 added / 0 removed / 0 resized / 0 renamed, .text 10792579 -> 10792579 (+0); nm --defined-only name set identical; ctest -N name set identical (2334); unit 1466/1466; DirectVulkan integration lane 427/427 on lavapipe (two ArmedWhenTheEnvironmentPinsItOn entries flake under -j 4 exactly as on the baseline and pass serially). The push build compiles and links. --- .../BackendObject_DirectVulkan.cpp | 9 +- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 95 +++---- .../DirectVulkan/Renderer/UniformManager.cpp | 47 ++-- .../Renderer/VertexInputStateFactory.h | 2 +- .../DirectVulkan/Renderer/VkClearManager.cpp | 3 +- .../Renderer/VkRenderPassManager.cpp | 7 +- .../Renderer/VkTextureManager.cpp | 5 +- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 259 +++++++++--------- 8 files changed, 217 insertions(+), 210 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp index 3a3bc0d1..450cb48c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp @@ -12,6 +12,7 @@ #include "SubgroupSupportPolicy.h" #include "MG_State/GLState/FramebufferState/FramebufferObject.h" #include "MG_State/GLState/Core.h" +#include #include "MG_State/GLState/TextureState/TextureState.h" #include "MG_Util/Classifiers/TextureEnumClassifier.h" #include "MG_Util/Converters/MGToGL/TextureEnumConverter.h" @@ -385,8 +386,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } UpdateDynamicBackendParameters(); UpdateAdvertisedExtensions(); - if (MG_State::pGLContext) { - MG_State::pGLContext->InvalidateCompileEnv(); + if (MGB_CTX_LIVE) { + MGB_CTX->InvalidateCompileEnv(); } PopulateFormatCapabilities(physicalDevice.handle, vkGetPhysicalDeviceFormatProperties, m_vulkanCaps, MutableFormatCapabilities()); @@ -783,8 +784,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { m_vulkanCaps = capabilities; UpdateDynamicBackendParameters(); UpdateAdvertisedExtensions(); - if (MG_State::pGLContext) { - MG_State::pGLContext->InvalidateCompileEnv(); + if (MGB_CTX_LIVE) { + MGB_CTX->InvalidateCompileEnv(); } MutableFormatCapabilities().Clear(); } diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index bb778cc2..0d5760b3 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -10,6 +10,7 @@ #include "DirectVulkanResourceState.h" #include "MG_Backend/BackendObjects.h" #include "MG_State/GLState/Core.h" +#include #include "MG_State/GLState/ErrorState/ErrorInfo.h" #include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h" #include "MG_Util/Converters/GLToMG/TextureEnumConverter.h" @@ -267,15 +268,15 @@ namespace MobileGL::MG_Backend::DirectVulkan { } MG_State::GLState::ProgramObject* TryGetDirectVulkanProgram(GLuint program) { - if (!MG_State::pGLContext->ValidateProgramName(program)) { + if (!MGB_CTX->ValidateProgramName(program)) { return nullptr; } - auto& programObject = MG_State::pGLContext->GetProgramObject(program); + auto& programObject = MGB_CTX->GetProgramObject(program); return programObject.get(); } const Uint8* ResolveIndirectCommandBytes(const void* indirect, SizeT requiredBytes, const char* label) { - auto drawBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { drawBuffer->SyncPersistentMappedRange(); const SizeT commandOffset = reinterpret_cast(indirect); @@ -334,64 +335,64 @@ 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(MG_State::pGLContext, "DirectVulkan::ClearBufferfi called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearBufferfv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearBufferuiv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearBufferiv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferfv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferiv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferuiv called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::ClearNamedFramebufferfi called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::ClearNamedFramebufferfi called with null GL context"); pVulkanRenderer->ClearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil); } void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawElementsIndirect called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawArraysIndirect called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirect called with null GL context"); if (drawcount <= 0) { return; @@ -399,7 +400,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 = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawArraysIndirect(mode, indirect, drawcount, stride); return; @@ -442,13 +443,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { void MultiDrawElementsIndirectCount(GLenum mode, GLenum type, const void* indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawElementsIndirectCount called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawElementsIndirectCount called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawElementsIndirectCount called with null GL context"); pVulkanRenderer->MultiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount, stride); } void MultiDrawArraysIndirectCount(GLenum mode, const void* indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MultiDrawArraysIndirectCount called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::MultiDrawArraysIndirectCount called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArraysIndirectCount called with null GL context"); if (maxdrawcount <= 0) { return; @@ -462,7 +463,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return; } - auto parameterBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto parameterBuffer = MGB_CTX->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; @@ -493,7 +494,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(MG_State::pGLContext, "DirectVulkan::DrawElementsInstancedBaseVertexBaseInstance called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsInstancedBaseVertexBaseInstance called with null GL context"); DrawIndexedCmd payload{}; payload.mode = mode; @@ -520,7 +521,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawElementsIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawElementsIndirect called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsIndirect called with null GL context"); const SizeT indexSize = MG_Util::GetGLTypeSize(type); if (indexSize == 0) { @@ -530,7 +531,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 = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawElementsIndirect(mode, type, indirect, 1, 0); return; @@ -564,7 +565,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(MG_State::pGLContext, "DirectVulkan::DrawArraysInstancedBaseInstance called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArraysInstancedBaseInstance called with null GL context"); DrawCmd payload{}; payload.mode = mode; @@ -579,11 +580,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void DrawArraysIndirect(GLenum mode, const void* indirect) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArraysIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawArraysIndirect called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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 = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (drawBuffer) { pVulkanRenderer->MultiDrawArraysIndirect(mode, indirect, 1, 0); return; @@ -613,13 +614,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(MG_State::pGLContext, "DirectVulkan::CopyTexImage2D called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::CopyTexSubImage2D called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::CopyTexSubImage2D called with null GL context"); pVulkanRenderer->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } void CopyImageSubData(const CopyImageEndpoint& src, @@ -628,32 +629,32 @@ 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(MG_State::pGLContext, "DirectVulkan::CopyImageSubData called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::GenerateMipmap called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::DispatchCompute called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DispatchCompute called with null GL context"); pVulkanRenderer->DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); } void DispatchComputeIndirect(GLintptr indirect) { MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DispatchComputeIndirect called with null VulkanRenderer"); - MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DispatchComputeIndirect called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::MemoryBarrier called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MemoryBarrier called with null GL context"); pVulkanRenderer->MemoryBarrier(barriers); } @@ -713,7 +714,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ? pActiveBackendObject->GetDynamicParameters().MaxShaderStorageBufferBindings : 0; if (storageBlockBinding >= static_cast(maxBindings)) { - MG_State::pGLContext->RecordError( + MGB_CTX->RecordError( ErrorCode::InvalidValue, MakeUnique("DirectVulkan", __func__, "Shader storage binding is out of range.")); return; @@ -738,24 +739,24 @@ namespace MobileGL::MG_Backend::DirectVulkan { } 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(MG_State::pGLContext, "DirectVulkan::ReadPixels called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::GetTexImage called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::GetTextureImage called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::Clear called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::Clear called with null GL context"); pVulkanRenderer->Clear(mask); } @@ -783,7 +784,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } const Uint8* indexBytes = nullptr; - const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); const auto& indexBufferShared = vao.GetIndexBufferBindingSlot().GetBoundObject(); if (indexBufferShared != nullptr) { const SizeT offset = reinterpret_cast(indices); @@ -814,7 +815,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(MG_State::pGLContext, "DirectVulkan::DrawArrays called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawArrays called with null GL context"); if (mode == GL_LINE_LOOP) { if (count < 2) { @@ -839,7 +840,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(MG_State::pGLContext, "DirectVulkan::DrawElements called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElements called with null GL context"); if (mode == GL_LINE_LOOP) { Vector closedIndices; @@ -862,7 +863,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(MG_State::pGLContext, "DirectVulkan::MultiDrawArrays called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::MultiDrawArrays called with null GL context"); if (drawcount <= 0) { return; } @@ -907,7 +908,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // MultiDrawIndexedCmd left the client-memory shape addressing a view whose byte // offset is a hardcoded 0, so UploadAndBindIndexBuffer saw a null client pointer, // declined the whole batch and painted nothing.) - const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); if (vao.GetIndexBufferBindingSlot().GetBoundObject() == nullptr) { for (GLsizei i = 0; i < drawcount; ++i) { if (count[i] <= 0) { @@ -968,13 +969,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(MG_State::pGLContext, "DirectVulkan::MultiDrawElements called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::DrawElementsBaseVertex called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::DrawElementsBaseVertex called with null GL context"); if (mode == GL_LINE_LOOP) { Vector closedIndices; if (BuildClosedLineLoopIndices(count, type, indices, closedIndices)) { @@ -998,14 +999,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(MG_State::pGLContext, "DirectVulkan::MultiDrawElementsBaseVertex called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(MG_State::pGLContext, "DirectVulkan::BlitFramebuffer called with null GL context"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "DirectVulkan::BlitFramebuffer called with null GL context"); pVulkanRenderer->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } @@ -1233,8 +1234,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } if (query->kind == VulkanTimerQuery::Kind::XfbGenerated && - !query->pausedPrimitivesCountedByGpu && MG_State::pGLContext != nullptr) { - primitives += MG_State::pGLContext->GetTransformFeedbackPausedPrimitiveCounter() - + !query->pausedPrimitivesCountedByGpu && MGB_CTX_LIVE) { + primitives += MGB_CTX->GetTransformFeedbackPausedPrimitiveCounter() - query->pausedPrimitiveSnapshot; } *outNanoseconds = primitives; @@ -1281,7 +1282,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { query->kind = generated ? VulkanTimerQuery::Kind::XfbGenerated : VulkanTimerQuery::Kind::XfbWritten; query->rendererGeneration = GetRendererGeneration(); query->pausedPrimitiveSnapshot = - MG_State::pGLContext ? MG_State::pGLContext->GetTransformFeedbackPausedPrimitiveCounter() : 0; + MGB_CTX_LIVE ? MGB_CTX->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 de816301..19094359 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp @@ -10,6 +10,7 @@ #include "MG_Backend/DirectVulkan/DirectVulkanResourceState.h" #include "MG_State/GLState/Core.h" +#include #include "MG_State/GLState/ProgramState/ProgramObject.h" #include "MG_State/GLState/TextureState/TextureObject1D.h" #include "MG_State/GLState/TextureState/TextureObject2D.h" @@ -503,7 +504,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 = MG_State::pGLContext->GetTextureUnitObject(unit); + auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); const auto& samplerOverride = textureUnit.GetSamplerObject(); const auto preferredTarget = programObj.samplerTextureTargetByBinding[binding]; SharedPtr fallbackHolder; @@ -552,7 +553,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } if (!IsValidSampledImageLayout(resource->layout)) { - auto drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + auto drawFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); FramebufferAttachmentType attachmentType = FramebufferAttachmentType::None; Int attachmentLevel = 0; if (drawFbo && @@ -779,7 +780,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 = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject(); + const auto& samplerOverride = MGB_CTX->GetTextureUnitObject(unit).GetSamplerObject(); const auto* effectiveSampler = samplerOverride ? samplerOverride.get() : texture->GetSamplerObject().get(); if (effectiveSampler == nullptr) return false; @@ -809,7 +810,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const ProgramFactory::VkProgramObject& programObj, Uint32 binding, SharedPtr& outTexture) { outTexture.reset(); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveSamplerTexture: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(), @@ -818,7 +819,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const Int location = programObj.samplerUniformLocationByBinding[binding]; const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); + auto& textureUnit = MGB_CTX->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 @@ -834,7 +835,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MG_State::GLState::ITextureObject* UniformManager::ResolveSamplerTextureRaw( const MG_State::GLState::ProgramObject& program, const ProgramFactory::VkProgramObject& programObj, Uint32 binding, Uint32 element) { - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveSamplerTextureRaw: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(), @@ -844,7 +845,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ResolveDescriptorElementLocation(program, programObj.samplerUniformLocationByBinding[binding], element); const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); + auto& textureUnit = MGB_CTX->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). @@ -989,7 +990,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkBufferView& outBufferView) { outBufferView = VK_NULL_HANDLE; MOBILEGL_ASSERT(m_bufferManager != nullptr, "ResolveStorageTexelBufferDescriptor: buffer manager is null"); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveStorageTexelBufferDescriptor: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageTexelBufferDescriptor: GL context is null"); MOBILEGL_ASSERT(frameIndex < m_frames.size(), "ResolveStorageTexelBufferDescriptor: frame index out of range"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), @@ -1013,7 +1014,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MOBILEGL_ASSERT(binding < programObj.samplerNumericDomainByBinding.size(), "ResolveStorageTexelBufferDescriptor: numeric domain binding %u out of range", binding); - auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(imageUnit); + auto& imageBinding = MGB_CTX->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 @@ -1149,7 +1150,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkDescriptorBufferInfo& outBufferInfo) const { outBufferInfo = {}; MOBILEGL_ASSERT(m_bufferManager != nullptr, "ResolveStorageBufferDescriptor: buffer manager is null"); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveStorageBufferDescriptor: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageBufferDescriptor: GL context is null"); MOBILEGL_ASSERT(binding < programObj.storageBlockIndexByBinding.size(), "ResolveStorageBufferDescriptor: binding %u out of range", binding); @@ -1186,12 +1187,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { ? static_cast(atomicCounterBinding) : GetShaderStorageBlockBinding(program, static_cast(blockIndex)) + element; const Uint32 bindingPointCount = - static_cast(MG_State::pGLContext->GetBufferBindingPointCount(bufferTarget)); + static_cast(MGB_CTX->GetBufferBindingPointCount(bufferTarget)); MOBILEGL_ASSERT(frontendBinding < bindingPointCount, "ResolveStorageBufferDescriptor: frontend binding %u out of range for block '%s'", frontendBinding, blockName.c_str()); - auto& bindingPoint = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, frontendBinding); + auto& bindingPoint = MGB_CTX->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 @@ -1263,7 +1264,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkDescriptorImageInfo& outImageInfo) const { outImageInfo = {}; MOBILEGL_ASSERT(m_textureManager != nullptr, "ResolveStorageImageDescriptor: texture manager is null"); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveStorageImageDescriptor: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "ResolveStorageImageDescriptor: GL context is null"); MOBILEGL_ASSERT(binding < programObj.samplerUniformLocationByBinding.size(), "ResolveStorageImageDescriptor: binding %u out of range", binding); @@ -1292,7 +1293,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } - auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(imageUnit); + auto& imageBinding = MGB_CTX->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 @@ -1648,7 +1649,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(MG_State::pGLContext != nullptr, "ResolveSampledBinding: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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(), @@ -1659,7 +1660,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } const Int unit = ResolveSamplerUnitIndex(program, location, binding); - auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); + auto& textureUnit = MGB_CTX->GetTextureUnitObject(unit); const TextureTarget preferredTarget = programObj.samplerTextureTargetByBinding[binding]; MG_State::GLState::ITextureObject* texture = textureUnit.GetBindingSlot(preferredTarget).GetBoundObject().get(); @@ -1803,7 +1804,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const ProgramFactory::VkProgramObject& programObj, Vector& outTextures) const { outTextures.clear(); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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. @@ -1847,7 +1848,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } - auto* texture = MG_State::pGLContext->GetImageTextureBinding(imageUnit).Texture.get(); + auto* texture = MGB_CTX->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 @@ -1885,7 +1886,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const ProgramFactory::VkProgramObject& programObj, Vector& outBindings) const { outBindings.clear(); - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, + MOBILEGL_ASSERT(MGB_CTX_LIVE, "CollectSamplerImageFeedback: GL context is null"); if (programObj.declinedDescriptors) return true; @@ -1935,7 +1936,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (imageUnit < 0 || imageUnit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) { return false; } - const auto& image = MG_State::pGLContext->GetImageTextureBinding(imageUnit); + const auto& image = MGB_CTX->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 && @@ -1965,7 +1966,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const void* outData = nullptr; VkDeviceSize outSize = 0; - MOBILEGL_ASSERT(MG_State::pGLContext != nullptr, "ResolveUniformBufferPayload: GL context is null"); + MOBILEGL_ASSERT(MGB_CTX_LIVE, "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, @@ -2010,12 +2011,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { const Uint32 frontendBinding = program.GetUniformBlockBinding(static_cast(blockIndex)); const Uint32 uniformBindingPointCount = - static_cast(MG_State::pGLContext->GetBufferBindingPointCount(BufferTarget::Uniform)); + static_cast(MGB_CTX->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 = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, frontendBinding); + auto& bindingPoint = MGB_CTX->GetBufferBindingPoint(BufferTarget::Uniform, frontendBinding); const auto& bufferObject = bindingPoint.GetBoundObject(); MOBILEGL_ASSERT(bufferObject != nullptr, "ResolveUniformBufferPayload: no UBO bound at frontend binding %u for block '%s'", diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.h index b14231bb..66dd6958 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.h @@ -130,7 +130,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // stale memo. // // Drawn from a process-wide source, never a per-instance counter: the VAO - // memos outlive this factory (they live on pGLContext's VAOs, the renderer + // memos outlive this factory (they live on the frontend context's VAOs, the renderer // is destroyed and recreated on EGL surface release/re-create), so a fresh // factory restarting at a dead factory's epoch value would honor its // dangling entry pointers. The constructor takes a value strictly greater diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp index e9191dc0..744f1e85 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -13,6 +13,7 @@ #include "VkTextureManager.h" #include "MG_State/GLState/Core.h" +#include #include "MG_Util/Converters/MGToStr/FramebufferEnumConverter.h" #include "MG_Util/Converters/MGToStr/TextureEnumConverter.h" @@ -54,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 (MG_State::pGLContext->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)) return; + if (MGB_CTX->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 7396fa2e..3adaf82c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp @@ -13,6 +13,7 @@ #include "MG_Util/Converters/MGToStr/FramebufferEnumConverter.h" #include "MG_Util/Converters/MGToVk/TextureEnumConverter.h" #include "MG_Util/Metrics/TextureMetrics.h" +#include namespace MobileGL::MG_Backend::DirectVulkan { static Bool TryResolveSampleCountFlagBits(Int requestedSamples, VkSampleCountFlagBits& outSampleCount) { @@ -610,7 +611,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 = - MG_State::pGLContext->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MGB_CTX->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]))); @@ -962,7 +963,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const VkImageLayout trackedRbLayout = rbResource->layout; const Bool rbFramebufferSrgb = - MG_State::pGLContext->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MGB_CTX->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); const VkFormat rbAttachmentFormat = ResolveSrgbAttachmentWriteFormat(rbResource->format, rbFramebufferSrgb); rbDesc.flags = 0; @@ -1108,7 +1109,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { textureResources.emplace_back(textureResource); desc.format = ResolveSrgbAttachmentWriteFormat( textureResource->format, - MG_State::pGLContext->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)); + MGB_CTX->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 0335f23b..d64ae924 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -11,6 +11,7 @@ #include "ProgramFactory.h" #include "MG_State/GLState/Core.h" +#include #include "MG_Util/Converters/MGToStr/TextureEnumConverter.h" #include "MG_Util/Converters/MGToVk/TextureEnumConverter.h" #include "MG_Util/Metrics/PipeStats.h" @@ -806,7 +807,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 = MG_State::pGLContext->GetTextureObject(texture.GetExternalIndex()); + const auto& liveTexture = MGB_CTX->GetTextureObject(texture.GetExternalIndex()); if (liveTexture && liveTexture.get() == &texture) { aliveTexture = liveTexture; } else { @@ -949,7 +950,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } const Bool framebufferSrgbEnabled = - MG_State::pGLContext->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb); + MGB_CTX->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 289d2c98..88869629 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -14,6 +14,7 @@ #include "VertexInputStateBuilder.h" #include "MG_State/GLState/Core.h" +#include #include "MG_State/GLState/ProgramState/ProgramObject.h" #include "MG_State/GLState/ProgramState/ShaderObject.h" #include "MG_State/GLState/SamplerState/SamplerObject.h" @@ -460,12 +461,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 = MG_State::pGLContext->GetViewportIndexed(index); + const FloatVec4& stored = MGB_CTX->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 = MG_State::pGLContext->GetDepthRangeIndexed(index); + const FloatVec2& depthRange = MGB_CTX->GetDepthRangeIndexed(index); const IntVec2 logicalExtent = isDefaultFramebuffer ? ResolveDefaultFramebufferLogicalExtent(preTransform, framebufferExtent) : framebufferExtent; @@ -520,7 +521,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyBlendConstants(VkCommandBuffer commandBuffer) { - const FloatVec4& blendColor = MG_State::pGLContext->GetBlendColor(); + const FloatVec4& blendColor = MGB_CTX->GetBlendColor(); const float blendConstants[4] = { blendColor.x(), blendColor.y(), @@ -553,8 +554,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyPolygonOffsetState(VkCommandBuffer commandBuffer) { - const Float constantFactor = MG_State::pGLContext->GetPolygonOffsetUnits(); - const Float slopeFactor = MG_State::pGLContext->GetPolygonOffsetFactor(); + const Float constantFactor = MGB_CTX->GetPolygonOffsetUnits(); + const Float slopeFactor = MGB_CTX->GetPolygonOffsetFactor(); auto& shadow = g_dynamicStateShadow; if (shadow.depthBiasValid && shadow.depthBiasConstantFactor == constantFactor && shadow.depthBiasSlopeFactor == slopeFactor) { @@ -567,7 +568,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyLineWidthState(VkCommandBuffer commandBuffer) { - Float lineWidth = MG_State::pGLContext->GetLineWidth(); + Float lineWidth = MGB_CTX->GetLineWidth(); if (MG_Backend::pActiveBackendObject != nullptr) { const auto& dynamicParameters = MG_Backend::pActiveBackendObject->GetDynamicParameters(); const Float minLineWidth = dynamicParameters.AliasedLineWidthRangeMin; @@ -646,8 +647,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void ApplyStencilState(VkCommandBuffer commandBuffer) { - const StencilFaceState& frontStencil = MG_State::pGLContext->GetStencilState(StencilFace::Front); - const StencilFaceState& backStencil = MG_State::pGLContext->GetStencilState(StencilFace::Back); + const StencilFaceState& frontStencil = MGB_CTX->GetStencilState(StencilFace::Front); + const StencilFaceState& backStencil = MGB_CTX->GetStencilState(StencilFace::Back); const Uint32 frontReference = static_cast(std::max(frontStencil.Ref, 0)); const Uint32 backReference = static_cast(std::max(backStencil.Ref, 0)); @@ -1240,11 +1241,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void RecordClearBufferError(const char* func, ErrorCode code, const char* message) { - MG_State::pGLContext->RecordError(code, MakeUnique("DirectVulkan", func, message)); + MGB_CTX->RecordError(code, MakeUnique("DirectVulkan", func, message)); } static void RecordTextureCopyError(const char* func, ErrorCode code, const char* message) { - MG_State::pGLContext->RecordError(code, MakeUnique("DirectVulkan", func, message)); + MGB_CTX->RecordError(code, MakeUnique("DirectVulkan", func, message)); } static Bool HasDistinctCompleteDepthStencilTextureAttachments( @@ -1300,7 +1301,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } static void RecordUnsupportedFramebufferError(const char* func) { - MG_State::pGLContext->RecordError( + MGB_CTX->RecordError( ErrorCode::InvalidFramebufferOperation, MakeUnique( "DirectVulkan", func, @@ -2768,7 +2769,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 = MG_State::pGLContext->GetClampReadColor(); + const GLenum clampMode = MGB_CTX->GetClampReadColor(); const Bool clamp = clampMode == GL_TRUE || (clampMode == GL_FIXED_ONLY && !IsFloatingPointReadbackFormat(srcFormat)); if (clamp) { @@ -2985,7 +2986,7 @@ void main() { inline ProgramFactory::CompileOptionFlags GetShaderTransformFlags(VkSurfaceTransformFlagBitsKHR preTransform) { ProgramFactory::CompileOptionFlags flags = ProgramFactory::CompileOptionBit::PositionZRemap; const auto& currentDrawFBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (currentDrawFBO != nullptr && currentDrawFBO->IsDefaultFramebuffer()) { flags |= ProgramFactory::CompileOptionBit::PositionYFlip; // gl_FragCoord follows the same rule the default-framebuffer RECTANGLES follow @@ -3445,8 +3446,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 = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); + MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestart) || + MGB_CTX->IsCapabilityEnabled(CapabilityInput::PrimitiveRestartFixedIndex); const Uint32 restartSentinel = indexSize == 1 ? 0xFFu : indexSize == 2 ? 0xFFFFu : 0xFFFFFFFFu; Uint32 maxIndex = 0; Bool sawIndex = false; @@ -3923,7 +3924,7 @@ void main() { } const auto glType = programObj.vertexInputTypes[location]; - const auto& currentValue = MG_State::pGLContext->GetCurrentVertexAttribute(location); + const auto& currentValue = MGB_CTX->GetCurrentVertexAttribute(location); VkFormat format = VK_FORMAT_UNDEFINED; const void* sourceData = nullptr; VkDeviceSize sourceSize = 0; @@ -4057,7 +4058,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 = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); if (rsp.PrimitiveRestartEnabled && !rsp.PrimitiveRestartFixedIndexEnabled) { const Uint32 restartIndex = rsp.PrimitiveRestartIndex; const Uint32 fixedMax = MG_Util::FixedRestartIndexForGLType(pIndexBufferView->indexType); @@ -4812,9 +4813,9 @@ void main() { Uint32 VulkanRenderer::ResolveEffectiveSampleMask(VkSampleCountFlagBits rasterizationSamples) const { constexpr Uint32 kFullCoverage = 0xffffffffu; if (rasterizationSamples == VK_SAMPLE_COUNT_1_BIT) return kFullCoverage; - if (!MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Multisample)) return kFullCoverage; - if (!MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::SampleMask)) return kFullCoverage; - return MG_State::pGLContext->GetRenderStateParameters().SampleMaskValue; + if (!MGB_CTX->IsCapabilityEnabled(CapabilityInput::Multisample)) return kFullCoverage; + if (!MGB_CTX->IsCapabilityEnabled(CapabilityInput::SampleMask)) return kFullCoverage; + return MGB_CTX->GetRenderStateParameters().SampleMaskValue; } Uint64 VulkanRenderer::ComputePipelineStateHash(Uint32 colorAttachmentCount, @@ -4825,7 +4826,7 @@ void main() { // field (RenderState.cpp), so the hashed values are bit-identical. This runs on // every draw whose pipeline-state version moved (a per-draw GL_BLEND toggle), // where the accessor-call overhead dominated the hash itself. - const RenderStateParameters& p = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& p = MGB_CTX->GetRenderStateParameters(); Uint64 capabilityBits = 0; capabilityBits |= p.CullFaceEnabled ? 1ull << 0 : 0; capabilityBits |= p.DepthTestEnabled ? 1ull << 1 : 0; @@ -4937,7 +4938,7 @@ void main() { if (!(aspects & DrawSetupAspect::IndexBuffer) || pIndexBufferView == nullptr) { return false; } - const RenderStateParameters& rsp = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); if (rsp.PrimitiveRestartFixedIndexEnabled) { return true; } @@ -4981,7 +4982,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 = MG_State::pGLContext->GetPipelineStateVersion(); + const Uint renderStateVersion = MGB_CTX->GetPipelineStateVersion(); if (!m_pipelineStateHashValid || m_pipelineStateHashVersion != renderStateVersion || m_pipelineStateHashColorCount != renderPassEntry.colorAttachmentCount || m_pipelineStateHashSampleCount != renderPassEntry.sampleCount) { @@ -5169,22 +5170,22 @@ void main() { syntheticVertexInputState.pNext = vis.state.pNext; pipelineVertexInputState = &syntheticVertexInputState; } - auto cullFaceEnabled = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace); - auto depthTestEnabled = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest); + auto cullFaceEnabled = MGB_CTX->IsCapabilityEnabled(CapabilityInput::CullFace); + auto depthTestEnabled = MGB_CTX->IsCapabilityEnabled(CapabilityInput::DepthTest); auto polygonOffsetFillEnabled = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) && + MGB_CTX->IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) && DrawModeUsesPolygonFill(mode); auto rasterizerDiscardEnabled = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard); + MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard); auto colorLogicOpEnabled = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ColorLogicOp) && m_logicOpFeatureEnabled; - auto stencilTestEnabled = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::StencilTest); + MGB_CTX->IsCapabilityEnabled(CapabilityInput::ColorLogicOp) && m_logicOpFeatureEnabled; + auto stencilTestEnabled = MGB_CTX->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. { const auto& gatingFbo = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->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); @@ -5196,10 +5197,10 @@ void main() { } } } - const StencilFaceState& frontStencil = MG_State::pGLContext->GetStencilState(StencilFace::Front); - const StencilFaceState& backStencil = MG_State::pGLContext->GetStencilState(StencilFace::Back); + const StencilFaceState& frontStencil = MGB_CTX->GetStencilState(StencilFace::Front); + const StencilFaceState& backStencil = MGB_CTX->GetStencilState(StencilFace::Back); const VkPolygonMode requestedPolygonMode = - MG_Util::ConvertPolygonModeToVkEnum(MG_State::pGLContext->GetPolygonModeFront()); + MG_Util::ConvertPolygonModeToVkEnum(MGB_CTX->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 = @@ -5284,18 +5285,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 && - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::SampleShading), - .minSampleShading = MG_State::pGLContext->GetMinSampleShadingValue(), + MGB_CTX->IsCapabilityEnabled(CapabilityInput::SampleShading), + .minSampleShading = MGB_CTX->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(MG_State::pGLContext->GetPatchVertices()), + .patchControlPoints = static_cast(MGB_CTX->GetPatchVertices()), .viewportCount = ResolveDrawViewportCount(programObj.writesViewportIndexBuiltin), .polygonMode = effectivePolygonMode, .cullMode = cullFaceEnabled - ? MG_Util::ConvertCullFaceModeToVkEnum(MG_State::pGLContext->GetCullFaceMode(), invertClockwise) + ? MG_Util::ConvertCullFaceModeToVkEnum(MGB_CTX->GetCullFaceMode(), invertClockwise) : VK_CULL_MODE_NONE, .frontFace = VK_FRONT_FACE_CLOCKWISE, // Read the geometry stage off the program's own shader list rather than @@ -5309,13 +5310,13 @@ void main() { .provokingVertexMode = SelectProvokingVertexMode( vkTopology, ProgramCapturesXfbFromGeometryStage(program)), .depthTestEnable = depthTestEnabled, - .depthWriteEnable = depthTestEnabled && MG_State::pGLContext->GetDepthMask(), + .depthWriteEnable = depthTestEnabled && MGB_CTX->GetDepthMask(), .depthBiasEnable = polygonOffsetFillEnabled, .rasterizerDiscardEnable = rasterizerDiscardEnabled, .logicOpEnable = colorLogicOpEnabled, .stencilTestEnable = stencilTestEnabled, - .depthCompareOp = MG_Util::ConvertDepthTestFuncToVkEnum(MG_State::pGLContext->GetDepthFunc()), - .logicOp = MG_Util::ConvertLogicOperationToVkEnum(MG_State::pGLContext->GetLogicOp()), + .depthCompareOp = MG_Util::ConvertDepthTestFuncToVkEnum(MGB_CTX->GetDepthFunc()), + .logicOp = MG_Util::ConvertLogicOperationToVkEnum(MGB_CTX->GetLogicOp()), .frontStencilFailOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.FailOp), .frontStencilPassOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.PassDepthPassOp), .frontStencilDepthFailOp = MG_Util::ConvertStencilOperationToVkEnum(frontStencil.PassDepthFailOp), @@ -5351,8 +5352,8 @@ void main() { // handed back after the application changed them. if (programObj.needsPassthroughTessControl && programObj.passthroughTessControlEmulatable && vkTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { - const FloatVec4& defaultOuterLevel = MG_State::pGLContext->GetPatchDefaultOuterLevel(); - const FloatVec2& defaultInnerLevel = MG_State::pGLContext->GetPatchDefaultInnerLevel(); + const FloatVec4& defaultOuterLevel = MGB_CTX->GetPatchDefaultOuterLevel(); + const FloatVec2& defaultInnerLevel = MGB_CTX->GetPatchDefaultInnerLevel(); payload.passthroughTessControlKey = ProgramFactory::ComputePassthroughTessControlKey( payload.patchControlPoints, defaultOuterLevel, defaultInnerLevel, programObj.passthroughPerVertexMembers); @@ -5404,7 +5405,7 @@ void main() { "GetOrCreatePipeline: colorAttachmentCount=%u exceeds payload capacity", payload.colorAttachmentCount); const auto& drawFboBinding = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); MOBILEGL_ASSERT(drawFboBinding != nullptr, "GetOrCreatePipeline: draw framebuffer is null"); const Bool isDefaultDrawFbo = drawFboBinding->IsDefaultFramebuffer(); const auto& drawBuffers = drawFboBinding->GetDrawBuffers(); @@ -5432,14 +5433,14 @@ void main() { BlendFactor dstAlpha = BlendFactor::Zero; BlendEquation colorEquation = BlendEquation::Add; BlendEquation alphaEquation = BlendEquation::Add; - MG_State::pGLContext->GetBlendFuncIndexed(i, srcRGB, dstRGB, srcAlpha, dstAlpha); - MG_State::pGLContext->GetBlendEquationIndexed(i, colorEquation, alphaEquation); - const Bool blendEnabled = MG_State::pGLContext->IsCapabilityEnabledIndexed(CapabilityInput::Blend, i); + MGB_CTX->GetBlendFuncIndexed(i, srcRGB, dstRGB, srcAlpha, dstAlpha); + MGB_CTX->GetBlendEquationIndexed(i, colorEquation, alphaEquation); + const Bool blendEnabled = MGB_CTX->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 = - MG_State::pGLContext->GetColorMaskIndexed(m_independentBlendFeatureEnabled ? i : 0); + MGB_CTX->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) | @@ -5855,7 +5856,7 @@ void main() { VkRect2D VulkanRenderer::ComputeGLScissorRect(Uint32 index, const IntVec2& extent, VkSurfaceTransformFlagBitsKHR preTransform, Bool isDefaultFbo) const { - const auto& parameters = MG_State::pGLContext->GetRenderStateParameters(); + const auto& parameters = MGB_CTX->GetRenderStateParameters(); if ((parameters.ScissorTestEnabledMask & (1u << index)) == 0) { VkRect2D full{}; full.offset = {0, 0}; @@ -5916,7 +5917,7 @@ void main() { // One compare for the whole tail: see the gate's declaration in // DynamicStateShadow for why (version, extent, default-FBO flag) pins every // input the six Apply* below read. - const Uint paramsVersion = MG_State::pGLContext->GetRenderStateParametersVersion(); + const Uint paramsVersion = MGB_CTX->GetRenderStateParametersVersion(); if (shadow.dynamicTailValid && shadow.dynamicTailParamsVersion == paramsVersion && shadow.dynamicTailExtentX == extent.x() && shadow.dynamicTailExtentY == extent.y() && shadow.dynamicTailIsDefaultFbo == isDefaultFbo) { @@ -5940,7 +5941,7 @@ void main() { // re-derive the value its shadow already holds. DynamicStateShadow::DynamicTailKey key; { - const RenderStateParameters& p = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& p = MGB_CTX->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(); @@ -6016,7 +6017,7 @@ void main() { MOBILEGL_ASSERT( [&] { const auto& fbo = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); return isDefaultFbo == (fbo != nullptr && fbo->IsDefaultFramebuffer()); }(), "GetBaseTransformFlagsRaw: isDefaultFbo does not match the bound draw framebuffer"); @@ -6040,7 +6041,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 = *MG_State::pGLContext->GetProgramForDraw(); + const auto& program = *MGB_CTX->GetProgramForDraw(); const Uint64 programLifetimeId = program.GetLifetimeId(); SetupDrawSnapshot* snapPtr = nullptr; { @@ -6088,7 +6089,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 && - MG_State::pGLContext->IsTransformFeedbackActive() && + MGB_CTX->IsTransformFeedbackActive() && program.GetTransformFeedbackVaryingCount() > 0; const Bool snapHasXfbCapture = static_cast(ProgramFactory::CompileOptionFlags(snap.resolvedTransformFlags) & @@ -6102,12 +6103,12 @@ 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 = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); const Bool vaoMoved = static_cast(&vao) != snap.vao || vao.GetLifetimeId() != snap.vaoLifetimeId || vao.GetConfigVersion() != snap.vaoConfigVersion; const auto& drawFbo = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); if (static_cast(drawFbo.get()) != snap.drawFbo || drawFbo->GetLifetimeId() != snap.drawFboLifetimeId || drawFbo->GetObjectVersion() != snap.fboVersion) { @@ -6118,8 +6119,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 = MG_State::pGLContext->GetPipelineStateVersion(); - const Uint64 bindGeneration = MG_State::pGLContext->GetTextureBindGeneration(); + const Uint renderStateVersion = MGB_CTX->GetPipelineStateVersion(); + const Uint64 bindGeneration = MGB_CTX->GetTextureBindGeneration(); const Bool renderStateMoved = renderStateVersion != snap.renderStateVersion; const Bool bindsMoved = bindGeneration != snap.bindGeneration; if (renderStateMoved) { @@ -6127,7 +6128,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 = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); const Bool drawUsesDepthStencil = rsp.DepthTestEnabled || rsp.StencilTestEnabled; if (drawUsesDepthStencil != snap.drawUsesDepthStencil) { return false; @@ -6301,7 +6302,7 @@ void main() { if (contentSum != snap.sampledContentSum || paramsSum != snap.sampledParamsSum) { return false; } - const Uint64 samplingResolutionGeneration = MG_State::pGLContext->GetSamplingResolutionGeneration(); + const Uint64 samplingResolutionGeneration = MGB_CTX->GetSamplingResolutionGeneration(); if (samplingResolutionGeneration != snap.samplingResolutionGeneration) { // Decline, not re-arm: snap.resolvedTransformFlags bakes the // ExplicitLod0Sampling verdict, which reads the effective sampler's @@ -6431,7 +6432,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 = *MG_State::pGLContext->GetProgramForDraw(); + const auto& drawProgram = *MGB_CTX->GetProgramForDraw(); if (!drawProgram.GetLinkStatus() || !drawProgram.GetSpirvStatus()) { MGLOG_D("SetupDraw skipped: program=%u is linked=%d spirv=%d", drawProgram.GetExternalIndex(), static_cast(drawProgram.GetLinkStatus()), @@ -6461,15 +6462,15 @@ void main() { MG_Util::PipeStats::AddCalls(MG_Util::PipeStats::CallClass::AccessorCalls, 3); } const auto& drawFbo = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + MGB_CTX->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 = *MG_State::pGLContext->GetBoundVertexArray(); - const auto& program = *MG_State::pGLContext->GetProgramForDraw(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); + const auto& program = *MGB_CTX->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. @@ -6509,7 +6510,7 @@ void main() { ProgramFactory::CompileOptionFlags transformFlags = ProgramFactory::CompileOptionFlags(GetBaseTransformFlagsRaw(drawFboIsDefault)); // Captured draws take the xfb-decorated program variant. - if (m_transformFeedbackFeatureEnabled && MG_State::pGLContext->IsTransformFeedbackActive() && + if (m_transformFeedbackFeatureEnabled && MGB_CTX->IsTransformFeedbackActive() && program.GetTransformFeedbackVaryingCount() > 0) { transformFlags |= ProgramFactory::CompileOptionBit::XfbCapture; } @@ -6523,13 +6524,13 @@ void main() { { const Uint64 lodProgramLifetimeId = program.GetLifetimeId(); const Uint32 lodProgramVersion = program.GetBackendStateVersion(); - const Uint64 lodBindGeneration = MG_State::pGLContext->GetTextureBindGeneration(); + const Uint64 lodBindGeneration = MGB_CTX->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 = MG_State::pGLContext->GetSamplingResolutionGeneration(); + const Uint64 lodSamplingGeneration = MGB_CTX->GetSamplingResolutionGeneration(); Bool lodMemoHit = false; if (m_lastLodDecisionValid && m_lastSampledSetValid && m_lastLodProgramLifetimeId == lodProgramLifetimeId && @@ -6647,7 +6648,7 @@ void main() { { const Uint64 programLifetimeId = program.GetLifetimeId(); const Uint32 programVersion = program.GetBackendStateVersion(); - const Uint64 bindGeneration = MG_State::pGLContext->GetTextureBindGeneration(); + const Uint64 bindGeneration = MGB_CTX->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 @@ -6666,7 +6667,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 = MG_State::pGLContext->GetSamplingResolutionGeneration(); + const Uint64 samplingGeneration = MGB_CTX->GetSamplingResolutionGeneration(); const Bool sampledSetUnchanged = m_lastSampledSetValid && m_lastSampledSetProgramLifetimeId == programLifetimeId && m_lastSampledSetProgramVersion == programVersion && @@ -6827,8 +6828,8 @@ void main() { // pass flavor (GL: a disabled depth/stencil test neither reads nor writes // its buffer). const Bool drawUsesDepthStencil = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest) || - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::StencilTest); + MGB_CTX->IsCapabilityEnabled(CapabilityInput::DepthTest) || + MGB_CTX->IsCapabilityEnabled(CapabilityInput::StencilTest); auto* renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired, drawUsesDepthStencil); // nullptr: the framebuffer has an attachment DirectVulkan cannot represent (a texture the @@ -6969,8 +6970,8 @@ void main() { snap.fboVersion = drawFbo->GetObjectVersion(); snap.drawFboIsDefault = drawFboIsDefault; snap.viewportCount = ResolveDrawViewportCount(programObj.writesViewportIndexBuiltin); - snap.renderStateVersion = MG_State::pGLContext->GetPipelineStateVersion(); - snap.bindGeneration = MG_State::pGLContext->GetTextureBindGeneration(); + snap.renderStateVersion = MGB_CTX->GetPipelineStateVersion(); + snap.bindGeneration = MGB_CTX->GetTextureBindGeneration(); snap.baseTransformFlags = GetBaseTransformFlagsRaw(drawFboIsDefault); snap.resolvedTransformFlags = transformFlags.GetRaw(); snap.renderPassHash = nowActiveRenderPass->hash; @@ -6996,7 +6997,7 @@ void main() { snap.programObj = nullptr; snap.programFactoryEpoch = 0; } - snap.samplingResolutionGeneration = MG_State::pGLContext->GetSamplingResolutionGeneration(); + snap.samplingResolutionGeneration = MGB_CTX->GetSamplingResolutionGeneration(); Uint64 snapContentSum = 0; Uint64 snapParamsSum = 0; // Per-entry copies of this draw's sampled set (the scratch vectors @@ -7033,7 +7034,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 = *MG_State::pGLContext->GetProgramForDispatch(); + const auto& program = *MGB_CTX->GetProgramForDispatch(); if (!program.GetLinkStatus() || !program.GetSpirvStatus()) { MGLOG_E_ONCE("DispatchCompute skipped: program=%u has no optimized SPIR-V", program.GetExternalIndex()); @@ -7085,7 +7086,7 @@ void main() { m_textureManager->CollectGarbage(); auto& frame = m_frameContext.GetCurrent(); // See DispatchCompute: the dispatch accessor, not the draw one. - const auto& program = *MG_State::pGLContext->GetProgramForDispatch(); + const auto& program = *MGB_CTX->GetProgramForDispatch(); if (!program.GetLinkStatus() || !program.GetSpirvStatus()) { MGLOG_E_ONCE("DispatchComputeIndirect skipped: program=%u has no optimized SPIR-V", program.GetExternalIndex()); @@ -7129,7 +7130,7 @@ void main() { return; } - auto indirectBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DispatchIndirect).GetBoundObject(); + auto indirectBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DispatchIndirect).GetBoundObject(); if (!indirectBuffer) { MGLOG_E_ONCE("DispatchComputeIndirect skipped: GL_DISPATCH_INDIRECT_BUFFER is not bound"); return; @@ -7203,10 +7204,10 @@ void main() { VkClearRect clearRect{}; clearRect.rect = framebuffer.IsDefaultFramebuffer() - ? MakeDefaultFramebufferScissorRect(MG_State::pGLContext->GetScissorBox(), + ? MakeDefaultFramebufferScissorRect(MGB_CTX->GetScissorBox(), renderPassEntry->extent, m_swapchainObject.GetPreTransform()) - : MakeClampedScissorRect(MG_State::pGLContext->GetScissorBox(), renderPassEntry->extent); + : MakeClampedScissorRect(MGB_CTX->GetScissorBox(), renderPassEntry->extent); clearRect.baseArrayLayer = 0; // GL 3.3 §4.4.7: clearing a layered framebuffer clears every layer. clearRect.layerCount = renderPassEntry->layers; @@ -7254,10 +7255,10 @@ void main() { return; } // GL 3.3 §3.1: when RASTERIZER_DISCARD is enabled, Clear and ClearBuffer* are ignored. - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { + if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return; } - auto* fbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); + auto* fbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); MOBILEGL_ASSERT(fbo, "VulkanRenderer::Clear: draw framebuffer not found (fbo == nullptr)"); if (IsUnsupportedFramebufferForDirectVulkan(*fbo)) { RecordUnsupportedFramebufferError(__func__); @@ -7265,16 +7266,16 @@ void main() { } ClearFramebufferPayload payload { - .color = MG_State::pGLContext->GetClearColor(), - .depth = MG_State::pGLContext->GetClearDepth(), - .stencil = MG_State::pGLContext->GetClearStencil() + .color = MGB_CTX->GetClearColor(), + .depth = MGB_CTX->GetClearDepth(), + .stencil = MGB_CTX->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 (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { VkClearRect clearRect{}; switch (PrepareScissoredClear(*fbo, clearRect)) { case ScissoredClearPrep::NoOp: @@ -7297,7 +7298,7 @@ void main() { continue; } - const BoolVec4 colorMask = MG_State::pGLContext->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { continue; } @@ -7324,7 +7325,7 @@ void main() { } VkImageAspectFlags depthStencilAspects = 0; - if ((mask & GL_DEPTH_BUFFER_BIT) != 0 && MG_State::pGLContext->GetDepthMask()) { + if ((mask & GL_DEPTH_BUFFER_BIT) != 0 && MGB_CTX->GetDepthMask()) { const auto& depthAttachment = fbo->GetAttachment(FramebufferAttachmentType::Depth); if (depthAttachment.IsComplete()) { depthStencilAspects |= VK_IMAGE_ASPECT_DEPTH_BIT; @@ -7337,7 +7338,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 = - MG_State::pGLContext->GetStencilState(StencilFace::Front).WriteMask; + MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { depthStencilAspects |= VK_IMAGE_ASPECT_STENCIL_BIT; } else if (stencilWriteMask != 0) { @@ -7366,11 +7367,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 && !MG_State::pGLContext->GetDepthMask()) { + if ((deferredMask & GL_DEPTH_BUFFER_BIT) != 0 && !MGB_CTX->GetDepthMask()) { deferredMask &= ~static_cast(GL_DEPTH_BUFFER_BIT); } if ((deferredMask & GL_STENCIL_BUFFER_BIT) != 0) { - const Uint32 stencilWriteMask = MG_State::pGLContext->GetStencilState(StencilFace::Front).WriteMask; + const Uint32 stencilWriteMask = MGB_CTX->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"); @@ -7386,7 +7387,7 @@ void main() { if (drawBuffers[drawBufferIndex] == FramebufferAttachmentType::None) { continue; } - const BoolVec4 colorMask = MG_State::pGLContext->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); const Bool full = colorMask.r() && colorMask.g() && colorMask.b() && colorMask.a(); if (full) { anyFullMask = true; @@ -7407,7 +7408,7 @@ void main() { if (attachmentType == FramebufferAttachmentType::None) { continue; } - const BoolVec4 colorMask = MG_State::pGLContext->GetColorMaskIndexed(drawBufferIndex); + const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(drawBufferIndex); if (!(colorMask.r() && colorMask.g() && colorMask.b() && colorMask.a())) { continue; } @@ -7436,7 +7437,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 (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { + if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return; } if (IsUnsupportedFramebufferForDirectVulkan(framebuffer)) { @@ -7478,7 +7479,7 @@ void main() { } // GL 3.3 §4.2.3: ClearBuffer* is clipped by GL_SCISSOR_TEST exactly like Clear. - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { VkClearRect clearRect{}; switch (PrepareScissoredClear(framebuffer, clearRect)) { case ScissoredClearPrep::NoOp: @@ -7509,9 +7510,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 MG_State::pGLContext->GetDepthMask(); }; + const auto depthClearAllowed = [&]() -> Bool { return MGB_CTX->GetDepthMask(); }; const auto stencilClearAllowed = [&]() -> Bool { - const Uint32 stencilWriteMask = MG_State::pGLContext->GetStencilState(StencilFace::Front).WriteMask; + const Uint32 stencilWriteMask = MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { return true; } @@ -7523,7 +7524,7 @@ void main() { switch (buffer) { case GL_COLOR: { - const BoolVec4 colorMask = MG_State::pGLContext->GetColorMaskIndexed(static_cast(drawbuffer)); + const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(static_cast(drawbuffer)); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { return; } @@ -7580,7 +7581,7 @@ void main() { if (!attachment.IsComplete()) { return; } - const BoolVec4 colorMask = MG_State::pGLContext->GetColorMaskIndexed(static_cast(drawbuffer)); + const BoolVec4 colorMask = MGB_CTX->GetColorMaskIndexed(static_cast(drawbuffer)); if (!colorMask.r() && !colorMask.g() && !colorMask.b() && !colorMask.a()) { return; } @@ -7598,7 +7599,7 @@ void main() { MakeVkClearColorValue(clearPayload, ColorFormatLacksAlpha(colorTexture)); } else { VkImageAspectFlags aspects = 0; - if ((clearPayload.mask & GL_DEPTH_BUFFER_BIT) != 0 && MG_State::pGLContext->GetDepthMask() && + if ((clearPayload.mask & GL_DEPTH_BUFFER_BIT) != 0 && MGB_CTX->GetDepthMask() && framebuffer.GetAttachment(FramebufferAttachmentType::Depth).IsComplete()) { aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; } @@ -7606,7 +7607,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 = - MG_State::pGLContext->GetStencilState(StencilFace::Front).WriteMask; + MGB_CTX->GetStencilState(StencilFace::Front).WriteMask; if ((stencilWriteMask & 0xFFu) == 0xFFu) { aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; } else if (stencilWriteMask != 0) { @@ -7625,7 +7626,7 @@ void main() { void VulkanRenderer::QueueClearBufferPayload(GLenum buffer, GLint drawbuffer, const ClearAttachmentPayload& clearPayload) { - auto* fbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); + auto* fbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject().get(); if (!fbo) { return; } @@ -8583,8 +8584,8 @@ void main() { void VulkanRenderer::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - auto readFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); - auto drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto drawFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); BlitNamedFramebuffer(readFbo, drawFbo, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } @@ -8616,8 +8617,8 @@ void main() { // The scissor test clips blit writes: intersect the destination rectangle with // the scissor box and shrink the source proportionally. - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { - const IntVec4& scissor = MG_State::pGLContext->GetScissorBox(); + if (MGB_CTX->IsCapabilityEnabled(CapabilityInput::ScissorTest)) { + const IntVec4& scissor = MGB_CTX->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; @@ -9211,7 +9212,7 @@ void main() { return; } - auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& textureUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->GetActiveTextureUnit()); auto destinationTexture = textureUnit.GetBindingSlot(textureTarget).GetBoundObject(); if (destinationTexture == nullptr) { RecordTextureCopyError(__func__, ErrorCode::InvalidOperation, @@ -9219,7 +9220,7 @@ void main() { return; } - auto readFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (readFbo == nullptr) { RecordTextureCopyError(__func__, ErrorCode::InvalidOperation, "CopyTexSubImage2D requires a framebuffer bound to GL_READ_FRAMEBUFFER."); @@ -9930,7 +9931,7 @@ void main() { return; } - auto readFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + auto readFbo = MGB_CTX->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); if (readFbo == nullptr) { MGLOG_E_ONCE("DirectVulkan::ReadPixels skipped: no read framebuffer is bound"); return; @@ -10685,8 +10686,8 @@ void main() { // Store honoring the client pack state (single slice). const auto& pixelPackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); - const auto packParams = MG_State::pGLContext->GetPixelStoreParameters(false); + MGB_CTX->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + const auto packParams = MGB_CTX->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; @@ -10716,7 +10717,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 = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& activeUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->GetActiveTextureUnit()); auto textureObject = activeUnit.GetBindingSlot(textureTarget).GetBoundObject(); GetTextureImage(textureObject, textureUploadTarget, level, format, type, -1, pixels); } @@ -10960,7 +10961,7 @@ void main() { return; } - auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& textureUnit = MGB_CTX->GetTextureUnitObject(MGB_CTX->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."); @@ -11216,7 +11217,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 = MG_State::pGLContext->GetBoundTransformFeedbackLifetimeId(); + const Uint64 identity = MGB_CTX->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"); @@ -11233,7 +11234,7 @@ void main() { Uint32 slot = freeSlot; if (slot == kNoSlot) { for (Uint32 candidate = 0; candidate < kNoSlot; ++candidate) { - if (MG_State::pGLContext->HasOpenTransformFeedbackSpan(m_xfbCounterSlotOwner[candidate])) { + if (MGB_CTX->HasOpenTransformFeedbackSpan(m_xfbCounterSlotOwner[candidate])) { continue; } if (slot == kNoSlot || m_xfbCounterSlotLastUse[candidate] < m_xfbCounterSlotLastUse[slot]) { @@ -11264,17 +11265,17 @@ void main() { } Bool VulkanRenderer::BeginXfbCaptureForDraw(FrameContext::FrameData& frame) { - if (!m_transformFeedbackFeatureEnabled || MG_State::pGLContext == nullptr || - !MG_State::pGLContext->IsTransformFeedbackActive()) { + if (!m_transformFeedbackFeatureEnabled || !MGB_CTX_LIVE || + !MGB_CTX->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 (MG_State::pGLContext->IsTransformFeedbackPaused()) { + if (MGB_CTX->IsTransformFeedbackPaused()) { return false; } - const auto& program = MG_State::pGLContext->GetTransformFeedbackProgram(); + const auto& program = MGB_CTX->GetTransformFeedbackProgram(); if (!program || program->GetTransformFeedbackVaryingCount() == 0) { return false; } @@ -11313,7 +11314,7 @@ void main() { VkDeviceSize offsets[4] = {}; VkDeviceSize sizes[4] = {}; for (SizeT i = 0; i < bufferCount; ++i) { - auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::TransformFeedback, + auto& point = MGB_CTX->GetBufferBindingPoint(BufferTarget::TransformFeedback, static_cast(i)); const auto& bufferObject = point.GetBoundObject(); if (bufferObject == nullptr) { @@ -11344,7 +11345,7 @@ void main() { offsets, sizes); const Uint32 counterSlot = CurrentXfbCounterSlot(); - const Uint64 generation = MG_State::pGLContext->GetTransformFeedbackGeneration(); + const Uint64 generation = MGB_CTX->GetTransformFeedbackGeneration(); const Bool resume = m_xfbCountersValid[counterSlot] && m_xfbLastSeenGeneration[counterSlot] == generation; m_xfbLastSeenGeneration[counterSlot] = generation; @@ -11367,7 +11368,7 @@ void main() { if (!began) { return; } - const auto& program = MG_State::pGLContext->GetTransformFeedbackProgram(); + const auto& program = MGB_CTX->GetTransformFeedbackProgram(); const SizeT bufferCount = program ? std::min(program->GetTransformFeedbackBufferCount(), 4) : 0; const Uint32 counterSlot = CurrentXfbCounterSlot(); VkBuffer counterBuffers[4] = {}; @@ -12015,7 +12016,7 @@ void main() { default: break; } if (mergeGranularity != 0) { - const RenderStateParameters& rsp = MG_State::pGLContext->GetRenderStateParameters(); + const RenderStateParameters& rsp = MGB_CTX->GetRenderStateParameters(); if (rsp.PrimitiveRestartEnabled || rsp.PrimitiveRestartFixedIndexEnabled) { mergeGranularity = 0; } @@ -12093,7 +12094,7 @@ void main() { return; } - const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); const auto* indexBuffer = vao.GetIndexBufferBindingSlot().GetBoundObject().get(); if (!indexBuffer) { MGLOG_E_ONCE("MultiDrawElementsIndirectCount skipped: no element array buffer is bound"); @@ -12103,13 +12104,13 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(maxdrawcount - 1) + kGLDrawElementsIndirectCommandBytes; - auto drawBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->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 = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Parameter).GetBoundObject(); + auto parameterBuffer = MGB_CTX->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; @@ -12194,7 +12195,7 @@ void main() { return; } - const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& vao = *MGB_CTX->GetBoundVertexArray(); const auto* indexBuffer = vao.GetIndexBufferBindingSlot().GetBoundObject().get(); if (!indexBuffer) { MGLOG_E_ONCE("MultiDrawElementsIndirect skipped: no element array buffer is bound"); @@ -12204,7 +12205,7 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(drawcount - 1) + kGLDrawElementsIndirectCommandBytes; - auto drawBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!drawBuffer || commandBytes > drawBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawElementsIndirect skipped: invalid GL_DRAW_INDIRECT_BUFFER binding or range"); return; @@ -12274,7 +12275,7 @@ void main() { const SizeT commandOffset = reinterpret_cast(indirect); const SizeT commandBytes = commandOffset + static_cast(stride) * static_cast(drawcount - 1) + kGLDrawArraysIndirectCommandBytes; - auto drawBuffer = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); + auto drawBuffer = MGB_CTX->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); if (!drawBuffer || commandBytes > drawBuffer->GetSize()) { MGLOG_E_ONCE("MultiDrawArraysIndirect skipped: invalid GL_DRAW_INDIRECT_BUFFER binding or range"); return; @@ -12763,8 +12764,8 @@ void main() { if (!m_provokingVertexModePerPipeline) { return VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; } - return (MG_State::pGLContext != nullptr && - MG_State::pGLContext->GetProvokingVertexMode() == ProvokingVertexMode::FirstVertex) + return (MGB_CTX_LIVE && + MGB_CTX->GetProvokingVertexMode() == ProvokingVertexMode::FirstVertex) ? VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT : VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; }