Add compute shader compilation support in the glsl compiler

Support is added for compute shader compilation. There is a small
extension to the parser so that 'local_size_x = ', 'local_size_y = '
and 'local_size_z = ' are supported as layout qualifiers.

A few shader compilation tests are added and one which checks the AST
whether the layout qualifiers are properly parsed.

BUG=angleproject:1442

TEST=angle_unittests
TEST=angle_end2end_tests

Change-Id: I67283797d1cf13fa4ac47faa2a6e66d93a2db867
Reviewed-on: https://chromium-review.googlesource.com/362300
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 6973a2c..ce71488 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -65,8 +65,10 @@
           mUsesFragColor(false),
           mUsesSecondaryOutputs(false),
           mMinProgramTexelOffset(resources.MinProgramTexelOffset),
-          mMaxProgramTexelOffset(resources.MaxProgramTexelOffset)
+          mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
+          mComputeShaderLocalSizeDeclared(false)
     {
+        mComputeShaderLocalSize.fill(-1);
     }
 
     const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
@@ -114,6 +116,9 @@
     void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
     void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
 
+    bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
+    TLocalSize getComputeShaderLocalSize() const;
+
     // This method is guaranteed to succeed, even if no variable with 'name' exists.
     const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
     TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
@@ -149,6 +154,11 @@
     bool extensionErrorCheck(const TSourceLoc &line, const TString&);
     bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
     bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier);
+    void layoutSupportedErrorCheck(const TSourceLoc &location,
+                                   const TString &layoutQualifierName,
+                                   int versionRequired);
+    bool layoutWorkGroupSizeErrorCheck(const TSourceLoc &location,
+                                       const TLayoutQualifier &layoutQualifier);
     bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
     void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
     void es3InputOutputTypeCheck(const TQualifier qualifier,
@@ -279,14 +289,22 @@
                                         TIntermTyped *arrayIndex,
                                         const TSourceLoc& arrayIndexLine);
 
+    void parseLocalSize(const TString &qualifierType,
+                        const TSourceLoc &qualifierTypeLine,
+                        int intValue,
+                        const TSourceLoc &intValueLine,
+                        const std::string &intValueString,
+                        size_t index,
+                        TLocalSize *localSize);
     TLayoutQualifier parseLayoutQualifier(
         const TString &qualifierType, const TSourceLoc &qualifierTypeLine);
     TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
                                           const TSourceLoc &qualifierTypeLine,
-                                          const TString &intValueString,
                                           int intValue,
                                           const TSourceLoc &intValueLine);
-    TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
+    TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
+                                          TLayoutQualifier rightQualifier,
+                                          const TSourceLoc &rightQualifierLocation);
     TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
                                             const TSourceLoc &storageLoc, TQualifier storageQualifier);
 
@@ -396,6 +414,10 @@
                                  // gl_Secondary FragColor or both.
     int mMinProgramTexelOffset;
     int mMaxProgramTexelOffset;
+
+    // keep track of local group size declared in layout. It should be declared only once.
+    bool mComputeShaderLocalSizeDeclared;
+    TLocalSize mComputeShaderLocalSize;
 };
 
 int PaParseStrings(