// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn_native/metal/BackendMTL.h"

#include "common/CoreFoundationRef.h"
#include "common/GPUInfo.h"
#include "common/NSRef.h"
#include "common/Platform.h"
#include "common/SystemUtils.h"
#include "dawn_native/Instance.h"
#include "dawn_native/MetalBackend.h"
#include "dawn_native/metal/BufferMTL.h"
#include "dawn_native/metal/DeviceMTL.h"

#if defined(DAWN_PLATFORM_MACOS)
#    import <IOKit/IOKitLib.h>
#    include "common/IOKitRef.h"
#endif

#include <vector>

namespace dawn_native::metal {

    namespace {

        struct PCIIDs {
            uint32_t vendorId;
            uint32_t deviceId;
        };

        struct Vendor {
            const char* trademark;
            uint32_t vendorId;
        };

#if defined(DAWN_PLATFORM_MACOS)
        const Vendor kVendors[] = {{"AMD", gpu_info::kVendorID_AMD},
                                   {"Radeon", gpu_info::kVendorID_AMD},
                                   {"Intel", gpu_info::kVendorID_Intel},
                                   {"Geforce", gpu_info::kVendorID_Nvidia},
                                   {"Quadro", gpu_info::kVendorID_Nvidia}};

        // Find vendor ID from MTLDevice name.
        MaybeError GetVendorIdFromVendors(id<MTLDevice> device, PCIIDs* ids) {
            uint32_t vendorId = 0;
            const char* deviceName = [device.name UTF8String];
            for (const auto& it : kVendors) {
                if (strstr(deviceName, it.trademark) != nullptr) {
                    vendorId = it.vendorId;
                    break;
                }
            }

            if (vendorId == 0) {
                return DAWN_INTERNAL_ERROR("Failed to find vendor id with the device");
            }

            // Set vendor id with 0
            *ids = PCIIDs{vendorId, 0};
            return {};
        }

        // Extracts an integer property from a registry entry.
        uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef name) {
            uint32_t value = 0;

            // Recursively search registry entry and its parents for property name
            // The data should release with CFRelease
            CFRef<CFDataRef> data =
                AcquireCFRef(static_cast<CFDataRef>(IORegistryEntrySearchCFProperty(
                    entry, kIOServicePlane, name, kCFAllocatorDefault,
                    kIORegistryIterateRecursively | kIORegistryIterateParents)));

            if (data == nullptr) {
                return value;
            }

            // CFDataGetBytePtr() is guaranteed to return a read-only pointer
            value = *reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(data.Get()));
            return value;
        }

        // Queries the IO Registry to find the PCI device and vendor IDs of the MTLDevice.
        // The registry entry correponding to [device registryID] doesn't contain the exact PCI ids
        // because it corresponds to a driver. However its parent entry corresponds to the device
        // itself and has uint32_t "device-id" and "registry-id" keys. For example on a dual-GPU
        // MacBook Pro 2017 the IORegistry explorer shows the following tree (simplified here):
        //
        //  - PCI0@0
        //  | - AppleACPIPCI
        //  | | - IGPU@2 (type IOPCIDevice)
        //  | | | - IntelAccelerator (type IOGraphicsAccelerator2)
        //  | | - PEG0@1
        //  | | | - IOPP
        //  | | | | - GFX0@0 (type IOPCIDevice)
        //  | | | | | - AMDRadeonX4000_AMDBaffinGraphicsAccelerator (type IOGraphicsAccelerator2)
        //
        // [device registryID] is the ID for one of the IOGraphicsAccelerator2 and we can see that
        // their parent always is an IOPCIDevice that has properties for the device and vendor IDs.
        MaybeError API_AVAILABLE(macos(10.13))
            GetDeviceIORegistryPCIInfo(id<MTLDevice> device, PCIIDs* ids) {
            // Get a matching dictionary for the IOGraphicsAccelerator2
            CFRef<CFMutableDictionaryRef> matchingDict =
                AcquireCFRef(IORegistryEntryIDMatching([device registryID]));
            if (matchingDict == nullptr) {
                return DAWN_INTERNAL_ERROR("Failed to create the matching dict for the device");
            }

            // IOServiceGetMatchingService will consume the reference on the matching dictionary,
            // so we don't need to release the dictionary.
            IORef<io_registry_entry_t> acceleratorEntry = AcquireIORef(
                IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict.Detach()));
            if (acceleratorEntry == IO_OBJECT_NULL) {
                return DAWN_INTERNAL_ERROR(
                    "Failed to get the IO registry entry for the accelerator");
            }

            // Get the parent entry that will be the IOPCIDevice
            IORef<io_registry_entry_t> deviceEntry;
            if (IORegistryEntryGetParentEntry(acceleratorEntry.Get(), kIOServicePlane,
                                              deviceEntry.InitializeInto()) != kIOReturnSuccess) {
                return DAWN_INTERNAL_ERROR("Failed to get the IO registry entry for the device");
            }

            ASSERT(deviceEntry != IO_OBJECT_NULL);

            uint32_t vendorId = GetEntryProperty(deviceEntry.Get(), CFSTR("vendor-id"));
            uint32_t deviceId = GetEntryProperty(deviceEntry.Get(), CFSTR("device-id"));

            *ids = PCIIDs{vendorId, deviceId};

            return {};
        }

        MaybeError GetDevicePCIInfo(id<MTLDevice> device, PCIIDs* ids) {
            // [device registryID] is introduced on macOS 10.13+, otherwise workaround to get vendor
            // id by vendor name on old macOS
            if (@available(macos 10.13, *)) {
                return GetDeviceIORegistryPCIInfo(device, ids);
            } else {
                return GetVendorIdFromVendors(device, ids);
            }
        }

        bool IsMetalSupported() {
            // Metal was first introduced in macOS 10.11
            // WebGPU is targeted at macOS 10.12+
            // TODO(dawn:1181): Dawn native should allow non-conformant WebGPU on macOS 10.11
            return IsMacOSVersionAtLeast(10, 12);
        }
#elif defined(DAWN_PLATFORM_IOS)
        MaybeError GetDevicePCIInfo(id<MTLDevice> device, PCIIDs* ids) {
            DAWN_UNUSED(device);
            *ids = PCIIDs{0, 0};
            return {};
        }

        bool IsMetalSupported() {
            return true;
        }
#else
#    error "Unsupported Apple platform."
#endif

        DAWN_NOINLINE bool IsCounterSamplingBoundarySupport(id<MTLDevice> device)
            API_AVAILABLE(macos(11.0), ios(14.0)) {
            bool isBlitBoundarySupported =
                [device supportsCounterSampling:MTLCounterSamplingPointAtBlitBoundary];
            bool isDispatchBoundarySupported =
                [device supportsCounterSampling:MTLCounterSamplingPointAtDispatchBoundary];
            bool isDrawBoundarySupported =
                [device supportsCounterSampling:MTLCounterSamplingPointAtDrawBoundary];

            return isBlitBoundarySupported && isDispatchBoundarySupported &&
                   isDrawBoundarySupported;
        }

        DAWN_NOINLINE bool IsGPUCounterSupported(id<MTLDevice> device,
                                                 MTLCommonCounterSet counterSetName,
                                                 std::vector<MTLCommonCounter> counterNames)
            API_AVAILABLE(macos(10.15), ios(14.0)) {
            // MTLDevice’s counterSets property declares which counter sets it supports. Check
            // whether it's available on the device before requesting a counter set.
            id<MTLCounterSet> counterSet = nil;
            for (id<MTLCounterSet> set in [device counterSets]) {
                if ([set.name caseInsensitiveCompare:counterSetName] == NSOrderedSame) {
                    counterSet = set;
                    break;
                }
            }

            // The counter set is not supported.
            if (counterSet == nil) {
                return false;
            }

            // A GPU might support a counter set, but only support a subset of the counters in that
            // set, check if the counter set supports all specific counters we need. Return false
            // if there is a counter unsupported.
            for (MTLCommonCounter counterName : counterNames) {
                bool found = false;
                for (id<MTLCounter> counter in [counterSet counters]) {
                    if ([counter.name caseInsensitiveCompare:counterName] == NSOrderedSame) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    return false;
                }
            }

            if (@available(macOS 11.0, iOS 14.0, *)) {
                // Check whether it can read GPU counters at the specified command boundary. Apple
                // family GPUs do not support sampling between different Metal commands, because
                // they defer fragment processing until after the GPU processes all the primitives
                // in the render pass.
                if (!IsCounterSamplingBoundarySupport(device)) {
                    return false;
                }
            }

            return true;
        }

    }  // anonymous namespace

    // The Metal backend's Adapter.

    class Adapter : public AdapterBase {
      public:
        Adapter(InstanceBase* instance, id<MTLDevice> device)
            : AdapterBase(instance, wgpu::BackendType::Metal), mDevice(device) {
            mName = std::string([[*mDevice name] UTF8String]);

            PCIIDs ids;
            if (!instance->ConsumedError(GetDevicePCIInfo(device, &ids))) {
                mVendorId = ids.vendorId;
                mDeviceId = ids.deviceId;
            }

#if defined(DAWN_PLATFORM_IOS)
            mAdapterType = wgpu::AdapterType::IntegratedGPU;
            const char* systemName = "iOS ";
#elif defined(DAWN_PLATFORM_MACOS)
            if ([device isLowPower]) {
                mAdapterType = wgpu::AdapterType::IntegratedGPU;
            } else {
                mAdapterType = wgpu::AdapterType::DiscreteGPU;
            }
            const char* systemName = "macOS ";
#else
#    error "Unsupported Apple platform."
#endif

            NSString* osVersion = [[NSProcessInfo processInfo] operatingSystemVersionString];
            mDriverDescription =
                "Metal driver on " + std::string(systemName) + [osVersion UTF8String];
        }

        // AdapterBase Implementation
        bool SupportsExternalImages() const override {
            // Via dawn_native::metal::WrapIOSurface
            return true;
        }

      private:
        ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
            const DeviceDescriptor* descriptor) override {
            return Device::Create(this, mDevice, descriptor);
        }

        MaybeError InitializeImpl() override {
            return {};
        }

        MaybeError InitializeSupportedFeaturesImpl() override {
#if defined(DAWN_PLATFORM_MACOS)
            if ([*mDevice supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1]) {
                mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
            }
#endif

            if (@available(macOS 10.15, iOS 14.0, *)) {
                if (IsGPUCounterSupported(
                        *mDevice, MTLCommonCounterSetStatistic,
                        {MTLCommonCounterVertexInvocations, MTLCommonCounterClipperInvocations,
                         MTLCommonCounterClipperPrimitivesOut, MTLCommonCounterFragmentInvocations,
                         MTLCommonCounterComputeKernelInvocations})) {
                    mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
                }

                if (IsGPUCounterSupported(*mDevice, MTLCommonCounterSetTimestamp,
                                          {MTLCommonCounterTimestamp})) {
                    bool enableTimestampQuery = true;

#if defined(DAWN_PLATFORM_MACOS)
                    // Disable timestamp query on macOS 10.15 on AMD GPU because WriteTimestamp
                    // fails to call without any copy commands on MTLBlitCommandEncoder. This issue
                    // has been fixed on macOS 11.0. See crbug.com/dawn/545
                    enableTimestampQuery &=
                        !(gpu_info::IsAMD(mVendorId) && IsMacOSVersionAtLeast(11));
#endif

                    if (enableTimestampQuery) {
                        mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
                    }
                }
            }

            if (@available(macOS 10.11, iOS 11.0, *)) {
                mSupportedFeatures.EnableFeature(Feature::DepthClamping);
            }

            if (@available(macOS 10.11, iOS 9.0, *)) {
                mSupportedFeatures.EnableFeature(Feature::Depth32FloatStencil8);
            }

#if defined(DAWN_PLATFORM_MACOS)
            // MTLPixelFormatDepth24Unorm_Stencil8 is only available on macOS 10.11+
            if ([*mDevice isDepth24Stencil8PixelFormatSupported]) {
                mSupportedFeatures.EnableFeature(Feature::Depth24UnormStencil8);
            }
#endif

            return {};
        }

        enum class MTLGPUFamily {
            Apple1,
            Apple2,
            Apple3,
            Apple4,
            Apple5,
            Apple6,
            Apple7,
            Mac1,
            Mac2,
        };

        ResultOrError<MTLGPUFamily> GetMTLGPUFamily() const {
            // https://developer.apple.com/documentation/metal/mtldevice/detecting_gpu_features_and_metal_software_versions?language=objc

            if (@available(macOS 10.15, iOS 10.13, *)) {
                if ([*mDevice supportsFamily:MTLGPUFamilyMac2]) {
                    return MTLGPUFamily::Mac2;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyMac1]) {
                    return MTLGPUFamily::Mac1;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple7]) {
                    return MTLGPUFamily::Apple7;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple6]) {
                    return MTLGPUFamily::Apple6;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple5]) {
                    return MTLGPUFamily::Apple5;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple4]) {
                    return MTLGPUFamily::Apple4;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple3]) {
                    return MTLGPUFamily::Apple3;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple2]) {
                    return MTLGPUFamily::Apple2;
                }
                if ([*mDevice supportsFamily:MTLGPUFamilyApple1]) {
                    return MTLGPUFamily::Apple1;
                }
            }

#if TARGET_OS_OSX
            if (@available(macOS 10.14, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1]) {
                    return MTLGPUFamily::Mac2;
                }
            }
            if (@available(macOS 10.11, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1]) {
                    return MTLGPUFamily::Mac1;
                }
            }
#elif TARGET_OS_IOS
            if (@available(iOS 10.11, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]) {
                    return MTLGPUFamily::Apple4;
                }
            }
            if (@available(iOS 9.0, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
                    return MTLGPUFamily::Apple3;
                }
            }
            if (@available(iOS 8.0, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]) {
                    return MTLGPUFamily::Apple2;
                }
            }
            if (@available(iOS 8.0, *)) {
                if ([*mDevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v1]) {
                    return MTLGPUFamily::Apple1;
                }
            }
#endif
            return DAWN_INTERNAL_ERROR("Unsupported Metal device");
        }

        MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override {
            struct MTLDeviceLimits {
                uint32_t maxVertexAttribsPerDescriptor;
                uint32_t maxBufferArgumentEntriesPerFunc;
                uint32_t maxTextureArgumentEntriesPerFunc;
                uint32_t maxSamplerStateArgumentEntriesPerFunc;
                uint32_t maxThreadsPerThreadgroup;
                uint32_t maxTotalThreadgroupMemory;
                uint32_t maxFragmentInputComponents;
                uint32_t max1DTextureSize;
                uint32_t max2DTextureSize;
                uint32_t max3DTextureSize;
                uint32_t maxTextureArrayLayers;
                uint32_t minBufferOffsetAlignment;
            };

            struct LimitsForFamily {
                uint32_t MTLDeviceLimits::*limit;
                ityp::array<MTLGPUFamily, uint32_t, 9> values;
            };

            // clang-format off
            // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
            //                                                               Apple                                                      Mac
            //                                                                   1,      2,      3,      4,      5,      6,      7,       1,      2
            constexpr LimitsForFamily kMTLLimits[12] = {
                {&MTLDeviceLimits::maxVertexAttribsPerDescriptor,         {    31u,    31u,    31u,    31u,    31u,    31u,    31u,     31u,    31u }},
                {&MTLDeviceLimits::maxBufferArgumentEntriesPerFunc,       {    31u,    31u,    31u,    31u,    31u,    31u,    31u,     31u,    31u }},
                {&MTLDeviceLimits::maxTextureArgumentEntriesPerFunc,      {    31u,    31u,    31u,    96u,    96u,   128u,   128u,    128u,   128u }},
                {&MTLDeviceLimits::maxSamplerStateArgumentEntriesPerFunc, {    16u,    16u,    16u,    16u,    16u,    16u,    16u,     16u,    16u }},
                {&MTLDeviceLimits::maxThreadsPerThreadgroup,              {   512u,   512u,   512u,  1024u,  1024u,  1024u,  1024u,   1024u,  1024u }},
                {&MTLDeviceLimits::maxTotalThreadgroupMemory,             { 16352u, 16352u, 16384u, 32768u, 32768u, 32768u, 32768u,  32768u, 32768u }},
                {&MTLDeviceLimits::maxFragmentInputComponents,            {    60u,    60u,    60u,   124u,   124u,   124u,   124u,    124u,   124u }},
                {&MTLDeviceLimits::max1DTextureSize,                      {  8192u,  8192u, 16384u, 16384u, 16384u, 16384u, 16384u,  16384u, 16384u }},
                {&MTLDeviceLimits::max2DTextureSize,                      {  8192u,  8192u, 16384u, 16384u, 16384u, 16384u, 16384u,  16384u, 16384u }},
                {&MTLDeviceLimits::max3DTextureSize,                      {  2048u,  2048u,  2048u,  2048u,  2048u,  2048u,  2048u,   2048u,  2048u }},
                {&MTLDeviceLimits::maxTextureArrayLayers,                 {  2048u,  2048u,  2048u,  2048u,  2048u,  2048u,  2048u,   2048u,  2048u }},
                {&MTLDeviceLimits::minBufferOffsetAlignment,              {     4u,     4u,     4u,     4u,     4u,     4u,     4u,    256u,   256u }},
            };
            // clang-format on

            MTLGPUFamily mtlGPUFamily;
            DAWN_TRY_ASSIGN(mtlGPUFamily, GetMTLGPUFamily());

            MTLDeviceLimits mtlLimits;
            for (const auto& limitsForFamily : kMTLLimits) {
                mtlLimits.*limitsForFamily.limit = limitsForFamily.values[mtlGPUFamily];
            }

            GetDefaultLimits(&limits->v1);

            limits->v1.maxTextureDimension1D = mtlLimits.max1DTextureSize;
            limits->v1.maxTextureDimension2D = mtlLimits.max2DTextureSize;
            limits->v1.maxTextureDimension3D = mtlLimits.max3DTextureSize;
            limits->v1.maxTextureArrayLayers = mtlLimits.maxTextureArrayLayers;

            uint32_t maxBuffersPerStage = mtlLimits.maxBufferArgumentEntriesPerFunc;
            maxBuffersPerStage -= 1;  // One slot is reserved to store buffer lengths.

            uint32_t baseMaxBuffersPerStage = limits->v1.maxStorageBuffersPerShaderStage +
                                              limits->v1.maxUniformBuffersPerShaderStage +
                                              limits->v1.maxVertexBuffers;

            ASSERT(maxBuffersPerStage >= baseMaxBuffersPerStage);
            {
                uint32_t additional = maxBuffersPerStage - baseMaxBuffersPerStage;
                limits->v1.maxStorageBuffersPerShaderStage += additional / 3;
                limits->v1.maxUniformBuffersPerShaderStage += additional / 3;
                limits->v1.maxVertexBuffers += (additional - 2 * (additional / 3));
            }

            uint32_t baseMaxTexturesPerStage = limits->v1.maxSampledTexturesPerShaderStage +
                                               limits->v1.maxStorageTexturesPerShaderStage;

            ASSERT(mtlLimits.maxTextureArgumentEntriesPerFunc >= baseMaxTexturesPerStage);
            {
                uint32_t additional =
                    mtlLimits.maxTextureArgumentEntriesPerFunc - baseMaxTexturesPerStage;
                limits->v1.maxSampledTexturesPerShaderStage += additional / 2;
                limits->v1.maxStorageTexturesPerShaderStage += (additional - additional / 2);
            }

            limits->v1.maxSamplersPerShaderStage = mtlLimits.maxSamplerStateArgumentEntriesPerFunc;

            // Metal limits are per-function, so the layout limits are the same as the stage
            // limits. Note: this should likely change if the implementation uses Metal argument
            // buffers. Non-dynamic buffers will probably be bound argument buffers, but dynamic
            // buffers may be set directly.
            //   Mac GPU families with tier 1 argument buffers support 64
            //   buffers, 128 textures, and 16 samplers. Mac GPU families
            //   with tier 2 argument buffers support 500000 buffers and
            //   textures, and 1024 unique samplers
            limits->v1.maxDynamicUniformBuffersPerPipelineLayout =
                limits->v1.maxUniformBuffersPerShaderStage;
            limits->v1.maxDynamicStorageBuffersPerPipelineLayout =
                limits->v1.maxStorageBuffersPerShaderStage;

            // The WebGPU limit is the limit across all vertex buffers, combined.
            limits->v1.maxVertexAttributes =
                limits->v1.maxVertexBuffers * mtlLimits.maxVertexAttribsPerDescriptor;

            limits->v1.maxInterStageShaderComponents = mtlLimits.maxFragmentInputComponents;

            limits->v1.maxComputeWorkgroupStorageSize = mtlLimits.maxTotalThreadgroupMemory;
            limits->v1.maxComputeInvocationsPerWorkgroup = mtlLimits.maxThreadsPerThreadgroup;
            limits->v1.maxComputeWorkgroupSizeX = mtlLimits.maxThreadsPerThreadgroup;
            limits->v1.maxComputeWorkgroupSizeY = mtlLimits.maxThreadsPerThreadgroup;
            limits->v1.maxComputeWorkgroupSizeZ = mtlLimits.maxThreadsPerThreadgroup;

            limits->v1.minUniformBufferOffsetAlignment = mtlLimits.minBufferOffsetAlignment;
            limits->v1.minStorageBufferOffsetAlignment = mtlLimits.minBufferOffsetAlignment;

            uint64_t maxBufferSize = Buffer::QueryMaxBufferLength(*mDevice);

            // Metal has no documented limit on the size of a binding. Use the maximum
            // buffer size.
            limits->v1.maxUniformBufferBindingSize = maxBufferSize;
            limits->v1.maxStorageBufferBindingSize = maxBufferSize;

            // TODO(crbug.com/dawn/685):
            // LIMITS NOT SET:
            // - maxBindGroups
            // - maxVertexBufferArrayStride

            return {};
        }

        NSPRef<id<MTLDevice>> mDevice;
    };

    // Implementation of the Metal backend's BackendConnection

    Backend::Backend(InstanceBase* instance)
        : BackendConnection(instance, wgpu::BackendType::Metal) {
        if (GetInstance()->IsBackendValidationEnabled()) {
            setenv("METAL_DEVICE_WRAPPER_TYPE", "1", 1);
        }
    }

    std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
        AdapterDiscoveryOptions options;
        auto result = DiscoverAdapters(&options);
        if (result.IsError()) {
            GetInstance()->ConsumedError(result.AcquireError());
            return {};
        }
        return result.AcquireSuccess();
    }

    ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
        const AdapterDiscoveryOptionsBase* optionsBase) {
        ASSERT(optionsBase->backendType == WGPUBackendType_Metal);

        std::vector<std::unique_ptr<AdapterBase>> adapters;
        BOOL supportedVersion = NO;
#if defined(DAWN_PLATFORM_MACOS)
        if (@available(macOS 10.11, *)) {
            supportedVersion = YES;

            NSRef<NSArray<id<MTLDevice>>> devices = AcquireNSRef(MTLCopyAllDevices());

            for (id<MTLDevice> device in devices.Get()) {
                std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(GetInstance(), device);
                if (!GetInstance()->ConsumedError(adapter->Initialize())) {
                    adapters.push_back(std::move(adapter));
                }
            }
        }
#endif

#if defined(DAWN_PLATFORM_IOS)
        if (@available(iOS 8.0, *)) {
            supportedVersion = YES;
            // iOS only has a single device so MTLCopyAllDevices doesn't exist there.
            std::unique_ptr<Adapter> adapter =
                std::make_unique<Adapter>(GetInstance(), MTLCreateSystemDefaultDevice());
            if (!GetInstance()->ConsumedError(adapter->Initialize())) {
                adapters.push_back(std::move(adapter));
            }
        }
#endif
        if (!supportedVersion) {
            UNREACHABLE();
        }
        return adapters;
    }

    BackendConnection* Connect(InstanceBase* instance) {
        if (!IsMetalSupported()) {
            return nullptr;
        }
        return new Backend(instance);
    }

}  // namespace dawn_native::metal
