Validate precision in uniform blocks for WebGL.

In WebGL mode turn on checking that precision qualifiers match in
corresponding vertex/fragment uniform blocks.  Add test for this behavior.

BUG=angleproject:2015

Change-Id: Ie035138e8c46e430bdcf8fb5bbc3e0a3ab7d6391
Reviewed-on: https://chromium-review.googlesource.com/517724
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 9ff1490..3614b12 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -666,7 +666,7 @@
             return NoError();
         }
 
-        if (!linkUniformBlocks(mInfoLog, caps))
+        if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
         {
             return NoError();
         }
@@ -713,7 +713,7 @@
             return NoError();
         }
 
-        if (!linkUniformBlocks(mInfoLog, caps))
+        if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
         {
             return NoError();
         }
@@ -2069,10 +2069,12 @@
 bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog,
                                                const std::string &uniformName,
                                                const sh::InterfaceBlockField &vertexUniform,
-                                               const sh::InterfaceBlockField &fragmentUniform)
+                                               const sh::InterfaceBlockField &fragmentUniform,
+                                               bool webglCompatibility)
 {
-    // We don't validate precision on UBO fields. See resolution of Khronos bug 10287.
-    if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false))
+    // If webgl, validate precision of UBO fields, otherwise don't.  See Khronos bug 10287.
+    if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
+                                   webglCompatibility))
     {
         return false;
     }
@@ -2209,7 +2211,8 @@
 bool Program::validateVertexAndFragmentInterfaceBlocks(
     const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
     const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
-    InfoLog &infoLog) const
+    InfoLog &infoLog,
+    bool webglCompatibility) const
 {
     // Check that interface blocks defined in the vertex and fragment shaders are identical
     typedef std::map<std::string, const sh::InterfaceBlock *> UniformBlockMap;
@@ -2226,7 +2229,8 @@
         if (entry != linkedUniformBlocks.end())
         {
             const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
-            if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+            if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock,
+                                            webglCompatibility))
             {
                 return false;
             }
@@ -2235,7 +2239,7 @@
     return true;
 }
 
-bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
+bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility)
 {
     if (mState.mAttachedComputeShader)
     {
@@ -2273,7 +2277,7 @@
         return false;
     }
     if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks,
-                                                  infoLog))
+                                                  infoLog, webglCompatibility))
     {
         return false;
     }
@@ -2283,7 +2287,8 @@
 
 bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
                                          const sh::InterfaceBlock &vertexInterfaceBlock,
-                                         const sh::InterfaceBlock &fragmentInterfaceBlock) const
+                                         const sh::InterfaceBlock &fragmentInterfaceBlock,
+                                         bool webglCompatibility) const
 {
     const char* blockName = vertexInterfaceBlock.name.c_str();
     // validate blocks for the same member types
@@ -2322,7 +2327,8 @@
             return false;
         }
         std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
-        if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
+        if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember,
+                                              webglCompatibility))
         {
             return false;
         }