// 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 { namespace 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

        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;
        }

        bool IsGPUCounterSupported(id<MTLDevice> device,
                                   MTLCommonCounterSet counterSetName,
                                   std::vector<MTLCommonCounter> counters)
            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;
            if (device.counterSets != 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.
            std::vector<NSString*> supportedCounters;
            for (id<MTLCounter> counter in counterSet.counters) {
                supportedCounters.push_back(counter.name);
            }
            for (const auto& counterName : counters) {
                if (std::find(supportedCounters.begin(), supportedCounters.end(), counterName) ==
                    supportedCounters.end()) {
                    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) {
            mPCIInfo.name = std::string([[*mDevice name] UTF8String]);

            PCIIDs ids;
            if (!instance->ConsumedError(GetDevicePCIInfo(device, &ids))) {
                mPCIInfo.vendorId = ids.vendorId;
                mPCIInfo.deviceId = 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<DeviceBase*> CreateDeviceImpl(
            const DawnDeviceDescriptor* 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(GetPCIInfo().vendorId) && IsMacOSVersionAtLeast(11));
#endif

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

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

            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() {
        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
