Constant fold compute shader local work group size

gl_WorkGroupSize should be written into the AST as a constant node
instead of a symbol node. In correct shaders, local size is guaranteed
to have been declared before any references to gl_WorkGroupSize -
otherwise the shader translator was already generating an error.

This ensures that work group size can be used to size arrays as
specified and also works around a crash issue on NVIDIA Linux OpenGL
driver.

BUG=angleproject:1442
TEST=angle_unittests

Change-Id: I9b1a4bff16ecf2c3db1511c3702756346cdd2f6b
Reviewed-on: https://chromium-review.googlesource.com/418735
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 3066df4..8807eee 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1471,6 +1471,25 @@
         const TConstantUnion *constArray = variable->getConstPointer();
         return intermediate.addConstantUnion(constArray, variable->getType(), location);
     }
+    else if (variable->getType().getQualifier() == EvqWorkGroupSize &&
+             mComputeShaderLocalSizeDeclared)
+    {
+        // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
+        // needs to be added to the AST as a constant and not as a symbol.
+        sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
+        TConstantUnion *constArray      = new TConstantUnion[3];
+        for (size_t i = 0; i < 3; ++i)
+        {
+            constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
+        }
+
+        ASSERT(variable->getType().getBasicType() == EbtUInt);
+        ASSERT(variable->getType().getObjectSize() == 3);
+
+        TType type(variable->getType());
+        type.setQualifier(EvqConst);
+        return intermediate.addConstantUnion(constArray, type, location);
+    }
     else
     {
         return intermediate.addSymbol(variable->getUniqueId(), variable->getName(),