Disallow multiple locations on output variables

GLSL ES specs from version 3.00 to 3.20 all mention that output layout
location qualifier may appear at most once within a declaration.
Enforce this rule when parsing shaders.

Also set max draw buffers to 8 when compiling GLSL ES >= 3.00 in the
qualification order tests and shader translator sample, so that
parsing locations > 0 will succeed.

BUG=angleproject:1505
TEST=angle_unittests

Change-Id: I50fe409041385f5e10e695f43dc3a572433e9772
Reviewed-on: https://chromium-review.googlesource.com/381211
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index 78e06b3..0919955 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -387,6 +387,7 @@
 struct TLayoutQualifier
 {
     int location;
+    unsigned int locationsSpecified;
     TLayoutMatrixPacking matrixPacking;
     TLayoutBlockStorage blockStorage;
 
@@ -398,6 +399,7 @@
         TLayoutQualifier layoutQualifier;
 
         layoutQualifier.location = -1;
+        layoutQualifier.locationsSpecified = 0;
         layoutQualifier.matrixPacking = EmpUnspecified;
         layoutQualifier.blockStorage = EbsUnspecified;
 
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index fc3c2c5..9a08ddf 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -2935,6 +2935,7 @@
         else
         {
             qualifier.location = intValue;
+            qualifier.locationsSpecified = 1;
         }
     }
     else if (qualifierType == "local_size_x")
diff --git a/src/compiler/translator/QualifierTypes.cpp b/src/compiler/translator/QualifierTypes.cpp
index 27d73aa..b785627 100644
--- a/src/compiler/translator/QualifierTypes.cpp
+++ b/src/compiler/translator/QualifierTypes.cpp
@@ -22,6 +22,7 @@
     if (rightQualifier.location != -1)
     {
         joinedQualifier.location = rightQualifier.location;
+        ++joinedQualifier.locationsSpecified;
     }
     if (rightQualifier.matrixPacking != EmpUnspecified)
     {
@@ -98,6 +99,9 @@
     bool layoutFound        = false;
     bool interpolationFound = false;
 
+    unsigned int locationsSpecified = 0;
+    bool isOut                      = false;
+
     // The iteration starts from one since the first qualifier only reveals the scope of the
     // expression. It is inserted first whenever the sequence gets created.
     for (size_t i = 1; i < qualifiers.size(); ++i)
@@ -132,6 +136,9 @@
                     return true;
                 }
                 layoutFound = true;
+                const TLayoutQualifier &currentQualifier =
+                    static_cast<const TLayoutQualifierWrapper *>(qualifiers[i])->getQualifier();
+                locationsSpecified += currentQualifier.locationsSpecified;
                 break;
             }
             case QtInterpolation:
@@ -153,6 +160,10 @@
                 // repetitions.
                 TQualifier currentQualifier =
                     static_cast<const TStorageQualifierWrapper *>(qualifiers[i])->getQualifier();
+                if (currentQualifier == EvqVertexOut || currentQualifier == EvqFragmentOut)
+                {
+                    isOut = true;
+                }
                 for (size_t j = 1; j < i; ++j)
                 {
                     if (qualifiers[j]->getType() == QtStorage)
@@ -175,6 +186,15 @@
         }
     }
 
+    if (locationsSpecified > 1 && isOut)
+    {
+        // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers
+        // GLSL ES 3.10 section 4.4.2 Output Layout Qualifiers
+        // "The qualifier may appear at most once within a declaration."
+        *errorMessage = "Output layout location specified multiple times.";
+        return true;
+    }
+
     return false;
 }