From da6f75dbd119039e2e480b0aa47308335aa09d3b Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 1 Aug 2026 09:59:26 -0400 Subject: [PATCH] [Fix] (DirectGLES): cap advertised GL_MAX_SAMPLE_MASK_WORDS to 1 MobileGL's sample-mask state is a single 32-bit word (RenderState:: SampleMaskValue) and SampleMaski_State() hard-rejects any maskNumber other than 0. DirectGLES forwarded the real underlying driver's GL_MAX_SAMPLE_MASK_WORDS unmodified (NVIDIA's GLES driver reports 2), so dEQP's per-test-case gluStateReset - which always calls glSampleMaski up to that reported word count - hit GL_INVALID_VALUE on word 1 after every single case and aborted the whole glcts process. Each restart only got through one more case before repeating, which run_cts_local.py recorded as a wall of per-case crashes (63 in packed_pixels.rectangle alone) and tripped its "many empty chunks" abort heuristic partway through the GL32 suite. 1 is the spec-required minimum and is what MobileGL actually implements, so cap to it instead of forwarding the raw driver limit. --- MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 97605f01..9b98c942 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -929,6 +929,15 @@ namespace MobileGL::MG_Util::BackendLoader { glesFuncs.glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &maxIntegerSamples); glesFuncs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); glesFuncs.glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords); + // MobileGL's sample-mask state only stores a single 32-bit word (see + // RenderState::SampleMaskValue) and SampleMaski_State() rejects any + // maskNumber other than 0. Advertising the real driver's value here (e.g. + // NVIDIA's GLES driver reports 2) makes glSampleMaski(1, ...) - which + // dEQP's per-case gluStateReset always issues up to GL_MAX_SAMPLE_MASK_WORDS - + // raise GL_INVALID_VALUE and aborts the whole glcts process after every + // single test case. 1 is a spec-legal value (the minimum required), so cap + // to what is actually implemented instead of forwarding the raw driver limit. + maxSampleMaskWords = std::min(maxSampleMaskWords, 1); glesFuncs.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits); glesFuncs.glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); glesFuncs.glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &maxComputeTextureImageUnits);