[dawn][wire] Use GetFeatures() instead of EnumerateFeatures()

This reverts commit 6366852ecf93927075e7cba01650678ab0e959ee.

Reason for revert: https://chromium-review.googlesource.com/c/chromium/src/+/6011908 has landed

Original change's description:
> Reland "Partial revert of webgpu.h: Add Adapter and Device GetFeatures() methods"
>
> This reverts commit df6873d0646714d9ff284848d84958e7412cd809.
>
> Reason for revert: flaky crashes on Chrome startup http://crbug.com/368672123#comment10
>
> Original change's description:
> > Revert "Partial revert of webgpu.h: Add Adapter and Device GetFeatures() methods"
> >
> > This reverts commit afd7389710ac47caed7cde667499877c6ccae327.
> >
> > Reason for revert: https://chromium-review.googlesource.com/c/chromium/src/+/5958567 has landed
> >
> > Original change's description:
> > > Partial revert of webgpu.h: Add Adapter and Device GetFeatures() methods
> > >
> > > Commit 78a100c8c999883350ea6e5a724119289d3ad45b changes
> > > dawn::wire::server to use GetFeatures to gather features instead of
> > > EnumerateFeatures. This breaks the filtering of features in Chromium's
> > > webgpu_cmd_decoder_impl.cc which proxies EnumerateFeatures but doesn't
> > > proxy GetFeatures yet. Before this code is relanded, Chromium must
> > > implement proxying of GetFeatures.
> > >
> > > Bug: 368672123
> > > Change-Id: I738d1d3f7b5342e73dfa59b63d42bb589c12ff41
> > > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/213674
> > > Commit-Queue: Corentin Wallez <cwallez@chromium.org>
> > > Reviewed-by: Kai Ninomiya <kainino@chromium.org>
> > > Commit-Queue: Kai Ninomiya <kainino@chromium.org>
> >
> > TBR=cwallez@chromium.org,kainino@chromium.org,dawn-scoped@luci-project-accounts.iam.gserviceaccount.com
> >
> > Change-Id: Ic659bcd271f3c95b578736d69cf5bdff10c40a18
> > No-Presubmit: true
> > No-Tree-Checks: true
> > No-Try: true
> > Bug: 368672123
> > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/213854
> > Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> > Commit-Queue: Fr <beaufort.francois@gmail.com>
> > Reviewed-by: Fr <beaufort.francois@gmail.com>
>
> # Not skipping CQ checks because this is a reland.
>
> Bug: 368672123
> Change-Id: If40cc5c979ded3c47d400b9991cc91c2bb5adf02
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/214114
> Auto-Submit: Yuly Novikov <ynovikov@chromium.org>
> Reviewed-by: Peter McNeeley <petermcneeley@google.com>
> Reviewed-by: dan sinclair <dsinclair@chromium.org>
> Commit-Queue: dan sinclair <dsinclair@chromium.org>

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 368672123
Change-Id: If8f5510762ff8356552d4727fd8bd21682e0668a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/214834
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
index b4b42bc..e242e5e 100644
--- a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
@@ -183,15 +183,17 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (wgpu::FeatureName feature : fakeFeatures) {
-                        *(features++) = static_cast<WGPUFeatureName>(feature);
+                        features[index++] = static_cast<WGPUFeatureName>(feature);
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
+                    return WGPUStatus_Success;
                 })));
 
             // The backend device should still not be known by the wire server since the
@@ -220,13 +222,13 @@
                           fakeLimits.limits.maxTextureDimension1D);
                 EXPECT_EQ(limits.limits.maxVertexAttributes, fakeLimits.limits.maxVertexAttributes);
 
-                std::vector<wgpu::FeatureName> features;
-                features.resize(device.EnumerateFeatures(nullptr));
-                ASSERT_EQ(features.size(), fakeFeatures.size());
-                EXPECT_EQ(device.EnumerateFeatures(&features[0]), features.size());
+                wgpu::SupportedFeatures supportedFeatures;
+                device.GetFeatures(&supportedFeatures);
+                ASSERT_EQ(supportedFeatures.featureCount, fakeFeatures.size());
 
                 std::unordered_set<wgpu::FeatureName> featureSet(fakeFeatures);
-                for (wgpu::FeatureName feature : features) {
+                for (uint32_t i = 0; i < supportedFeatures.featureCount; ++i) {
+                    wgpu::FeatureName feature = supportedFeatures.features[i];
                     EXPECT_EQ(featureSet.erase(feature), 1u);
                 }
             })));
@@ -265,15 +267,16 @@
     WGPUDevice apiDevice = api.GetNewDevice();
     EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
         .WillOnce(InvokeWithoutArgs([&] {
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (wgpu::FeatureName feature : fakeFeatures) {
-                        *(features++) = static_cast<WGPUFeatureName>(feature);
+                        features[index++] = static_cast<WGPUFeatureName>(feature);
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
                 })));
 
             // The device was actually created, but the wire didn't support its features.
@@ -349,15 +352,16 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (wgpu::FeatureName feature : fakeFeatures) {
-                        *(features++) = static_cast<WGPUFeatureName>(feature);
+                        features[index++] = static_cast<WGPUFeatureName>(feature);
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
                 })));
 
             api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
diff --git a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
index a2950f7..92a32de 100644
--- a/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireInstanceTests.cpp
@@ -161,15 +161,16 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (WGPUFeatureName feature : fakeFeatures) {
-                        *(features++) = feature;
+                        features[index++] = feature;
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
                 })));
             api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                    apiAdapter, kEmptyOutputStringView);
@@ -204,13 +205,13 @@
                           fakeLimits.limits.maxTextureDimension1D);
                 EXPECT_EQ(limits.limits.maxVertexAttributes, fakeLimits.limits.maxVertexAttributes);
 
-                std::vector<WGPUFeatureName> features;
-                features.resize(wgpuAdapterEnumerateFeatures(adapter, nullptr));
-                ASSERT_EQ(features.size(), fakeFeatures.size());
-                EXPECT_EQ(wgpuAdapterEnumerateFeatures(adapter, &features[0]), features.size());
+                WGPUSupportedFeatures supportedFeatures;
+                wgpuAdapterGetFeatures(adapter, &supportedFeatures);
+                ASSERT_EQ(supportedFeatures.featureCount, fakeFeatures.size());
 
                 std::unordered_set<WGPUFeatureName> featureSet(fakeFeatures);
-                for (WGPUFeatureName feature : features) {
+                for (uint32_t i = 0; i < supportedFeatures.featureCount; ++i) {
+                    WGPUFeatureName feature = supportedFeatures.features[i];
                     EXPECT_EQ(featureSet.erase(feature), 1u);
                 }
             })));
@@ -299,15 +300,16 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (WGPUFeatureName feature : fakeFeatures) {
-                        *(features++) = feature;
+                        features[index++] = feature;
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
                 })));
             api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                    apiAdapter, kEmptyOutputStringView);
@@ -396,15 +398,16 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
-                .WillOnce(Return(fakeFeatures.size()));
-
-            EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, NotNull()))
-                .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
+            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* supportedFeatures) {
+                    const size_t count = fakeFeatures.size();
+                    WGPUFeatureName* features = new WGPUFeatureName[count];
+                    uint32_t index = 0;
                     for (WGPUFeatureName feature : fakeFeatures) {
-                        *(features++) = feature;
+                        features[index++] = feature;
                     }
-                    return fakeFeatures.size();
+                    supportedFeatures->featureCount = count;
+                    supportedFeatures->features = features;
                 })));
             api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                    apiAdapter, kEmptyOutputStringView);
@@ -418,10 +421,10 @@
         EXPECT_CALL(mockCb,
                     Call(WGPURequestAdapterStatus_Success, NotNull(), EmptySizedString(), nullptr))
             .WillOnce(WithArg<1>(Invoke([&](WGPUAdapter adapter) {
-                WGPUFeatureName feature;
-                ASSERT_EQ(wgpuAdapterEnumerateFeatures(adapter, nullptr), 1u);
-                wgpuAdapterEnumerateFeatures(adapter, &feature);
-                EXPECT_EQ(feature, WGPUFeatureName_Depth32FloatStencil8);
+                WGPUSupportedFeatures supportedFeatures;
+                wgpuAdapterGetFeatures(adapter, &supportedFeatures);
+                EXPECT_EQ(supportedFeatures.featureCount, 1u);
+                EXPECT_EQ(supportedFeatures.features[0], WGPUFeatureName_Depth32FloatStencil8);
             })));
 
         FlushCallbacks();
diff --git a/src/dawn/tests/unittests/wire/WireTest.cpp b/src/dawn/tests/unittests/wire/WireTest.cpp
index 7aeba35..8d653bd 100644
--- a/src/dawn/tests/unittests/wire/WireTest.cpp
+++ b/src/dawn/tests/unittests/wire/WireTest.cpp
@@ -118,9 +118,11 @@
                 return WGPUStatus_Success;
             })));
 
-        EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
-            .WillOnce(Return(0))
-            .WillOnce(Return(0));
+        EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
+            .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* features) {
+                features->featureCount = 0;
+                return WGPUStatus_Success;
+            })));
 
         api.CallInstanceRequestAdapter2Callback(apiInstance, WGPURequestAdapterStatus_Success,
                                                 apiAdapter, kEmptyOutputStringView);
@@ -167,9 +169,11 @@
                     return WGPUStatus_Success;
                 })));
 
-            EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, nullptr))
-                .WillOnce(Return(0))
-                .WillOnce(Return(0));
+            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull()))
+                .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedFeatures* features) {
+                    features->featureCount = 0;
+                    return WGPUStatus_Success;
+                })));
 
             api.CallAdapterRequestDevice2Callback(apiAdapter, WGPURequestDeviceStatus_Success,
                                                   apiDevice, kEmptyOutputStringView);
diff --git a/src/dawn/wire/server/ServerAdapter.cpp b/src/dawn/wire/server/ServerAdapter.cpp
index 8d4c3c8..f8ffea5 100644
--- a/src/dawn/wire/server/ServerAdapter.cpp
+++ b/src/dawn/wire/server/ServerAdapter.cpp
@@ -97,17 +97,15 @@
         return;
     }
 
-    std::vector<WGPUFeatureName> features;
-
-    size_t featuresCount = mProcs.deviceEnumerateFeatures(device, nullptr);
-    features.resize(featuresCount);
-    mProcs.deviceEnumerateFeatures(device, features.data());
+    WGPUSupportedFeatures supportedFeatures;
+    mProcs.deviceGetFeatures(device, &supportedFeatures);
 
     // The client should only be able to request supported features, so all enumerated
     // features that were enabled must also be supported by the wire.
     // Note: We fail the callback here, instead of immediately upon receiving
     // the request to preserve callback ordering.
-    for (WGPUFeatureName f : features) {
+    for (uint32_t i = 0; i < supportedFeatures.featureCount; ++i) {
+        WGPUFeatureName f = supportedFeatures.features[i];
         if (!IsFeatureSupported(f)) {
             // Release the device.
             mProcs.deviceRelease(device);
@@ -116,12 +114,13 @@
             cmd.status = WGPURequestDeviceStatus_Error;
             cmd.message = ToOutputStringView("Requested feature not supported.");
             SerializeCommand(cmd);
+            mProcs.supportedFeaturesFreeMembers(supportedFeatures);
             return;
         }
     }
 
-    cmd.featuresCount = features.size();
-    cmd.features = features.data();
+    cmd.featuresCount = supportedFeatures.featureCount;
+    cmd.features = supportedFeatures.features;
 
     // Query and report the adapter limits, including DawnExperimentalSubgroupLimits and
     // DawnExperimentalImmediateDataLimits. Reporting to client.
@@ -146,6 +145,7 @@
         cmd.status = WGPURequestDeviceStatus_Unknown;
         cmd.message = ToOutputStringView("Destroyed before request was fulfilled.");
         SerializeCommand(cmd);
+        mProcs.supportedFeaturesFreeMembers(supportedFeatures);
         return;
     }
     DAWN_ASSERT(reservation.data != nullptr);
@@ -153,6 +153,7 @@
     reservation->info->self = reservation.AsHandle();
     SetForwardingDeviceCallbacks(reservation);
     SerializeCommand(cmd);
+    mProcs.supportedFeaturesFreeMembers(supportedFeatures);
 }
 
 }  // namespace dawn::wire::server
diff --git a/src/dawn/wire/server/ServerInstance.cpp b/src/dawn/wire/server/ServerInstance.cpp
index 4e1b883..02b998c 100644
--- a/src/dawn/wire/server/ServerInstance.cpp
+++ b/src/dawn/wire/server/ServerInstance.cpp
@@ -25,11 +25,7 @@
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <algorithm>
-#include <vector>
-
 #include "dawn/common/StringViewUtils.h"
-#include "dawn/wire/SupportedFeatures.h"
 #include "dawn/wire/server/ObjectStorage.h"
 #include "dawn/wire/server/Server.h"
 
@@ -87,17 +83,10 @@
     }
 
     // Query and report the adapter supported features.
-    std::vector<WGPUFeatureName> features;
-
-    size_t featuresCount = mProcs.adapterEnumerateFeatures(adapter, nullptr);
-    features.resize(featuresCount);
-    mProcs.adapterEnumerateFeatures(adapter, features.data());
-
-    // Hide features the wire cannot support.
-    auto it = std::partition(features.begin(), features.end(), IsFeatureSupported);
-
-    cmd.featuresCount = std::distance(features.begin(), it);
-    cmd.features = features.data();
+    WGPUSupportedFeatures supportedFeatures;
+    mProcs.adapterGetFeatures(adapter, &supportedFeatures);
+    cmd.featuresCount = supportedFeatures.featureCount;
+    cmd.features = supportedFeatures.features;
 
     // Query and report the adapter info.
     WGPUAdapterInfo info = {};
@@ -149,6 +138,7 @@
     SerializeCommand(cmd);
     mProcs.adapterInfoFreeMembers(info);
     mProcs.adapterPropertiesMemoryHeapsFreeMembers(memoryHeapProperties);
+    mProcs.supportedFeaturesFreeMembers(supportedFeatures);
 }
 
 }  // namespace dawn::wire::server