Validate that fragment shader output matches the draw buffer type.

TEST=conformance2/rendering/fs-color-type-mismatch-color-buffer-type
BUG=angleproject:1688

Change-Id: I17848baf40b6d32b5adc1458fe2369b850164da3
Reviewed-on: https://chromium-review.googlesource.com/518246
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 0bfdc24..4e5b8fe 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -718,6 +718,28 @@
     return false;
 }
 
+bool ValidateFragmentShaderColorBufferTypeMatch(ValidationContext *context)
+{
+    const Program *program         = context->getGLState().getProgram();
+    const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
+
+    const auto &programOutputTypes = program->getOutputVariableTypes();
+    for (size_t drawBufferIdx = 0; drawBufferIdx < programOutputTypes.size(); drawBufferIdx++)
+    {
+        GLenum outputType = programOutputTypes[drawBufferIdx];
+        GLenum inputType  = framebuffer->getDrawbufferWriteType(drawBufferIdx);
+        if (outputType != GL_NONE && inputType != GL_NONE && inputType != outputType)
+        {
+            context->handleError(Error(GL_INVALID_OPERATION,
+                                       "Fragment shader output type does not match the bound "
+                                       "framebuffer attachment type."));
+            return false;
+        }
+    }
+
+    return true;
+}
+
 }  // anonymous namespace
 
 bool ValidTextureTarget(const ValidationContext *context, GLenum target)
@@ -2713,9 +2735,10 @@
         }
     }
 
-    // Detect rendering feedback loops for WebGL.
+    // Do some additonal WebGL-specific validation
     if (context->getExtensions().webglCompatibility)
     {
+        // Detect rendering feedback loops for WebGL.
         if (framebuffer->formsRenderingFeedbackLoopWith(state))
         {
             context->handleError(
@@ -2723,6 +2746,12 @@
                       "Rendering feedback loop formed between Framebuffer and active Texture."));
             return false;
         }
+
+        // Detect that the color buffer types match the fragment shader output types
+        if (!ValidateFragmentShaderColorBufferTypeMatch(context))
+        {
+            return false;
+        }
     }
 
     // No-op if zero count