Vulkan: Check for required features when initializing adapters

Core WebGPU requires some Vulkan features to be implemented. Check for
them so that we don't return an adapter for a Vulkan device with
insufficient features.

Bug: dawn:796
Change-Id: I445760f184807b8f2d4ee248289b512c18038f33
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/55920
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp
index 532def4..a8f936e 100644
--- a/src/dawn_native/vulkan/AdapterVk.cpp
+++ b/src/dawn_native/vulkan/AdapterVk.cpp
@@ -39,11 +39,7 @@
 
     MaybeError Adapter::Initialize() {
         DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
-        if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
-            return DAWN_INTERNAL_ERROR(
-                "Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support "
-                "viewport flipY");
-        }
+        DAWN_TRY(CheckCoreWebGPUSupport());
 
         if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
             mDriverDescription = mDeviceInfo.driverProperties.driverName;
@@ -79,6 +75,42 @@
         return {};
     }
 
+    MaybeError Adapter::CheckCoreWebGPUSupport() {
+        // Needed for viewport Y-flip.
+        if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
+            return DAWN_INTERNAL_ERROR("Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 required.");
+        }
+
+        // Needed for security
+        if (!mDeviceInfo.features.robustBufferAccess) {
+            return DAWN_INTERNAL_ERROR("Vulkan robustBufferAccess feature required.");
+        }
+
+        // TODO(crbug.com/dawn/955): Require BC || (ETC && ASTC) instead.
+        if (!mDeviceInfo.features.textureCompressionBC) {
+            return DAWN_INTERNAL_ERROR("Vulkan textureCompressionBC feature required.");
+        }
+
+        // Needed for the respective WebGPU features.
+        if (!mDeviceInfo.features.depthBiasClamp) {
+            return DAWN_INTERNAL_ERROR("Vulkan depthBiasClamp feature required.");
+        }
+        if (!mDeviceInfo.features.fragmentStoresAndAtomics) {
+            return DAWN_INTERNAL_ERROR("Vulkan fragmentStoresAndAtomics feature required.");
+        }
+        if (!mDeviceInfo.features.fullDrawIndexUint32) {
+            return DAWN_INTERNAL_ERROR("Vulkan fullDrawIndexUint32 feature required.");
+        }
+        if (!mDeviceInfo.features.imageCubeArray) {
+            return DAWN_INTERNAL_ERROR("Vulkan imageCubeArray feature required.");
+        }
+        if (!mDeviceInfo.features.independentBlend) {
+            return DAWN_INTERNAL_ERROR("Vulkan independentBlend feature required.");
+        }
+
+        return {};
+    }
+
     void Adapter::InitializeSupportedExtensions() {
         if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
             mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
diff --git a/src/dawn_native/vulkan/AdapterVk.h b/src/dawn_native/vulkan/AdapterVk.h
index 67f77d9..94939d2 100644
--- a/src/dawn_native/vulkan/AdapterVk.h
+++ b/src/dawn_native/vulkan/AdapterVk.h
@@ -37,6 +37,7 @@
 
       private:
         ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
+        MaybeError CheckCoreWebGPUSupport();
         void InitializeSupportedExtensions();
 
         VkPhysicalDevice mPhysicalDevice;
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 8f94b16..2f7cbad 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -315,14 +315,12 @@
         features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
         PNextChainBuilder featuresChain(&features2);
 
-        // Always require independentBlend because it is a core Dawn feature
-        usedKnobs.features.independentBlend = VK_TRUE;
-        // Always require imageCubeArray because it is a core Dawn feature
-        usedKnobs.features.imageCubeArray = VK_TRUE;
-        // Always require fragmentStoresAndAtomics because it is required by end2end tests.
-        usedKnobs.features.fragmentStoresAndAtomics = VK_TRUE;
-        // Always require depthBiasClamp because it is a core Dawn feature
+        // Required for core WebGPU features.
         usedKnobs.features.depthBiasClamp = VK_TRUE;
+        usedKnobs.features.fragmentStoresAndAtomics = VK_TRUE;
+        usedKnobs.features.fullDrawIndexUint32 = VK_TRUE;
+        usedKnobs.features.imageCubeArray = VK_TRUE;
+        usedKnobs.features.independentBlend = VK_TRUE;
 
         if (IsRobustnessEnabled()) {
             usedKnobs.features.robustBufferAccess = VK_TRUE;