Support CPU adapters in dawn_end2end_tests

This is so we can run the end2end_tests using Swiftshader. We still
prefer the discrete, then integrated GPUs so that normal testing uses
the real GPU.

Bug: dawn:283
Change-Id: I17a1ffd8aa88ddeaafa019feb67deeb25cdd2da0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16220
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Mark Henderson <mehe@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp
index 47bcfb9..2837406 100644
--- a/src/tests/DawnTest.cpp
+++ b/src/tests/DawnTest.cpp
@@ -560,36 +560,61 @@
         dawn_native::Instance* instance = gTestEnv->GetInstance();
         std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
 
-        for (const dawn_native::Adapter& adapter : adapters) {
+        static constexpr size_t kInvalidIndex = std::numeric_limits<size_t>::max();
+        size_t discreteAdapterIndex = kInvalidIndex;
+        size_t integratedAdapterIndex = kInvalidIndex;
+        size_t cpuAdapterIndex = kInvalidIndex;
+        size_t unknownAdapterIndex = kInvalidIndex;
+
+        for (size_t i = 0; i < adapters.size(); ++i) {
+            const dawn_native::Adapter& adapter = adapters[i];
+
             wgpu::AdapterProperties properties;
             adapter.GetProperties(&properties);
 
             if (properties.backendType == backendType) {
-                if (properties.adapterType == wgpu::AdapterType::CPU) {
+                // If the vendor id doesn't match, skip this adapter.
+                if (HasVendorIdFilter() && properties.vendorID != GetVendorIdFilter()) {
                     continue;
                 }
 
-                // Filter adapter by vendor id
-                if (HasVendorIdFilter()) {
-                    if (properties.vendorID == GetVendorIdFilter()) {
-                        mBackendAdapter = adapter;
+                // Find the index of each type of adapter.
+                switch (adapter.GetDeviceType()) {
+                    case dawn_native::DeviceType::DiscreteGPU:
+                        discreteAdapterIndex = i;
                         break;
-                    }
-                    continue;
-                }
-
-                // Prefer discrete GPU on multi-GPU systems, otherwise get integrated GPU.
-                mBackendAdapter = adapter;
-                mAdapterProperties = properties;
-                if (properties.adapterType == wgpu::AdapterType::DiscreteGPU) {
-                    break;
+                    case dawn_native::DeviceType::IntegratedGPU:
+                        integratedAdapterIndex = i;
+                        break;
+                    case dawn_native::DeviceType::CPU:
+                        cpuAdapterIndex = i;
+                        break;
+                    case dawn_native::DeviceType::Unknown:
+                        unknownAdapterIndex = i;
+                        break;
+                    default:
+                        UNREACHABLE();
+                        break;
                 }
             }
         }
 
+        // Prefer, discrete, then integrated, then CPU, then unknown adapters.
+        if (discreteAdapterIndex != kInvalidIndex) {
+            mBackendAdapter = adapters[discreteAdapterIndex];
+        } else if (integratedAdapterIndex != kInvalidIndex) {
+            mBackendAdapter = adapters[integratedAdapterIndex];
+        } else if (cpuAdapterIndex != kInvalidIndex) {
+            mBackendAdapter = adapters[cpuAdapterIndex];
+        } else if (unknownAdapterIndex != kInvalidIndex) {
+            mBackendAdapter = adapters[unknownAdapterIndex];
+        }
+
         if (!mBackendAdapter) {
             return;
         }
+
+        mBackendAdapter.GetProperties(&mAdapterProperties);
     }
 
     for (const char* forceEnabledWorkaround : mParam.forceEnabledWorkarounds) {