ES31: Add Geometry Shader layout qualifiers in GLSL compiler

This patch intends to implement Geometry Shader layout qualifiers
required in OpenGL ES 3.1 extension GL_OES_geometry_shader in ANGLE
GLSL compiler.

1. Add support to the shader type GL_GEOMETRY_SHADER_OES.
2. Implement Geometry Shader layout qualifiers in the GLSL compiler:
(1) Add support to OpenGL ES 3.1 extension "GL_OES_geometry_shader".
(2) Add validations of the input and output primitive declarations
    in the Geometry Shader layout declarations.
(3) Add 'invocations' and 'max_vertices' support in the Geometry
    Shader layout declarations
3. Add unit tests to cover all the new features added in this patch.

BUG=angleproject:1941
TEST=angle_unittests

Change-Id: Ie693e11f8a00dab3552626ed63e9336c7fbd3cb8
Reviewed-on: https://chromium-review.googlesource.com/560647
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index ab89e9a..cf0483d 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -146,11 +146,14 @@
             return resources.MaxVertexUniformVectors;
         case GL_FRAGMENT_SHADER:
             return resources.MaxFragmentUniformVectors;
+
+        // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
         case GL_COMPUTE_SHADER:
-            // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
             return resources.MaxComputeUniformComponents / 4;
+        case GL_GEOMETRY_SHADER_OES:
+            return resources.MaxGeometryUniformComponents / 4;
         default:
-            UNIMPLEMENTED();
+            UNREACHABLE();
             return -1;
     }
 }
@@ -242,7 +245,11 @@
       builtInFunctionEmulator(),
       mDiagnostics(infoSink.info),
       mSourcePath(nullptr),
-      mComputeShaderLocalSizeDeclared(false)
+      mComputeShaderLocalSizeDeclared(false),
+      mGeometryShaderMaxVertices(-1),
+      mGeometryShaderInvocations(0),
+      mGeometryShaderInputPrimitiveType(EptUndefined),
+      mGeometryShaderOutputPrimitiveType(EptUndefined)
 {
     mComputeShaderLocalSize.fill(1);
 }
@@ -360,6 +367,15 @@
             success = false;
         }
 
+        if (success && shaderType == GL_GEOMETRY_SHADER_OES)
+        {
+            mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType();
+            mGeometryShaderOutputPrimitiveType =
+                parseContext.getGeometryShaderOutputPrimitiveType();
+            mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices();
+            mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations();
+        }
+
         // Disallow expressions deemed too complex.
         if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
             success = limitExpressionComplexity(root);
@@ -626,15 +642,13 @@
             symbolTable.setDefaultPrecision(EbtInt, EbpMedium);
             break;
         case GL_VERTEX_SHADER:
-            symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
-            symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
-            break;
         case GL_COMPUTE_SHADER:
+        case GL_GEOMETRY_SHADER_OES:
             symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
             symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
             break;
         default:
-            assert(false && "Language not supported");
+            UNREACHABLE();
     }
     // Set defaults for sampler types that have default precision, even those that are
     // only available if an extension exists.
@@ -694,6 +708,7 @@
         << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
         << ":OVR_multiview:" << compileResources.OVR_multiview
         << ":EXT_YUV_target:" << compileResources.EXT_YUV_target
+        << ":OES_geometry_shader:" << compileResources.OES_geometry_shader
         << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
         << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
         << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
@@ -725,7 +740,10 @@
         << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
         << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
         << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
-        << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
+        << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize
+        << ":MaxGeometryOutputVertices:" << compileResources.MaxGeometryOutputVertices
+        << ":MaxGeometryUniformComponents:" << compileResources.MaxGeometryUniformComponents
+        << ":MaxGeometryShaderInvocations:" << compileResources.MaxGeometryShaderInvocations;
     // clang-format on
 
     builtInResourcesString = strstream.str();
@@ -749,6 +767,11 @@
 
     mNumViews = -1;
 
+    mGeometryShaderInputPrimitiveType  = EptUndefined;
+    mGeometryShaderOutputPrimitiveType = EptUndefined;
+    mGeometryShaderInvocations         = 0;
+    mGeometryShaderMaxVertices         = -1;
+
     builtInFunctionEmulator.cleanup();
 
     nameMap.clear();