Add es3.1 shader constants

The patch adds all shader built-in constants.

BUG=angleproject:1442

TEST=angle_unittests
TEST=angle_end2end_tests

Change-Id: I81cae479d6506a8faa2dce023d5fcc2c1291d521
Reviewed-on: https://chromium-review.googlesource.com/364460
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index b1c1774..f586c7f 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -427,6 +427,7 @@
     symbolTable.push();   // COMMON_BUILTINS
     symbolTable.push();   // ESSL1_BUILTINS
     symbolTable.push();   // ESSL3_BUILTINS
+    symbolTable.push();   // ESSL3_1_BUILTINS
 
     TPublicType integer;
     integer.type = EbtInt;
@@ -515,7 +516,31 @@
               << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
               << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
               << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
-              << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
+              << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
+              << ":MaxImageUnits:" << compileResources.MaxImageUnits
+              << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
+              << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
+              << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
+              << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
+              << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
+              << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
+              << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
+              << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
+              << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
+              << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
+              << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
+              << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
+              << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
+              << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
+              << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
+              << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
+              << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
+              << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
+              << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
+              << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
+              << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
+              << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
+              << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
     // clang-format on
 
     builtInResourcesString = strstream.str();
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index b45e47b..87dc8d6 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -495,18 +495,26 @@
     //
     // Implementation dependent built-in constants.
     //
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits);
-    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs,
+                               EbpMedium);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors",
+                               resources.MaxVertexUniformVectors, EbpMedium);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits",
+                               resources.MaxVertexTextureImageUnits, EbpMedium);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits",
+                               resources.MaxCombinedTextureImageUnits, EbpMedium);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits",
+                               resources.MaxTextureImageUnits, EbpMedium);
+    symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors",
+                               resources.MaxFragmentUniformVectors, EbpMedium);
 
-    symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors);
+    symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
+                               EbpMedium);
 
     if (spec != SH_CSS_SHADERS_SPEC)
     {
-        symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
+        symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
+                                   EbpMedium);
         if (resources.EXT_blend_func_extended)
         {
             symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
@@ -515,10 +523,60 @@
         }
     }
 
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset);
-    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset);
+    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
+                               resources.MaxVertexOutputVectors, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors",
+                               resources.MaxFragmentInputVectors, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset",
+                               resources.MinProgramTexelOffset, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset",
+                               resources.MaxProgramTexelOffset, EbpMedium);
+
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxImageUnits", resources.MaxImageUnits,
+                               EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms",
+                               resources.MaxVertexImageUniforms, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms",
+                               resources.MaxFragmentImageUniforms, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms",
+                               resources.MaxComputeImageUniforms, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms",
+                               resources.MaxCombinedImageUniforms, EbpMedium);
+
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources",
+                               resources.MaxCombinedShaderOutputResources, EbpMedium);
+
+    symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount",
+                                 resources.MaxComputeWorkGroupCount, EbpHigh);
+    symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize",
+                                 resources.MaxComputeWorkGroupSize, EbpHigh);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents",
+                               resources.MaxComputeUniformComponents, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits",
+                               resources.MaxComputeTextureImageUnits, EbpMedium);
+
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters",
+                               resources.MaxComputeAtomicCounters, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers",
+                               resources.MaxComputeAtomicCounterBuffers, EbpMedium);
+
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters",
+                               resources.MaxVertexAtomicCounters, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters",
+                               resources.MaxFragmentAtomicCounters, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters",
+                               resources.MaxCombinedAtomicCounters, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings",
+                               resources.MaxAtomicCounterBindings, EbpMedium);
+
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers",
+                               resources.MaxVertexAtomicCounterBuffers, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
+                               resources.MaxFragmentAtomicCounterBuffers, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
+                               resources.MaxCombinedAtomicCounterBuffers, EbpMedium);
+    symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
+                               resources.MaxAtomicCounterBufferSize, EbpMedium);
 }
 
 void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index c679c62..c000598 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -182,6 +182,37 @@
     resources->MaxExpressionComplexity = 256;
     resources->MaxCallStackDepth       = 256;
     resources->MaxFunctionParameters   = 1024;
+
+    // ES 3.1 Revision 4, 7.2 Built-in Constants
+    resources->MaxImageUnits            = 4;
+    resources->MaxVertexImageUniforms   = 0;
+    resources->MaxFragmentImageUniforms = 0;
+    resources->MaxComputeImageUniforms  = 4;
+    resources->MaxCombinedImageUniforms = 4;
+
+    resources->MaxCombinedShaderOutputResources = 4;
+
+    resources->MaxComputeWorkGroupCount[0] = 65535;
+    resources->MaxComputeWorkGroupCount[1] = 65535;
+    resources->MaxComputeWorkGroupCount[2] = 65535;
+    resources->MaxComputeWorkGroupSize[0]  = 128;
+    resources->MaxComputeWorkGroupSize[1]  = 128;
+    resources->MaxComputeWorkGroupSize[2]  = 64;
+    resources->MaxComputeUniformComponents = 512;
+    resources->MaxComputeTextureImageUnits = 16;
+
+    resources->MaxComputeAtomicCounters       = 8;
+    resources->MaxComputeAtomicCounterBuffers = 1;
+
+    resources->MaxVertexAtomicCounters   = 0;
+    resources->MaxFragmentAtomicCounters = 0;
+    resources->MaxCombinedAtomicCounters = 8;
+    resources->MaxAtomicCounterBindings  = 1;
+
+    resources->MaxVertexAtomicCounterBuffers   = 0;
+    resources->MaxFragmentAtomicCounterBuffers = 0;
+    resources->MaxCombinedAtomicCounterBuffers = 1;
+    resources->MaxAtomicCounterBufferSize      = 32;
 }
 
 //
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index f578909..059c5c7 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -88,7 +88,9 @@
 
     do
     {
-        if (level == ESSL3_BUILTINS && shaderVersion != 300)
+        if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
+            level--;
+        if (level == ESSL3_BUILTINS && shaderVersion < 300)
             level--;
         if (level == ESSL1_BUILTINS && shaderVersion != 100)
             level--;
@@ -110,7 +112,9 @@
 {
     for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
     {
-        if (level == ESSL3_BUILTINS && shaderVersion != 300)
+        if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
+            level--;
+        if (level == ESSL3_BUILTINS && shaderVersion < 300)
             level--;
         if (level == ESSL1_BUILTINS && shaderVersion != 100)
             level--;
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index a3ca98f..0571065 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -30,6 +30,7 @@
 //   are tracked in the intermediate representation, not the symbol table.
 //
 
+#include <array>
 #include <assert.h>
 #include <set>
 
@@ -317,8 +318,9 @@
 const int COMMON_BUILTINS = 0;
 const int ESSL1_BUILTINS = 1;
 const int ESSL3_BUILTINS = 2;
-const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
-const int GLOBAL_LEVEL = 3;
+const int ESSL3_1_BUILTINS   = 3;
+const int LAST_BUILTIN_LEVEL = ESSL3_1_BUILTINS;
+const int GLOBAL_LEVEL       = 4;
 
 class TSymbolTable : angle::NonCopyable
 {
@@ -379,10 +381,10 @@
         return table[level]->insert(symbol);
     }
 
-    bool insertConstInt(ESymbolLevel level, const char *name, int value)
+    bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
     {
-        TVariable *constant = new TVariable(
-            NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
+        TVariable *constant =
+            new TVariable(NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1));
         TConstantUnion *unionArray = new TConstantUnion[1];
         unionArray[0].setIConst(value);
         constant->shareConstPointer(unionArray);
@@ -399,6 +401,24 @@
         return insert(level, ext, constant);
     }
 
+    bool insertConstIvec3(ESymbolLevel level,
+                          const char *name,
+                          const std::array<int, 3> &values,
+                          TPrecision precision)
+    {
+        TVariable *constantIvec3 =
+            new TVariable(NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3));
+
+        TConstantUnion *unionArray = new TConstantUnion[3];
+        for (size_t index = 0u; index < 3u; ++index)
+        {
+            unionArray[index].setIConst(values[index]);
+        }
+        constantIvec3->shareConstPointer(unionArray);
+
+        return insert(level, constantIvec3);
+    }
+
     void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
                        const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0);