Vulkan: Enable barrier validation using VK_EXT_validation_features.

This found a couple issues with readonly storage textures and buffers
and will prevent regression in the correctness of barriers in the Vulkan
backend.

Bug: dawn:635

Change-Id: I99f77134eff62c466d010c4f301f7e79de0b4977
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38021
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/vulkan/BackendVk.cpp b/src/dawn_native/vulkan/BackendVk.cpp
index 6e431f1..c9bcdcc 100644
--- a/src/dawn_native/vulkan/BackendVk.cpp
+++ b/src/dawn_native/vulkan/BackendVk.cpp
@@ -298,6 +298,21 @@
                                 VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT);
         }
 
+        // Try to turn on synchronization validation if the instance was created with backend
+        // validation enabled.
+        VkValidationFeaturesEXT validationFeatures;
+        VkValidationFeatureEnableEXT kEnableSynchronizationValidation =
+            VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT;
+        if (GetInstance()->IsBackendValidationEnabled() &&
+            usedKnobs.HasExt(InstanceExt::ValidationFeatures)) {
+            validationFeatures.enabledValidationFeatureCount = 1;
+            validationFeatures.pEnabledValidationFeatures = &kEnableSynchronizationValidation;
+            validationFeatures.disabledValidationFeatureCount = 0;
+            validationFeatures.pDisabledValidationFeatures = nullptr;
+
+            createInfoChain.Add(&validationFeatures, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT);
+        }
+
         DAWN_TRY(CheckVkSuccess(mFunctions.CreateInstance(&createInfo, nullptr, &mInstance),
                                 "vkCreateInstance"));
 
diff --git a/src/dawn_native/vulkan/VulkanExtensions.cpp b/src/dawn_native/vulkan/VulkanExtensions.cpp
index 4c07d69..3073625 100644
--- a/src/dawn_native/vulkan/VulkanExtensions.cpp
+++ b/src/dawn_native/vulkan/VulkanExtensions.cpp
@@ -48,6 +48,7 @@
         {InstanceExt::XlibSurface, "VK_KHR_xlib_surface", NeverPromoted},
 
         {InstanceExt::DebugUtils, "VK_EXT_debug_utils", NeverPromoted},
+        {InstanceExt::ValidationFeatures, "VK_EXT_validation_features", NeverPromoted},
         //
     }};
 
@@ -88,6 +89,7 @@
                 case InstanceExt::GetPhysicalDeviceProperties2:
                 case InstanceExt::Surface:
                 case InstanceExt::DebugUtils:
+                case InstanceExt::ValidationFeatures:
                     hasDependencies = true;
                     break;
 
diff --git a/src/dawn_native/vulkan/VulkanExtensions.h b/src/dawn_native/vulkan/VulkanExtensions.h
index 91af192..bd87527 100644
--- a/src/dawn_native/vulkan/VulkanExtensions.h
+++ b/src/dawn_native/vulkan/VulkanExtensions.h
@@ -40,6 +40,7 @@
 
         // Others
         DebugUtils,
+        ValidationFeatures,
 
         EnumCount,
     };
diff --git a/src/tests/end2end/QueueTests.cpp b/src/tests/end2end/QueueTests.cpp
index 5ebb86b..1ed3fab 100644
--- a/src/tests/end2end/QueueTests.cpp
+++ b/src/tests/end2end/QueueTests.cpp
@@ -118,6 +118,11 @@
     // once the issue with Metal on 10.14.6 is fixed.
     DAWN_SKIP_TEST_IF(IsMacOS() && IsIntel() && IsMetal());
 
+    // The Vulkan Validation Layers' memory barrier validation keeps track of every range written
+    // to independently which causes validation of each WriteBuffer to take increasing time, and
+    // this test to take forever. Skip it when VVLs are enabled.
+    DAWN_SKIP_TEST_IF(IsVulkan() && IsBackendValidationEnabled());
+
     constexpr uint64_t kSize = 4000 * 1000;
     constexpr uint32_t kElements = 250 * 250;
     wgpu::BufferDescriptor descriptor;