Remove invariant qualifier for ESSL 3.0 on AMD driver
AMD driver in Linux requires invariant qualifier to match between
shaders even for GLSL >= 4.2. This conflicts with ESSL 3.0 which
disallows invariant qualifier in fragment shader. Remove invariant
qualifier in vertex shader to workaround AMD driver bug.
BUG=chromium:639760
TEST=webgl2_conformance
Change-Id: Id5adf7e7032105486df90a1f200471ea81ee5c36
Reviewed-on: https://chromium-review.googlesource.com/411917
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index deead5e..01b1e02 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -205,7 +205,12 @@
// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX
// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and
// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers.
-// Note that the two flags only take effect on ESSL3 input shaders translated to GLSL 4.1 or lower.
+// AMD driver in Linux requires invariant qualifier to match between vertex and fragment shaders,
+// while ESSL3 disallows invariant qualifier in fragment shader and GLSL >= 4.2 doesn't require
+// invariant qualifier to match between shaders. Remove invariant qualifier from vertex shader to
+// workaround AMD driver bug.
+// Note that the two flags take effect on ESSL3 input shaders translated to GLSL 4.1 or lower and to
+// GLSL 4.2 or newer on Linux AMD.
// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some
// developers' content. A more complex workaround of dynamically generating, compiling, and
// re-linking shaders that use these qualifiers should be implemented.
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index e085ed5..de9d98f 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -113,7 +113,7 @@
return true;
if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 &&
- shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER && IsGLSL410OrOlder(outputType))
+ shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER)
return true;
return false;
diff --git a/src/compiler/translator/TranslatorGLSL.cpp b/src/compiler/translator/TranslatorGLSL.cpp
index 1d6582b..f25df31 100644
--- a/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/compiler/translator/TranslatorGLSL.cpp
@@ -58,7 +58,9 @@
// variables. It should be harmless to do this twice in the case that the shader also explicitly
// did this. However, it's important to emit invariant qualifiers only for those built-in
// variables that are actually used, to avoid affecting the behavior of the shader.
- if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && getPragma().stdgl.invariantAll)
+ if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) != 0 &&
+ getPragma().stdgl.invariantAll &&
+ !sh::RemoveInvariant(getShaderType(), getShaderVersion(), getOutputType(), compileOptions))
{
ASSERT(wereVariablesCollected());
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index c80597f..04e26ce 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -945,7 +945,9 @@
workarounds->packLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
#endif
- workarounds->removeInvariantAndCentroidForESSL3 = functions->isAtMostGL(gl::Version(4, 1));
+ workarounds->removeInvariantAndCentroidForESSL3 =
+ functions->isAtMostGL(gl::Version(4, 1)) ||
+ (functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor));
}
}