From 86c00bdf18202e8354f0652e4f8c860e5948f246 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sun, 2 Aug 2026 09:04:16 -0400 Subject: [PATCH] [Test] (MG_Test): catch the unit tests up with three deliberate behaviour changes ctest -L unit had been failing 13 of its 418 cases, all of them tests left asserting what the code did before a commit that changed it on purpose: - "restore target GL version to 3.3" put the advertised target back after the experimental 4.6 run, but the two Voxy sanity tests still demanded 4.6. The extensions they really care about are all still advertised, so assert 3.3 and drop the now-meaningless AtExperimentalCTSVersion from their names. - "support rectangle textures where the emulation is exact" made every desktop-only target supported - rectangle included, stored as a plain 2D - while the texture test still expected rectangle to be rejected. - "keep declared modern GLSL versions strict" changed two things at once: a normalized legacy directive now carries a marker on its line, so the ten tests matching "#version 330 core\n" whole no longer match; and a version the application declared itself is no longer raised to 460, so the sources declaring 330/400 keep their own number and only MobileGL's own normalization is retargeted. Test expectations follow, rather than the implementation being bent back: each of the three changes is the intended behaviour and is argued for where it was made. The retry test now drives the 460 escalation from a legacy "#version 130" source, which is the only thing that is still rescued, and gained a case pinning the other half of that contract - an application-declared "#version 330" stays at 330. 418/418 unit tests pass. --- MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 54 +++++++++++++------- MobileGL/MG_Test/SanityTest.cpp | 15 +++--- MobileGL/MG_Test/Texture/TextureTest.cpp | 8 +-- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index fcaf6174..27993c91 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -223,7 +223,7 @@ void main() { PreprocessShaderSource(ShaderStage::Vertex, source); - EXPECT_EQ(source.find("#version 330 core\n"), 0); + EXPECT_EQ(source.find("#version 330 core "), 0); EXPECT_NE(source.find("in vec3 position;"), String::npos); EXPECT_NE(source.find("out vec2 uv;"), String::npos); EXPECT_EQ(source.find("attribute"), String::npos); @@ -323,7 +323,7 @@ void main() { PreprocessShaderSource(ShaderStage::Fragment, source); - EXPECT_EQ(source.find("#version 330 core\n"), 0); + EXPECT_EQ(source.find("#version 330 core "), 0); EXPECT_NE(source.find("out vec4 mg_FragColor;\n"), String::npos); EXPECT_NE(source.find("in vec2 uv;"), String::npos); EXPECT_NE(source.find("texture(texture0, uv)"), String::npos); @@ -379,7 +379,7 @@ void main() { PreprocessShaderSource(ShaderStage::Fragment, source); - EXPECT_EQ(source.find("#version 330 core\n"), 0); + EXPECT_EQ(source.find("#version 330 core "), 0); EXPECT_NE(source.find("vec4 sample = texture(DiffuseSampler"), String::npos); EXPECT_NE(source.find("totalAlpha = totalAlpha + sample.a;"), String::npos); EXPECT_NE(source.find("float totalSamples = 0.0;"), String::npos); @@ -405,7 +405,7 @@ void main() { )"; PreprocessShaderSource(ShaderStage::Vertex, vertexSource); - EXPECT_EQ(vertexSource.find("#version 330 core\n"), 0); + EXPECT_EQ(vertexSource.find("#version 330 core "), 0); EXPECT_NE(vertexSource.find("in vec3 sample;"), String::npos); ShaderAttrib vertexAttrib{.shaderType = GL_VERTEX_SHADER, .sourceStr = vertexSource}; @@ -425,7 +425,7 @@ void main() { )"; PreprocessShaderSource(ShaderStage::Fragment, fragmentSource); - EXPECT_EQ(fragmentSource.find("#version 330 core\n"), 0); + EXPECT_EQ(fragmentSource.find("#version 330 core "), 0); EXPECT_NE(fragmentSource.find("uniform sampler2D sample;"), String::npos); EXPECT_NE(fragmentSource.find("texture(sample, texCoord)"), String::npos); @@ -483,7 +483,9 @@ void main() { )"; PreprocessShaderSource(ShaderStage::Fragment, source); - EXPECT_EQ(source.find("#version 460 core\n"), 0); + // An explicitly declared modern core version keeps its number (see "keep declared modern + // GLSL versions strict"); only the BOM goes. + EXPECT_EQ(source.find(String(inputVersion) + "\n"), 0); EXPECT_EQ(source.find("\xef\xbb\xbf"), String::npos); ShaderAttrib attrib{.shaderType = GL_FRAGMENT_SHADER, .sourceStr = source}; @@ -568,10 +570,12 @@ void main() { )"; PreprocessShaderSource(ShaderStage::Fragment, source); - const SizeT versionPos = source.find("#version 330 core\n"); + const SizeT versionPos = source.find("#version 330 core "); const SizeT outputPos = source.find("out vec4 mg_FragColor;\n"); EXPECT_NE(versionPos, String::npos); - EXPECT_EQ(outputPos, versionPos + std::strlen("#version 330 core\n")); + // The normalized directive carries a marker recording that this 330 came from a legacy + // declaration, so measure the line rather than assuming its length. + EXPECT_EQ(outputPos, source.find('\n', versionPos) + 1); EXPECT_NE(source.find("// #version 460 core"), String::npos); // This #line sits ahead of the version directive, where GLSL would never have honoured it, so // it is still dropped. Directives that follow the version line are kept - see @@ -684,7 +688,7 @@ void main() { } } -TEST_F(ProgramUtilTest, PreprocessModernSampleQualifierStaysAtVersion460) { +TEST_F(ProgramUtilTest, PreprocessModernSampleQualifierStaysAtItsDeclaredVersion) { using namespace MG_Util::ShaderTranspiler; String source = R"(#version 400 core @@ -697,7 +701,7 @@ void main() { )"; PreprocessShaderSource(ShaderStage::Fragment, source); - EXPECT_EQ(source.find("#version 460 core\n"), 0); + EXPECT_EQ(source.find("#version 400 core\n"), 0); EXPECT_NE(source.find("sample in vec4 interpolatedColor;"), String::npos); ShaderAttrib attrib{.shaderType = GL_FRAGMENT_SHADER, .sourceStr = source}; @@ -746,7 +750,7 @@ void main() { PreprocessShaderSource(ShaderStage::Fragment, source); - EXPECT_EQ(source.find("#version 330 core\n"), 0); + EXPECT_EQ(source.find("#version 330 core "), 0); EXPECT_NE(source.find("layout(location = 0) out vec4 mg_FragData[8];\n"), String::npos); EXPECT_NE(source.find("mg_FragData[0] = vec4(1.0);"), String::npos); EXPECT_NE(source.find("mg_FragData[1].a = 0.5;"), String::npos); @@ -902,16 +906,17 @@ TEST_F(ProgramUtilTest, CompileSimpleVertexShader) { } // Legacy desktop sources are normalized to "#version 330 core", which is stricter than the 460 they -// used to be forced to. A shader declaring 330 while using 420-era syntax without the matching -// #extension line is accepted by real drivers, so CompileShader retries it at 460 instead of failing. -TEST_F(ProgramUtilTest, CompileShaderRetriesAt460WhenLegacyVersionRejects420Syntax) { +// used to be forced to. A legacy shader using 420-era syntax without the matching #extension line +// is accepted by real drivers, so CompileShader retries the normalized source at 460 rather than +// failing. Only MobileGL's own normalization is rescued this way - an application-declared +// "#version 330" keeps strict 3.30 semantics, which is what the CTS negative-compile cases need. +TEST_F(ProgramUtilTest, CompileShaderRetriesAt460WhenNormalizedLegacyVersionRejects420Syntax) { using namespace MG_Util::ShaderTranspiler; - String source = R"(#version 330 + String source = R"(#version 130 layout(binding = 0) uniform sampler2D InSampler; -in vec2 texCoord; -out vec4 fragColor; +varying vec2 texCoord; void main() { - fragColor = texture(InSampler, texCoord); + gl_FragColor = texture2D(InSampler, texCoord); })"; PreprocessShaderSource(ShaderStage::Fragment, source); // The normal path still emits 330 - the retry must not become the default. @@ -952,10 +957,21 @@ void main() { TEST_F(ProgramUtilTest, RetargetLegacyVersionDirectiveOnlyTouchesNormalizedDesktopCore) { using namespace MG_Util::ShaderTranspiler; - String normalized = "#version 330 core\nvoid main() {}\n"; + // Only MobileGL's own normalization is retargetable, and it is recognised by the marker the + // preprocessor leaves on the directive line - so normalize a legacy source rather than + // hand-writing the directive the marker belongs to. + String normalized = "#version 130\nvoid main() {}\n"; + PreprocessShaderSource(ShaderStage::Vertex, normalized); + ASSERT_EQ(normalized.find("#version 330 core "), 0u); EXPECT_TRUE(RetargetLegacyVersionDirectiveTo460(normalized)); EXPECT_EQ(normalized.find("#version 460 core"), 0u); + // An application that declared 330 itself keeps strict 3.30 semantics: raising it would + // re-legalize the CTS negative-compile cases. + String declared330 = "#version 330 core\nvoid main() {}\n"; + EXPECT_FALSE(RetargetLegacyVersionDirectiveTo460(declared330)); + EXPECT_EQ(declared330.find("#version 330 core"), 0u); + // Already modern: nothing to retarget. String modern = "#version 460 core\nvoid main() {}\n"; EXPECT_FALSE(RetargetLegacyVersionDirectiveTo460(modern)); diff --git a/MobileGL/MG_Test/SanityTest.cpp b/MobileGL/MG_Test/SanityTest.cpp index d2a4e668..130be5f0 100644 --- a/MobileGL/MG_Test/SanityTest.cpp +++ b/MobileGL/MG_Test/SanityTest.cpp @@ -197,13 +197,15 @@ TEST(DirectGLESSanity, AdvertisesDepthTextureForGlmarkShadowScenes) { EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_depth_texture), extensions.end()); } -TEST(DirectGLESSanity, AdvertisesVoxyRequiredRenderingExtensionsAtExperimentalCTSVersion) { +// The advertised target went back to 3.3 (see "restore target GL version to 3.3"); Voxy only ever +// needed the extensions, which stay advertised, so assert what the backend really reports. +TEST(DirectGLESSanity, AdvertisesVoxyRequiredRenderingExtensions) { MobileGL::MG_Backend::DirectGLES::BackendObject_DirectGLES backend; const auto& rendererInfo = backend.GetRendererInfo().RendererGLInfo; const auto& extensions = rendererInfo.Extensions; - EXPECT_EQ(rendererInfo.TargetGLVersion.Major, 4); - EXPECT_EQ(rendererInfo.TargetGLVersion.Minor, 6); + EXPECT_EQ(rendererInfo.TargetGLVersion.Major, 3); + EXPECT_EQ(rendererInfo.TargetGLVersion.Minor, 3); EXPECT_EQ(rendererInfo.TargetGLVersion.Patch, 0); EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_compute_shader), @@ -397,13 +399,14 @@ TEST(DirectVulkanSanity, RenderPassExtentUsesSwapchainSizeOnlyForDefaultFramebuf MobileGL::IntVec2(512, 512)); } -TEST(DirectVulkanSanity, AdvertisesVoxyRequiredRenderingExtensionsAtExperimentalCTSVersion) { +// See the DirectGLES twin above: the target version is 3.3 again, the extensions are what matter. +TEST(DirectVulkanSanity, AdvertisesVoxyRequiredRenderingExtensions) { MobileGL::MG_Backend::DirectVulkan::BackendObject_DirectVulkan backend; const auto& rendererInfo = backend.GetRendererInfo().RendererGLInfo; const auto& extensions = rendererInfo.Extensions; - EXPECT_EQ(rendererInfo.TargetGLVersion.Major, 4); - EXPECT_EQ(rendererInfo.TargetGLVersion.Minor, 6); + EXPECT_EQ(rendererInfo.TargetGLVersion.Major, 3); + EXPECT_EQ(rendererInfo.TargetGLVersion.Minor, 3); EXPECT_EQ(rendererInfo.TargetGLVersion.Patch, 0); EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_compute_shader), diff --git a/MobileGL/MG_Test/Texture/TextureTest.cpp b/MobileGL/MG_Test/Texture/TextureTest.cpp index a23fd8ea..ac060b5b 100644 --- a/MobileGL/MG_Test/Texture/TextureTest.cpp +++ b/MobileGL/MG_Test/Texture/TextureTest.cpp @@ -1867,11 +1867,13 @@ TEST_F(TextureTest, DirectGLESTreats2DArrayAsSupportedTextureTarget) { EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture2DArray)); EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture3D)); EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture2D)); - // 1D and 1D-array are emulated as 2D / 2D-array (MapToBackendTextureTarget), matching - // SPIRV-Cross's ES 1D-as-2D shader emission; only rectangle textures stay unsupported. + // Every desktop-only target is stored on an ES one (MapToBackendTextureTarget): 1D and + // 1D-array as 2D / 2D-array, matching SPIRV-Cross's ES 1D-as-2D shader emission, and + // rectangle as a plain 2D - it is single-level and already clamps, so only the + // non-normalized coordinates differ and LowerRectImagesForEssl handles those. EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture1D)); EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture1DArray)); - EXPECT_FALSE(IsSupportedTextureTarget(TextureTarget::TextureRectangle)); + EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::TextureRectangle)); } // 2D-array textures keep their layer count constant across mip levels (GL 3.3 ยง3.9);