mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Util/ShaderTranspiler): stop stripping precision qualifiers - the strip corrupted "precision highp float;" into invalid syntax; glslang accepts and ignores them natively in 460 core (unblocks ~2000 GL CTS cases per backend)
This commit is contained in:
@@ -112,8 +112,14 @@ void main() {
|
|||||||
EXPECT_NE(source.find("out vec2 uv;"), String::npos);
|
EXPECT_NE(source.find("out vec2 uv;"), String::npos);
|
||||||
EXPECT_EQ(source.find("attribute"), String::npos);
|
EXPECT_EQ(source.find("attribute"), String::npos);
|
||||||
EXPECT_EQ(source.find("varying"), String::npos);
|
EXPECT_EQ(source.find("varying"), String::npos);
|
||||||
EXPECT_EQ(source.find("HIGHP_OR_DEFAULT"), String::npos);
|
// Precision-qualifier macros are left for glslang's own preprocessor to expand.
|
||||||
EXPECT_EQ(source.find("#define"), String::npos);
|
EXPECT_NE(source.find("#define HIGHP_OR_DEFAULT highp"), String::npos);
|
||||||
|
|
||||||
|
ShaderAttrib attrib{.shaderType = GL_VERTEX_SHADER, .sourceStr = source};
|
||||||
|
auto res = ShaderCompiler::CompileShader(attrib);
|
||||||
|
if (!res) {
|
||||||
|
FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log << "\nsource:\n" << source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProgramUtilTest, PreprocessLegacyFragmentShaderModernizesGlmarkStyleSource) {
|
TEST_F(ProgramUtilTest, PreprocessLegacyFragmentShaderModernizesGlmarkStyleSource) {
|
||||||
@@ -137,9 +143,14 @@ void main() {
|
|||||||
EXPECT_NE(source.find("mg_FragColor = color;"), String::npos);
|
EXPECT_NE(source.find("mg_FragColor = color;"), String::npos);
|
||||||
EXPECT_EQ(source.find("gl_FragColor"), String::npos);
|
EXPECT_EQ(source.find("gl_FragColor"), String::npos);
|
||||||
EXPECT_EQ(source.find("texture2D"), String::npos);
|
EXPECT_EQ(source.find("texture2D"), String::npos);
|
||||||
EXPECT_EQ(source.find("MEDIUMP_OR_DEFAULT"), String::npos);
|
// Precision-qualifier macros are left for glslang's own preprocessor to expand.
|
||||||
EXPECT_EQ(source.find("mediump"), String::npos);
|
EXPECT_NE(source.find("#define MEDIUMP_OR_DEFAULT mediump"), String::npos);
|
||||||
EXPECT_EQ(source.find("#define"), String::npos);
|
|
||||||
|
ShaderAttrib attrib{.shaderType = GL_FRAGMENT_SHADER, .sourceStr = source};
|
||||||
|
auto res = ShaderCompiler::CompileShader(attrib);
|
||||||
|
if (!res) {
|
||||||
|
FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log << "\nsource:\n" << source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProgramUtilTest, PreprocessLegacyFragmentShaderModernizesFragData) {
|
TEST_F(ProgramUtilTest, PreprocessLegacyFragmentShaderModernizesFragData) {
|
||||||
@@ -166,6 +177,65 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProgramUtilTest, PreprocessKeepsDefaultPrecisionStatements) {
|
||||||
|
using namespace MG_Util::ShaderTranspiler;
|
||||||
|
|
||||||
|
// Mirrors the GL CTS helper shaders (e.g. glcPixelStorageModesTests): the old qualifier strip
|
||||||
|
// turned "precision highp float;" into invalid "precision float;". Precision qualifiers are
|
||||||
|
// legal (and ignored) in the forced 460 core profile, so they now pass through untouched.
|
||||||
|
String source = R"(#version 330
|
||||||
|
precision highp float;
|
||||||
|
precision mediump int;
|
||||||
|
out vec4 fragColor;
|
||||||
|
uniform highp sampler2D tex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 uv = vec2(0.5);
|
||||||
|
fragColor = texture(tex, uv);
|
||||||
|
})";
|
||||||
|
|
||||||
|
PreprocessShaderSource(ShaderStage::Fragment, source);
|
||||||
|
|
||||||
|
EXPECT_NE(source.find("precision highp float;"), String::npos);
|
||||||
|
EXPECT_NE(source.find("precision mediump int;"), String::npos);
|
||||||
|
EXPECT_NE(source.find("uniform highp sampler2D tex;"), String::npos);
|
||||||
|
EXPECT_NE(source.find("fragColor = texture(tex, uv);"), String::npos);
|
||||||
|
|
||||||
|
ShaderAttrib attrib{.shaderType = GL_FRAGMENT_SHADER, .sourceStr = source};
|
||||||
|
auto res = ShaderCompiler::CompileShader(attrib);
|
||||||
|
if (!res) {
|
||||||
|
FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log << "\nsource:\n" << source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProgramUtilTest, PreprocessKeepsPrecisionInLegacyShaderForGlslang) {
|
||||||
|
using namespace MG_Util::ShaderTranspiler;
|
||||||
|
|
||||||
|
// Legacy ES-style shader: precision statements and qualifier macros are left for glslang
|
||||||
|
// (its preprocessor expands the #define; the 460 core parse ignores the qualifiers).
|
||||||
|
String source = R"(#define HIGHP_OR_DEFAULT highp
|
||||||
|
precision HIGHP_OR_DEFAULT float;
|
||||||
|
precision mediump int;
|
||||||
|
varying vec2 uv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mediump float shade = uv.x;
|
||||||
|
gl_FragColor = vec4(uv, shade, 1.0);
|
||||||
|
})";
|
||||||
|
|
||||||
|
PreprocessShaderSource(ShaderStage::Fragment, source);
|
||||||
|
|
||||||
|
EXPECT_NE(source.find("precision HIGHP_OR_DEFAULT float;"), String::npos);
|
||||||
|
EXPECT_NE(source.find("precision mediump int;"), String::npos);
|
||||||
|
EXPECT_NE(source.find("in vec2 uv;"), String::npos);
|
||||||
|
|
||||||
|
ShaderAttrib attrib{.shaderType = GL_FRAGMENT_SHADER, .sourceStr = source};
|
||||||
|
auto res = ShaderCompiler::CompileShader(attrib);
|
||||||
|
if (!res) {
|
||||||
|
FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log << "\nsource:\n" << source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProgramUtilTest, PreprocessFragmentShaderInjectsDepthRangeShim) {
|
TEST_F(ProgramUtilTest, PreprocessFragmentShaderInjectsDepthRangeShim) {
|
||||||
using namespace MG_Util::ShaderTranspiler;
|
using namespace MG_Util::ShaderTranspiler;
|
||||||
|
|
||||||
|
|||||||
@@ -262,15 +262,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModernizeLegacyGLSL(MobileGL::ShaderStage stage, MobileGL::String& source) {
|
void ModernizeLegacyGLSL(MobileGL::ShaderStage stage, MobileGL::String& source) {
|
||||||
RemoveDefineForIdentifier(source, "HIGHP_OR_DEFAULT");
|
// Precision qualifiers (highp/mediump/lowp and default-precision statements) are legal and
|
||||||
RemoveDefineForIdentifier(source, "MEDIUMP_OR_DEFAULT");
|
// ignored in the forced "#version 460 core" profile, so glslang handles them natively.
|
||||||
RemoveDefineForIdentifier(source, "LOWP_OR_DEFAULT");
|
|
||||||
ReplaceIdentifier(source, "HIGHP_OR_DEFAULT", "");
|
|
||||||
ReplaceIdentifier(source, "MEDIUMP_OR_DEFAULT", "");
|
|
||||||
ReplaceIdentifier(source, "LOWP_OR_DEFAULT", "");
|
|
||||||
ReplaceIdentifier(source, "highp", "");
|
|
||||||
ReplaceIdentifier(source, "mediump", "");
|
|
||||||
ReplaceIdentifier(source, "lowp", "");
|
|
||||||
|
|
||||||
ReplaceIdentifier(source, "texture2D", "texture");
|
ReplaceIdentifier(source, "texture2D", "texture");
|
||||||
ReplaceIdentifier(source, "texture2DProj", "textureProj");
|
ReplaceIdentifier(source, "texture2DProj", "textureProj");
|
||||||
|
|||||||
Reference in New Issue
Block a user