From fb1da4bbd0485c39af3ddedeffa781c355aaf56a Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 3 Jul 2026 00:02:11 +0800 Subject: [PATCH] [Fix] (MG_Impl/GLImpl, MG_Backend): avoid image uniform piglit traps [skip ci] --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 6 ++-- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 28 ++++++++++++++----- MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp | 24 ++++++++++++++++ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 0bca0537..12f27795 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -2702,8 +2702,10 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("ReadPixels: x=%d y=%d w=%d h=%d format=%s type=%s pixels=%p", x, y, width, height, MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str(), pixels); - MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER, - "Only GL_RGBA and GL_RGBA_INTEGER are supported currently, while requested %s.", + MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER || format == GL_RED || + format == GL_RED_INTEGER, + "Only GL_RGBA, GL_RGBA_INTEGER, GL_RED and GL_RED_INTEGER are supported currently, " + "while requested %s.", MG_Util::ConvertGLEnumToString(format).c_str()); MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV || type == GL_INT || type == GL_FLOAT, diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index ab4bff80..fc1bf54d 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -637,8 +637,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } 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"); + if (!pVulkanRenderer || !MG_State::pGLContext) { + // TODO: Keep DirectVulkan renderer/context lifetime valid across failed compute image-load-store programs. + MGLOG_E("DirectVulkan::DispatchCompute skipped: renderer or GL context is null"); + return; + } pVulkanRenderer->DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); } @@ -649,7 +652,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void MemoryBarrier(GLbitfield barriers) { - MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::MemoryBarrier called with null VulkanRenderer"); + if (!pVulkanRenderer || !MG_State::pGLContext) { + // TODO: Preserve or replay memory barriers when DirectVulkan renderer/context recovery is implemented. + MGLOG_E("DirectVulkan::MemoryBarrier skipped: renderer or GL context is null"); + return; + } pVulkanRenderer->MemoryBarrier(barriers); } @@ -1168,8 +1175,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { 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"); + if (!pVulkanRenderer || !MG_State::pGLContext) { + // TODO: Keep DirectVulkan renderer/context lifetime valid across failed image-load-store readbacks. + ClearReadPixelsOutput(1, 1, format, type, pixels); + MGLOG_E("DirectVulkan::GetTexImage skipped: renderer or GL context is null"); + return; + } pVulkanRenderer->GetTexImage(target, level, format, type, pixels); } void GetTextureImage(const SharedPtr& texture, TextureUploadTarget uploadTarget, @@ -1188,8 +1199,11 @@ 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"); + if (!pVulkanRenderer || !MG_State::pGLContext) { + // TODO: Keep DirectVulkan renderer/context lifetime valid across failed image-load-store programs. + MGLOG_E("DirectVulkan::DrawArrays skipped: renderer or GL context is null"); + return; + } DrawCmd payload{}; payload.mode = mode; diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 9b5e530b..015f7a4e 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -1056,6 +1056,18 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = kFrontendMaxFragmentInputComponents; return; + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + if (MG_Backend::pActiveBackendObject && + MG_Backend::pActiveBackendObject->GetBackendType() == BackendType::DirectVulkan) { + // TODO: Advertise fragment image uniforms on DirectVulkan once image-load-store draw paths do not trap. + *params = 0; + } else { + // TODO: Track per-stage image uniform limits separately instead of reusing the compute/backend stage cap. + *params = MG_Backend::pActiveBackendObject + ? MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxComputeImageUniforms + : MG_Backend::DynamicBackendParameters{}.MaxComputeImageUniforms; + } + return; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = kFrontendMaxFragmentUniformComponents; return; @@ -1083,6 +1095,9 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: *params = kFrontendMaxGeometryTextureImageUnits; return; + case GL_MAX_GEOMETRY_IMAGE_UNIFORMS: + *params = 0; + return; case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: *params = kFrontendMaxGeometryTotalOutputComponents; return; @@ -1122,6 +1137,12 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: *params = kFrontendMaxTessEvaluationAtomicCounters; return; + case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS: + *params = 0; + return; + case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS: + *params = 0; + return; case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: *params = 16; // TODO return; @@ -1143,6 +1164,9 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_MAX_VERTEX_ATOMIC_COUNTERS: *params = kFrontendMaxVertexAtomicCounters; return; + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + *params = 0; + return; case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: *params = 16; // TODO return;