ES31: Add link validation on geometry shader interface block limits

This patch adds link validation on the maximum number of active
uniform blocks and shader storage blocks defined in the geometry
shader.

BUG=angleproject:1941
TEST=angle_end2end_tests

Change-Id: Ieffc234981a3f32a569392786e8fa1c6623a7a23
Reviewed-on: https://chromium-review.googlesource.com/966491
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jiajia Qin <jiajia.qin@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 2bbcfce..8e1abb9 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -205,7 +205,7 @@
     return false;
 }
 
-bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
+bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
                                   const std::vector<sh::InterfaceBlock> &interfaceBlocks,
                                   const std::string &errorMessage,
                                   InfoLog &infoLog)
@@ -2744,7 +2744,7 @@
         Shader &computeShader              = *mState.mAttachedComputeShader;
         const auto &computeUniformBlocks   = computeShader.getUniformBlocks(context);
 
-        if (!validateInterfaceBlocksCount(
+        if (!ValidateInterfaceBlocksCount(
                 caps.maxComputeUniformBlocks, computeUniformBlocks,
                 "Compute shader uniform block count exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS (",
                 infoLog))
@@ -2753,7 +2753,7 @@
         }
 
         const auto &computeShaderStorageBlocks = computeShader.getShaderStorageBlocks(context);
-        if (!validateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks,
                                           computeShaderStorageBlocks,
                                           "Compute shader shader storage block count exceeds "
                                           "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS (",
@@ -2770,13 +2770,13 @@
     const auto &vertexUniformBlocks   = vertexShader.getUniformBlocks(context);
     const auto &fragmentUniformBlocks = fragmentShader.getUniformBlocks(context);
 
-    if (!validateInterfaceBlocksCount(
+    if (!ValidateInterfaceBlocksCount(
             caps.maxVertexUniformBlocks, vertexUniformBlocks,
             "Vertex shader uniform block count exceeds GL_MAX_VERTEX_UNIFORM_BLOCKS (", infoLog))
     {
         return false;
     }
-    if (!validateInterfaceBlocksCount(
+    if (!ValidateInterfaceBlocksCount(
             caps.maxFragmentUniformBlocks, fragmentUniformBlocks,
             "Fragment shader uniform block count exceeds GL_MAX_FRAGMENT_UNIFORM_BLOCKS (",
             infoLog))
@@ -2785,6 +2785,20 @@
         return false;
     }
 
+    Shader *geometryShader = mState.mAttachedGeometryShader;
+    if (geometryShader)
+    {
+        const auto &geometryUniformBlocks = geometryShader->getUniformBlocks(context);
+        if (!ValidateInterfaceBlocksCount(
+                caps.maxGeometryUniformBlocks, geometryUniformBlocks,
+                "Geometry shader uniform block count exceeds GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT (",
+                infoLog))
+        {
+            return false;
+        }
+    }
+
+    // TODO(jiawei.shao@intel.com): validate geometry shader uniform blocks.
     bool webglCompatibility = context->getExtensions().webglCompatibility;
     if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog,
                                          webglCompatibility, sh::BlockType::BLOCK_UNIFORM,
@@ -2798,7 +2812,7 @@
         const auto &vertexShaderStorageBlocks   = vertexShader.getShaderStorageBlocks(context);
         const auto &fragmentShaderStorageBlocks = fragmentShader.getShaderStorageBlocks(context);
 
-        if (!validateInterfaceBlocksCount(caps.maxVertexShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxVertexShaderStorageBlocks,
                                           vertexShaderStorageBlocks,
                                           "Vertex shader shader storage block count exceeds "
                                           "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS (",
@@ -2806,7 +2820,7 @@
         {
             return false;
         }
-        if (!validateInterfaceBlocksCount(caps.maxFragmentShaderStorageBlocks,
+        if (!ValidateInterfaceBlocksCount(caps.maxFragmentShaderStorageBlocks,
                                           fragmentShaderStorageBlocks,
                                           "Fragment shader shader storage block count exceeds "
                                           "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS (",
@@ -2816,6 +2830,21 @@
             return false;
         }
 
+        if (geometryShader)
+        {
+            const auto &geometryShaderStorageBlocks =
+                geometryShader->getShaderStorageBlocks(context);
+            if (!ValidateInterfaceBlocksCount(caps.maxGeometryShaderStorageBlocks,
+                                              geometryShaderStorageBlocks,
+                                              "Geometry shader shader storage block count exceeds "
+                                              "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT (",
+                                              infoLog))
+            {
+                return false;
+            }
+        }
+
+        // TODO(jiawei.shao@intel.com): validate geometry shader shader storage blocks.
         if (!ValidateGraphicsInterfaceBlocks(
                 vertexShaderStorageBlocks, fragmentShaderStorageBlocks, infoLog, webglCompatibility,
                 sh::BlockType::BLOCK_BUFFER, caps.maxCombinedShaderStorageBlocks))