// 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 "dawn/common/CoreFoundationRef.h"
#include "dawn/common/GPUInfo.h"
#include "dawn/common/NSRef.h"
#include "dawn/common/Platform.h"
#include "dawn/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 "dawn/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 11.0 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.
                    if (gpu_info::IsAMD(mVendorId) && !IsMacOSVersionAtLeast(11)) {
                        enableTimestampQuery = false;
                    }
#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<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
        AdapterDiscoveryOptions options;
        auto result = DiscoverAdapters(&options);
        if (result.IsError()) {
            GetInstance()->ConsumedError(result.AcquireError());
            return {};
        }
        return result.AcquireSuccess();
    }

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

        std::vector<Ref<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()) {
                Ref<Adapter> adapter = AcquireRef(new 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.
            Ref<Adapter> adapter =
                AcquireRef(new 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
