Vulkan: Support for bools and bvec* uniforms

- Also enables the dEQP tests for bools and bvec*

Bug: angleproject:2442

Change-Id: Ib9ea017008293bf407bf7e5b5b881f376f226cd0
Reviewed-on: https://chromium-review.googlesource.com/985954
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index d6fecd7..f2761b5 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -437,29 +437,41 @@
         return;
     }
 
-    if (linkedUniform.type == entryPointType)
+    for (auto &uniformBlock : mDefaultUniformBlocks)
     {
-        for (auto &uniformBlock : mDefaultUniformBlocks)
+        const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
+
+        // Assume an offset of -1 means the block is unused.
+        if (layoutInfo.offset == -1)
         {
-            const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
-
-            // Assume an offset of -1 means the block is unused.
-            if (layoutInfo.offset == -1)
-            {
-                continue;
-            }
-
-            UpdateDefaultUniformBlock(count, locationInfo.arrayIndex,
-                                      linkedUniform.typeInfo->componentCount, v, layoutInfo,
-                                      &uniformBlock.uniformData);
-
-            uniformBlock.uniformsDirty = true;
+            continue;
         }
-    }
-    else
-    {
-        ASSERT(linkedUniform.type == gl::VariableBoolVectorType(entryPointType));
-        UNIMPLEMENTED();
+
+        const GLint componentCount = linkedUniform.typeInfo->componentCount;
+        if (linkedUniform.typeInfo->type == entryPointType)
+        {
+            UpdateDefaultUniformBlock(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
+                                      &uniformBlock.uniformData);
+        }
+        else
+        {
+            ASSERT(linkedUniform.typeInfo->type == gl::VariableBoolVectorType(entryPointType));
+
+            GLint initialArrayOffset = locationInfo.arrayIndex * layoutInfo.arrayStride;
+            for (GLint i = 0; i < count; i++)
+            {
+                GLint elementOffset = i * layoutInfo.arrayStride + initialArrayOffset;
+                GLint *dest =
+                    reinterpret_cast<GLint *>(uniformBlock.uniformData.data() + elementOffset);
+                const T *source = v + i * componentCount;
+
+                for (int c = 0; c < componentCount; c++)
+                {
+                    dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
+                }
+            }
+        }
+        uniformBlock.uniformsDirty = true;
     }
 }
 
@@ -475,13 +487,15 @@
         return;
     }
 
-    ASSERT(linkedUniform.typeInfo->componentType == entryPointType);
     const gl::ShaderType shaderType = linkedUniform.getFirstShaderTypeWhereActive();
     ASSERT(shaderType != gl::ShaderType::InvalidEnum);
 
     const DefaultUniformBlock &uniformBlock =
         mDefaultUniformBlocks[static_cast<GLuint>(shaderType)];
     const sh::BlockMemberInfo &layoutInfo   = uniformBlock.uniformLayout[location];
+
+    ASSERT(linkedUniform.typeInfo->componentType == entryPointType ||
+           linkedUniform.typeInfo->componentType == gl::VariableBoolVectorType(entryPointType));
     ReadFromDefaultUniformBlock(linkedUniform.typeInfo->componentCount, locationInfo.arrayIndex, v,
                                 layoutInfo, &uniformBlock.uniformData);
 }