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));
 }
 
 }