ES31: Support EXT_geometry_shader in GLSL compiler

This patch intends to support "EXT_geometry_shader" as a valid
extension string in ANGLE GLSL compiler.

We decide to support it because in dEQP-GLES31 all geometry
shader related tests are using "EXT_geometry_shader" instead of
"OES_geometry_shader".

1. Support new extension string "EXT_geometry_shader"
2. Enable geometry shader layout qualifiers with EXT_geometry_shader
3. Enable geometry shader builtins with EXT_geometry_shader

BUG=angleproject:1941
TEST=angle_unittests

Change-Id: Iaedd01a9100ccf56243c957db36ff0c983d17060
Reviewed-on: https://chromium-review.googlesource.com/737933
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 87d6fd0..6b40262 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1159,6 +1159,7 @@
 bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
 {
     ASSERT(extension != TExtension::UNDEFINED);
+    ASSERT(extension != TExtension::EXT_geometry_shader);
     const TExtensionBehavior &extBehavior   = extensionBehavior();
     TExtensionBehavior::const_iterator iter = extBehavior.find(extension);
     if (iter == extBehavior.end())
@@ -1169,11 +1170,53 @@
     // In GLSL ES, an extension's default behavior is "disable".
     if (iter->second == EBhDisable || iter->second == EBhUndefined)
     {
+        // We also need to check EXT_geometry_shader because internally we always use
+        // TExtension::OES_geometry_shader to represent both OES_geometry_shader and
+        // EXT_geometry_shader.
+        if (extension == TExtension::OES_geometry_shader)
+        {
+            TExtensionBehavior::const_iterator iterExt =
+                extBehavior.find(TExtension::EXT_geometry_shader);
+            ASSERT(iterExt != extBehavior.end());
+            if (iterExt->second == EBhUndefined)
+            {
+                error(line, "extension is disabled",
+                      GetExtensionNameString(TExtension::OES_geometry_shader));
+                return false;
+            }
+            if (iterExt->second == EBhDisable)
+            {
+                error(line, "extension is disabled",
+                      GetExtensionNameString(TExtension::EXT_geometry_shader));
+                return false;
+            }
+            if (iterExt->second == EBhWarn)
+            {
+                warning(line, "extension is being used",
+                        GetExtensionNameString(TExtension::EXT_geometry_shader));
+            }
+
+            return true;
+        }
+
         error(line, "extension is disabled", GetExtensionNameString(extension));
         return false;
     }
     if (iter->second == EBhWarn)
     {
+        if (extension == TExtension::OES_geometry_shader)
+        {
+            TExtensionBehavior::const_iterator iterExt =
+                extBehavior.find(TExtension::EXT_geometry_shader);
+            ASSERT(iterExt != extBehavior.end());
+            // We should output no warnings when OES_geometry_shader is declared as "warn" and
+            // EXT_geometry_shader is declared as "require" or "enable".
+            if (iterExt->second == EBhRequire || iterExt->second == EBhEnable)
+            {
+                return true;
+            }
+        }
+
         warning(line, "extension is being used", GetExtensionNameString(extension));
         return true;
     }
@@ -4233,47 +4276,44 @@
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.imageInternalFormat = EiifR32UI;
     }
-    else if (qualifierType == "points" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "points" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptPoints;
     }
-    else if (qualifierType == "lines" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "lines" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLines;
     }
-    else if (qualifierType == "lines_adjacency" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "lines_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLinesAdjacency;
     }
-    else if (qualifierType == "triangles" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangles" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTriangles;
     }
-    else if (qualifierType == "triangles_adjacency" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangles_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTrianglesAdjacency;
     }
-    else if (qualifierType == "line_strip" && isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "line_strip" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptLineStrip;
     }
-    else if (qualifierType == "triangle_strip" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "triangle_strip" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
         qualifier.primitiveType = EptTriangleStrip;
@@ -4429,15 +4469,13 @@
     {
         parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
     }
-    else if (qualifierType == "invocations" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
     }
-    else if (qualifierType == "max_vertices" &&
-             isExtensionEnabled(TExtension::OES_geometry_shader) &&
-             mShaderType == GL_GEOMETRY_SHADER_OES)
+    else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_OES &&
+             checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
     {
         parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
     }