ES31: Implement Geometry Shader inputs and outputs

This patch intends to implement Geometry Shader inputs and
outputs in ANGLE GLSL compiler.

1. Only accept arrays as the inputs of a Geometry Shader.
2. Allow unsized arrays as the inputs of a Geometry Shader after a
   valid input primitive declaration and assign size to them.
3. Implement Geometry Shader outputs.
4. Allow Geometry Shader inputs and outputs using interpolation
   qualifiers ('flat', 'smooth', 'centroid').
5. Allow using 'location' layout qualifier on Geometry Shader inputs
   and outputs.

BUG=angleproject:1941
TEST=angle_unittests

Change-Id: Ia7e250277c61f45c8479437b567c2831ff26b433
Reviewed-on: https://chromium-review.googlesource.com/650211
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index c713209..fdd04cb 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -23,6 +23,24 @@
 namespace sh
 {
 
+namespace
+{
+
+bool IsInterpolationIn(TQualifier qualifier)
+{
+    switch (qualifier)
+    {
+        case EvqSmoothIn:
+        case EvqFlatIn:
+        case EvqCentroidIn:
+            return true;
+        default:
+            return false;
+    }
+}
+
+}  // anonymous namespace
+
 float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
 {
     // Parses a decimal string using scientific notation into a floating point number.
@@ -442,7 +460,12 @@
     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
          ++arraySizeIter)
     {
-        arrayString << "[" << (*arraySizeIter) << "]";
+        arrayString << "[";
+        if (*arraySizeIter > 0)
+        {
+            arrayString << (*arraySizeIter);
+        }
+        arrayString << "]";
     }
     return arrayString.str();
 }
@@ -464,6 +487,7 @@
         case EvqFlatOut:
         case EvqCentroidOut:
         case EvqVertexOut:
+        case EvqGeometryOut:
             return true;
 
         default:
@@ -482,6 +506,7 @@
         case EvqFlatIn:
         case EvqCentroidIn:
         case EvqFragmentIn:
+        case EvqGeometryIn:
             return true;
 
         default:
@@ -496,6 +521,12 @@
     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
 }
 
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+    return (qualifier == EvqGeometryIn) ||
+           ((shaderType == GL_GEOMETRY_SHADER_OES) && IsInterpolationIn(qualifier));
+}
+
 InterpolationType GetInterpolationType(TQualifier qualifier)
 {
     switch (qualifier)
@@ -510,6 +541,8 @@
         case EvqFragmentIn:
         case EvqVaryingIn:
         case EvqVaryingOut:
+        case EvqGeometryIn:
+        case EvqGeometryOut:
             return INTERPOLATION_SMOOTH;
 
         case EvqCentroidIn: