ES31: Implement GL_OES_geometry_shader built-ins in GLSL compiler

This patch intends to implement all built-in constants, variables and
functions defined in OpenGL ES 3.1 extension GL_OES_geometry_shader
in ANGLE GLSL compiler.

1. Add all built-in constants defined in GL_OES_geometry_shader.
2. Add built-in functions EmitVertex() and EndPrimitive() required
   in Geometry Shader.
3. Add built-in variables gl_PrimitiveIDIn and gl_InvocationID to
   Geometry Shader.
4. Add built-in variables gl_PrimitiveID and gl_Layer to both
   Geometry Shader and Fragment Shader when GL_OES_geometry_shader
   is enabled.

BUG=angleproject:1941
TEST=angle_unittests

Change-Id: I92821553ed0efee2ccb77fead6e065e7799819d0
Reviewed-on: https://chromium-review.googlesource.com/627670
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/CollectVariables.cpp b/src/compiler/translator/CollectVariables.cpp
index abe4592..8753d77 100644
--- a/src/compiler/translator/CollectVariables.cpp
+++ b/src/compiler/translator/CollectVariables.cpp
@@ -100,6 +100,7 @@
                               ShHashFunction64 hashFunction,
                               TSymbolTable *symbolTable,
                               int shaderVersion,
+                              GLenum shaderType,
                               const TExtensionBehavior &extensionBehavior);
 
     void visitSymbol(TIntermSymbol *symbol) override;
@@ -139,15 +140,21 @@
 
     std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
 
+    // Shader uniforms
     bool mDepthRangeAdded;
+
+    // Vertex Shader builtins
+    bool mInstanceIDAdded;
+    bool mVertexIDAdded;
+    bool mPointSizeAdded;
+
+    // Vertex Shader and Geometry Shader builtins
+    bool mPositionAdded;
+
+    // Fragment Shader builtins
     bool mPointCoordAdded;
     bool mFrontFacingAdded;
     bool mFragCoordAdded;
-
-    bool mInstanceIDAdded;
-    bool mVertexIDAdded;
-    bool mPositionAdded;
-    bool mPointSizeAdded;
     bool mLastFragDataAdded;
     bool mFragColorAdded;
     bool mFragDataAdded;
@@ -156,11 +163,19 @@
     bool mSecondaryFragColorEXTAdded;
     bool mSecondaryFragDataEXTAdded;
 
+    // Geometry Shader builtins
     bool mPerVertexInAdded;
+    bool mPrimitiveIDInAdded;
+    bool mInvocationIDAdded;
+
+    // Geometry Shader and Fragment Shader builtins
+    bool mPrimitiveIDAdded;
+    bool mLayerAdded;
 
     ShHashFunction64 mHashFunction;
 
     int mShaderVersion;
+    GLenum mShaderType;
     const TExtensionBehavior &mExtensionBehavior;
 };
 
@@ -176,6 +191,7 @@
     ShHashFunction64 hashFunction,
     TSymbolTable *symbolTable,
     int shaderVersion,
+    GLenum shaderType,
     const TExtensionBehavior &extensionBehavior)
     : TIntermTraverser(true, false, false, symbolTable),
       mAttribs(attribs),
@@ -187,13 +203,13 @@
       mShaderStorageBlocks(shaderStorageBlocks),
       mInBlocks(inBlocks),
       mDepthRangeAdded(false),
+      mInstanceIDAdded(false),
+      mVertexIDAdded(false),
+      mPointSizeAdded(false),
+      mPositionAdded(false),
       mPointCoordAdded(false),
       mFrontFacingAdded(false),
       mFragCoordAdded(false),
-      mInstanceIDAdded(false),
-      mVertexIDAdded(false),
-      mPositionAdded(false),
-      mPointSizeAdded(false),
       mLastFragDataAdded(false),
       mFragColorAdded(false),
       mFragDataAdded(false),
@@ -202,8 +218,13 @@
       mSecondaryFragColorEXTAdded(false),
       mSecondaryFragDataEXTAdded(false),
       mPerVertexInAdded(false),
+      mPrimitiveIDInAdded(false),
+      mInvocationIDAdded(false),
+      mPrimitiveIDAdded(false),
+      mLayerAdded(false),
       mHashFunction(hashFunction),
       mShaderVersion(shaderVersion),
+      mShaderType(shaderType),
       mExtensionBehavior(extensionBehavior)
 {
 }
@@ -470,6 +491,38 @@
                 recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
                                                 &mSecondaryFragDataEXTAdded);
                 return;
+            case EvqInvocationID:
+                recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
+                break;
+            case EvqPrimitiveIDIn:
+                recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
+                break;
+            case EvqPrimitiveID:
+                if (mShaderType == GL_GEOMETRY_SHADER_OES)
+                {
+                    recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
+                }
+                else
+                {
+                    ASSERT(mShaderType == GL_FRAGMENT_SHADER);
+                    recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
+                }
+                break;
+            case EvqLayer:
+                if (mShaderType == GL_GEOMETRY_SHADER_OES)
+                {
+                    recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
+                }
+                else if (mShaderType == GL_FRAGMENT_SHADER)
+                {
+                    recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
+                }
+                else
+                {
+                    ASSERT(mShaderType == GL_VERTEX_SHADER &&
+                           IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview"));
+                }
+                break;
             default:
                 break;
         }
@@ -783,11 +836,13 @@
                       ShHashFunction64 hashFunction,
                       TSymbolTable *symbolTable,
                       int shaderVersion,
+                      GLenum shaderType,
                       const TExtensionBehavior &extensionBehavior)
 {
     CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
                                       outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
-                                      hashFunction, symbolTable, shaderVersion, extensionBehavior);
+                                      hashFunction, symbolTable, shaderVersion, shaderType,
+                                      extensionBehavior);
     root->traverse(&collect);
 }