[Fix] (MG_Impl/GLImpl, MG_Backend): avoid image uniform piglit traps [skip ci]

This commit is contained in:
2026-07-03 00:02:11 +08:00
parent ac43c0224c
commit fb1da4bbd0
3 changed files with 49 additions and 9 deletions
@@ -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,
@@ -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<MG_State::GLState::ITextureObject>& 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;
@@ -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;