Add support for EXT_YUV_target

Add new sampler type "__samplerExternal2DY2YEXT"
to sample a YUV texture image and output color value
without any color conversion,
new additional type to specify color space standard formula and
built-in functions for yuv to rgb transformation.

Change-Id: I1780650fe84cd75191c1ca1e4118e89d585bfd92
Reviewed-on: https://chromium-review.googlesource.com/454697
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 47325d4..bb08882 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1188,6 +1188,15 @@
         return;
     }
 
+    if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
+         publicType.qualifier != EvqConst) &&
+        publicType.getBasicType() == EbtYuvCscStandardEXT)
+    {
+        error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
+              getQualifierString(publicType.qualifier));
+        return;
+    }
+
     // check for layout qualifier issues
     const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
 
@@ -1226,6 +1235,19 @@
         checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier);
     }
 
+    if (publicType.qualifier == EvqFragmentOut)
+    {
+        if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
+        {
+            error(identifierLocation, "invalid layout qualifier combination", "yuv");
+            return;
+        }
+    }
+    else
+    {
+        checkYuvIsNotSpecified(identifierLocation, layoutQualifier.yuv);
+    }
+
     if (IsImage(publicType.getBasicType()))
     {
 
@@ -1402,6 +1424,14 @@
     }
 }
 
+void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
+{
+    if (yuv != false)
+    {
+        error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
+    }
+}
+
 void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
                                                  TIntermAggregate *fnCall)
 {
@@ -2340,6 +2370,8 @@
 
     checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
 
+    checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
+
     if (typeQualifier.qualifier == EvqComputeIn)
     {
         if (mComputeShaderLocalSizeDeclared &&
@@ -2818,6 +2850,8 @@
     // TODO(oetuaho): Remove this and support binding for blocks.
     checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
 
+    checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
+
     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
     checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
 
@@ -3304,6 +3338,11 @@
         error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
               qualifierType.c_str());
     }
+    else if (qualifierType == "yuv" && isExtensionEnabled("GL_EXT_YUV_target") &&
+             mShaderType == GL_FRAGMENT_SHADER)
+    {
+        qualifier.yuv = true;
+    }
     else if (qualifierType == "rgba32f")
     {
         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);