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/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 52ae411..dc2cd12 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -676,6 +676,15 @@
                                                       voidType, "groupMemoryBarrier");
     }
 
+    if (type == GL_GEOMETRY_SHADER_OES)
+    {
+        const char *extension = "GL_OES_geometry_shader";
+        symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex,
+                                                         voidType, "EmitVertex");
+        symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension,
+                                                         EOpEndPrimitive, voidType, "EndPrimitive");
+    }
+
     //
     // Depth range in window coordinates
     //
@@ -720,7 +729,7 @@
     {
         symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
                                       "gl_MaxDualSourceDrawBuffersEXT",
-                                      resources.MaxDualSourceDrawBuffers);
+                                      resources.MaxDualSourceDrawBuffers, EbpMedium);
     }
 
     symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
@@ -777,6 +786,29 @@
                                resources.MaxCombinedAtomicCounterBuffers, EbpMedium);
     symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
                                resources.MaxAtomicCounterBufferSize, EbpMedium);
+
+    if (resources.OES_geometry_shader)
+    {
+        const char *ext = "GL_OES_geometry_shader";
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryInputComponents",
+                                      resources.MaxGeometryInputComponents, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputComponents",
+                                      resources.MaxGeometryOutputComponents, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryImageUniforms",
+                                      resources.MaxGeometryImageUniforms, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTextureImageUnits",
+                                      resources.MaxGeometryTextureImageUnits, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputVertices",
+                                      resources.MaxGeometryOutputVertices, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTotalOutputComponents",
+                                      resources.MaxGeometryTotalOutputComponents, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryUniformComponents",
+                                      resources.MaxGeometryUniformComponents, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounters",
+                                      resources.MaxGeometryAtomicCounters, EbpMedium);
+        symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounterBuffers",
+                                      resources.MaxGeometryAtomicCounterBuffers, EbpMedium);
+    }
 }
 
 void IdentifyBuiltIns(sh::GLenum type,
@@ -872,6 +904,15 @@
                                               TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
             }
 
+            if (resources.OES_geometry_shader)
+            {
+                const char *extension = "GL_OES_geometry_shader";
+                symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
+                                              TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
+                symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
+                                              TType(EbtInt, EbpHigh, EvqLayer, 1));
+            }
+
             break;
         }
         case GL_VERTEX_SHADER:
@@ -909,7 +950,6 @@
 
         case GL_GEOMETRY_SHADER_OES:
         {
-            // TODO(jiawei.shao@intel.com): add all Geometry Shader built-in variables.
             const char *extension = "GL_OES_geometry_shader";
 
             // Add built-in interface block gl_PerVertex and the built-in array gl_in.
@@ -932,6 +972,20 @@
             glInType.makeArray(0u);
             symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
 
+            TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4);
+            glPositionType.setInterfaceBlock(new TInterfaceBlock(
+                glPerVertexString, fieldList, nullptr, TLayoutQualifier::create()));
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position",
+                                          glPositionType);
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn",
+                                          TType(EbtInt, EbpHigh, EvqPrimitiveIDIn, 1));
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID",
+                                          TType(EbtInt, EbpHigh, EvqInvocationID, 1));
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
+                                          TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
+            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
+                                          TType(EbtInt, EbpHigh, EvqLayer, 1));
+
             break;
         }
         default: