Revert "webgpu.h: Remove EnumerateFeatures()"

This reverts commit 476693ae501a3a39851858ded2bd430d4c811104.

Reason for revert: Causing Dawn->Chromium roll to fail due to outstanding dependency in MLDrift

Original change's description:
> webgpu.h: Remove EnumerateFeatures()
>
> Now that GetFeatures() has been added, we can safely remove the
> deprecated EnumerateFeatures().
>
> Bug: 368672123
> Change-Id: Ia8a4b377ff9b41219543f3a1071aacfe05d07998
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/215514
> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
> Commit-Queue: Fr <beaufort.francois@gmail.com>
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>

TBR=cwallez@chromium.org,kainino@chromium.org,beaufort.francois@gmail.com,dawn-scoped@luci-project-accounts.iam.gserviceaccount.com

Change-Id: I960cf163580307a8488955f486387572af4322dd
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 368672123
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/215794
Reviewed-by: Brandon Jones <bajones@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index d719a2c..5450df5 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -155,6 +155,14 @@
                 ]
             },
             {
+                "name": "enumerate features",
+                "tags": ["deprecated"],
+                "returns": "size_t",
+                "args": [
+                    {"name": "features", "type": "feature name", "annotation": "*"}
+                ]
+            },
+            {
                 "name": "get features",
                 "returns": "void",
                 "args": [
@@ -1559,6 +1567,14 @@
                 ]
             },
             {
+                "name": "enumerate features",
+                "tags": ["deprecated"],
+                "returns": "size_t",
+                "args": [
+                    {"name": "features", "type": "feature name", "annotation": "*"}
+                ]
+            },
+            {
                 "name": "get features",
                 "returns": "void",
                 "args": [
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index ba541a9..f95a1ca 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -224,6 +224,7 @@
             "AdapterGetInstance",
             "AdapterGetLimits",
             "AdapterHasFeature",
+            "AdapterEnumerateFeatures",
             "AdapterRequestDevice",
             "AdapterRequestDeviceF",
             "AdapterRequestDevice2",
@@ -247,6 +248,7 @@
             "DeviceGetFeatures",
             "DeviceGetLimits",
             "DeviceHasFeature",
+            "DeviceEnumerateFeatures",
             "DevicePopErrorScope",
             "DevicePopErrorScopeF",
             "DevicePopErrorScope2",
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index c2f0e70..be0cca3 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -224,6 +224,10 @@
     return mSupportedFeatures.IsEnabled(feature);
 }
 
+size_t AdapterBase::APIEnumerateFeatures(wgpu::FeatureName* features) const {
+    return mSupportedFeatures.EnumerateFeatures(features);
+}
+
 void AdapterBase::APIGetFeatures(wgpu::SupportedFeatures* features) const {
     this->APIGetFeatures(reinterpret_cast<SupportedFeatures*>(features));
 }
diff --git a/src/dawn/native/Adapter.h b/src/dawn/native/Adapter.h
index bcf4a06..28b5bcf 100644
--- a/src/dawn/native/Adapter.h
+++ b/src/dawn/native/Adapter.h
@@ -63,6 +63,7 @@
     wgpu::Status APIGetLimits(SupportedLimits* limits) const;
     wgpu::Status APIGetInfo(AdapterInfo* info) const;
     bool APIHasFeature(wgpu::FeatureName feature) const;
+    size_t APIEnumerateFeatures(wgpu::FeatureName* features) const;
     void APIGetFeatures(SupportedFeatures* features) const;
     void APIGetFeatures(wgpu::SupportedFeatures* features) const;
     void APIRequestDevice(const DeviceDescriptor* descriptor,
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 423889c..eea04ac 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -2009,6 +2009,10 @@
     return mEnabledFeatures.IsEnabled(feature);
 }
 
+size_t DeviceBase::APIEnumerateFeatures(wgpu::FeatureName* features) const {
+    return mEnabledFeatures.EnumerateFeatures(features);
+}
+
 void DeviceBase::APIGetFeatures(wgpu::SupportedFeatures* features) const {
     this->APIGetFeatures(reinterpret_cast<SupportedFeatures*>(features));
 }
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h
index 2b0708f..4f9b327 100644
--- a/src/dawn/native/Device.h
+++ b/src/dawn/native/Device.h
@@ -288,6 +288,7 @@
                                                  AHardwareBufferProperties* properties);
     wgpu::Status APIGetLimits(SupportedLimits* limits) const;
     bool APIHasFeature(wgpu::FeatureName feature) const;
+    size_t APIEnumerateFeatures(wgpu::FeatureName* features) const;
     void APIGetFeatures(wgpu::SupportedFeatures* features) const;
     void APIGetFeatures(SupportedFeatures* features) const;
     wgpu::Status APIGetAdapterInfo(AdapterInfo* adapterInfo) const;
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index 52d2964..f0c3944 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -421,6 +421,17 @@
     return f != Feature::InvalidEnum && IsEnabled(f);
 }
 
+size_t FeaturesSet::EnumerateFeatures(wgpu::FeatureName* features) const {
+    for (Feature f : IterateBitSet(featuresBitSet)) {
+        wgpu::FeatureName feature = ToAPI(f);
+        if (features != nullptr) {
+            *features = feature;
+            features += 1;
+        }
+    }
+    return featuresBitSet.count();
+}
+
 std::vector<const char*> FeaturesSet::GetEnabledFeatureNames() const {
     std::vector<const char*> enabledFeatureNames(featuresBitSet.count());
 
diff --git a/src/dawn/native/Features.h b/src/dawn/native/Features.h
index 915b137..d97d0b5 100644
--- a/src/dawn/native/Features.h
+++ b/src/dawn/native/Features.h
@@ -56,6 +56,9 @@
     void EnableFeature(wgpu::FeatureName feature);
     bool IsEnabled(Feature feature) const;
     bool IsEnabled(wgpu::FeatureName feature) const;
+    // Returns |count|, the number of features. Writes out all |count| values if |features| is
+    // non-null.
+    size_t EnumerateFeatures(wgpu::FeatureName* features) const;
     std::vector<const char*> GetEnabledFeatureNames() const;
     void ToSupportedFeatures(SupportedFeatures* supportedFeatures) const;
 };
diff --git a/src/dawn/tests/unittests/native/DeviceCreationTests.cpp b/src/dawn/tests/unittests/native/DeviceCreationTests.cpp
index 1c59873..cc62cd0 100644
--- a/src/dawn/tests/unittests/native/DeviceCreationTests.cpp
+++ b/src/dawn/tests/unittests/native/DeviceCreationTests.cpp
@@ -164,10 +164,15 @@
             wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
             EXPECT_NE(device, nullptr);
 
+            ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
+            wgpu::FeatureName enabledFeature;
+            device.EnumerateFeatures(&enabledFeature);
+            EXPECT_EQ(enabledFeature, featureName);
+
             wgpu::SupportedFeatures supportedFeatures;
             device.GetFeatures(&supportedFeatures);
             ASSERT_EQ(1u, supportedFeatures.featureCount);
-            EXPECT_EQ(featureName, supportedFeatures.features[0]);
+            EXPECT_EQ(enabledFeature, supportedFeatures.features[0]);
         }
 
         // Test creating device with AllowUnsafeApis enabled in device toggle descriptor will
@@ -184,10 +189,15 @@
                 wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
                 EXPECT_NE(device, nullptr);
 
+                ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
+                wgpu::FeatureName enabledFeature;
+                device.EnumerateFeatures(&enabledFeature);
+                EXPECT_EQ(enabledFeature, featureName);
+
                 wgpu::SupportedFeatures supportedFeatures;
                 device.GetFeatures(&supportedFeatures);
                 ASSERT_EQ(1u, supportedFeatures.featureCount);
-                EXPECT_EQ(featureName, supportedFeatures.features[0]);
+                EXPECT_EQ(enabledFeature, supportedFeatures.features[0]);
             }
 
             // Test on adapter with AllowUnsafeApis disabled.
@@ -195,10 +205,15 @@
                 wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
                 EXPECT_NE(device, nullptr);
 
+                ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
+                wgpu::FeatureName enabledFeature;
+                device.EnumerateFeatures(&enabledFeature);
+                EXPECT_EQ(enabledFeature, featureName);
+
                 wgpu::SupportedFeatures supportedFeatures;
                 device.GetFeatures(&supportedFeatures);
                 ASSERT_EQ(1u, supportedFeatures.featureCount);
-                EXPECT_EQ(featureName, supportedFeatures.features[0]);
+                EXPECT_EQ(enabledFeature, supportedFeatures.features[0]);
             }
         }
 
diff --git a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
index 3b59c80..9400eca 100644
--- a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
@@ -791,11 +791,9 @@
 
     std::vector<wgpu::FeatureName> GetAllFeatures() {
         std::vector<wgpu::FeatureName> requiredFeatures;
-        wgpu::SupportedFeatures supportedFeatures;
-        adapter.GetFeatures(&supportedFeatures);
-        for (uint32_t i = 0; i < supportedFeatures.featureCount; ++i) {
-            requiredFeatures.push_back(supportedFeatures.features[i]);
-        }
+        const size_t featureCount = adapter.EnumerateFeatures(nullptr);
+        requiredFeatures.resize(featureCount);
+        adapter.EnumerateFeatures(requiredFeatures.data());
         return requiredFeatures;
     }
 };
diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp
index 9dfa04b..2547eac 100644
--- a/src/dawn/wire/client/Adapter.cpp
+++ b/src/dawn/wire/client/Adapter.cpp
@@ -150,6 +150,10 @@
     return mLimitsAndFeatures.HasFeature(feature);
 }
 
+size_t Adapter::EnumerateFeatures(WGPUFeatureName* features) const {
+    return mLimitsAndFeatures.EnumerateFeatures(features);
+}
+
 void Adapter::GetFeatures(WGPUSupportedFeatures* features) const {
     mLimitsAndFeatures.ToSupportedFeatures(features);
 }
diff --git a/src/dawn/wire/client/Adapter.h b/src/dawn/wire/client/Adapter.h
index cfdebfd..c21d7f2 100644
--- a/src/dawn/wire/client/Adapter.h
+++ b/src/dawn/wire/client/Adapter.h
@@ -47,6 +47,7 @@
 
     WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
     bool HasFeature(WGPUFeatureName feature) const;
+    size_t EnumerateFeatures(WGPUFeatureName* features) const;
     void SetLimits(const WGPUSupportedLimits* limits);
     void SetFeatures(const WGPUFeatureName* features, uint32_t featuresCount);
     void SetInfo(const WGPUAdapterInfo* info);
diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp
index 3883cb2..ddf4bef 100644
--- a/src/dawn/wire/client/Device.cpp
+++ b/src/dawn/wire/client/Device.cpp
@@ -337,6 +337,10 @@
     return mLimitsAndFeatures.HasFeature(feature);
 }
 
+size_t Device::EnumerateFeatures(WGPUFeatureName* features) const {
+    return mLimitsAndFeatures.EnumerateFeatures(features);
+}
+
 void Device::GetFeatures(WGPUSupportedFeatures* features) const {
     mLimitsAndFeatures.ToSupportedFeatures(features);
 }
diff --git a/src/dawn/wire/client/Device.h b/src/dawn/wire/client/Device.h
index 15f0e03..edc7c68 100644
--- a/src/dawn/wire/client/Device.h
+++ b/src/dawn/wire/client/Device.h
@@ -97,6 +97,7 @@
 
     WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
     bool HasFeature(WGPUFeatureName feature) const;
+    size_t EnumerateFeatures(WGPUFeatureName* features) const;
     void GetFeatures(WGPUSupportedFeatures* features) const;
     WGPUStatus GetAdapterInfo(WGPUAdapterInfo* info) const;
     WGPUAdapter GetAdapter() const;
diff --git a/src/dawn/wire/client/LimitsAndFeatures.cpp b/src/dawn/wire/client/LimitsAndFeatures.cpp
index 790fb8c..803480a 100644
--- a/src/dawn/wire/client/LimitsAndFeatures.cpp
+++ b/src/dawn/wire/client/LimitsAndFeatures.cpp
@@ -74,6 +74,16 @@
     return mFeatures.contains(feature);
 }
 
+size_t LimitsAndFeatures::EnumerateFeatures(WGPUFeatureName* features) const {
+    if (features != nullptr) {
+        for (WGPUFeatureName f : mFeatures) {
+            *features = f;
+            ++features;
+        }
+    }
+    return mFeatures.size();
+}
+
 void LimitsAndFeatures::ToSupportedFeatures(WGPUSupportedFeatures* supportedFeatures) const {
     if (!supportedFeatures) {
         return;
diff --git a/src/dawn/wire/client/LimitsAndFeatures.h b/src/dawn/wire/client/LimitsAndFeatures.h
index 3034407..4c4933f 100644
--- a/src/dawn/wire/client/LimitsAndFeatures.h
+++ b/src/dawn/wire/client/LimitsAndFeatures.h
@@ -41,6 +41,7 @@
 
     WGPUStatus GetLimits(WGPUSupportedLimits* limits) const;
     bool HasFeature(WGPUFeatureName feature) const;
+    size_t EnumerateFeatures(WGPUFeatureName* features) const;
     void ToSupportedFeatures(WGPUSupportedFeatures* supportedFeatures) const;
 
     void SetLimits(const WGPUSupportedLimits* limits);
diff --git a/third_party/emdawnwebgpu/library_webgpu.js b/third_party/emdawnwebgpu/library_webgpu.js
index 8390709..e406c18 100644
--- a/third_party/emdawnwebgpu/library_webgpu.js
+++ b/third_party/emdawnwebgpu/library_webgpu.js
@@ -2484,7 +2484,7 @@
   // --------------------------------------------------------------------------
 };
 
-// Inverted index used by GetFeatures/HasFeature
+// Inverted index used by EnumerateFeatures/HasFeature
 LibraryWebGPU.$WebGPU.FeatureNameString2Enum = {};
 for (var value in LibraryWebGPU.$WebGPU.FeatureName) {
   LibraryWebGPU.$WebGPU.FeatureNameString2Enum[LibraryWebGPU.$WebGPU.FeatureName[value]] = value;