/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "experimental/graphite/src/mtl/MtlCaps.h" #include "experimental/graphite/include/TextureInfo.h" #include "experimental/graphite/include/mtl/MtlTypes.h" #include "experimental/graphite/src/mtl/MtlUtils.h" namespace skgpu::mtl { Caps::Caps(const id device) : skgpu::Caps() { // TODO: allocate shadercaps this->initGPUFamily(device); this->initCaps(device); this->initShaderCaps(); this->initFormatTable(); // Metal-specific caps } // translates from older MTLFeatureSet interface to MTLGPUFamily interface bool Caps::GetGPUFamilyFromFeatureSet(id device, GPUFamily* gpuFamily, int* group) { #if defined(SK_BUILD_FOR_MAC) // Apple Silicon is only available in later OSes *gpuFamily = GPUFamily::kMac; // Mac OSX 14 if (@available(macOS 10.14, *)) { if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1]) { *group = 2; return true; } if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v4]) { *group = 1; return true; } } // Mac OSX 13 if (@available(macOS 10.13, *)) { if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v3]) { *group = 1; return true; } } // Mac OSX 12 if (@available(macOS 10.12, *)) { if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v2]) { *group = 1; return true; } } // Mac OSX 11 if (@available(macOS 10.11, *)) { if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1]) { *group = 1; return true; } } #elif defined(SK_BUILD_FOR_IOS) // TODO: support tvOS *gpuFamily = GPUFamily::kApple; // iOS 12 if (@available(iOS 12.0, *)) { if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily5_v1]) { *group = 5; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v2]) { *group = 4; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v4]) { *group = 3; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v5]) { *group = 2; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v5]) { *group = 1; return true; } } // iOS 11 if (@available(iOS 11.0, *)) { if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]) { *group = 4; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v3]) { *group = 3; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v4]) { *group = 2; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v4]) { *group = 1; return true; } } // iOS 10 if (@available(iOS 10.0, *)) { if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2]) { *group = 3; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v3]) { *group = 2; return true; } if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v3]) { *group = 1; return true; } } // We don't support earlier OSes #endif // No supported GPU families were found return false; } bool Caps::GetGPUFamily(id device, GPUFamily* gpuFamily, int* group) { #if GR_METAL_SDK_VERSION >= 220 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { // Apple Silicon #if GR_METAL_SDK_VERSION >= 230 if ([device supportsFamily:MTLGPUFamilyApple7]) { *gpuFamily = GPUFamily::kApple; *group = 7; return true; } #endif #ifdef SK_BUILD_FOR_IOS if ([device supportsFamily:MTLGPUFamilyApple6]) { *gpuFamily = GPUFamily::kApple; *group = 6; return true; } if ([device supportsFamily:MTLGPUFamilyApple5]) { *gpuFamily = GPUFamily::kApple; *group = 5; return true; } if ([device supportsFamily:MTLGPUFamilyApple4]) { *gpuFamily = GPUFamily::kApple; *group = 4; return true; } if ([device supportsFamily:MTLGPUFamilyApple3]) { *gpuFamily = GPUFamily::kApple; *group = 3; return true; } if ([device supportsFamily:MTLGPUFamilyApple2]) { *gpuFamily = GPUFamily::kApple; *group = 2; return true; } if ([device supportsFamily:MTLGPUFamilyApple1]) { *gpuFamily = GPUFamily::kApple; *group = 1; return true; } #endif // Older Macs // At the moment MacCatalyst families have the same features as Mac, // so we treat them the same if ([device supportsFamily:MTLGPUFamilyMac2] || [device supportsFamily:MTLGPUFamilyMacCatalyst2]) { *gpuFamily = GPUFamily::kMac; *group = 2; return true; } if ([device supportsFamily:MTLGPUFamilyMac1] || [device supportsFamily:MTLGPUFamilyMacCatalyst1]) { *gpuFamily = GPUFamily::kMac; *group = 1; return true; } } #endif // No supported GPU families were found return false; } void Caps::initGPUFamily(id device) { if (!GetGPUFamily(device, &fGPUFamily, &fFamilyGroup) && !GetGPUFamilyFromFeatureSet(device, &fGPUFamily, &fFamilyGroup)) { // We don't know what this is, fall back to minimum defaults #ifdef SK_BUILD_FOR_MAC fGPUFamily = GPUFamily::kMac; fFamilyGroup = 1; #else fGPUFamily = GPUFamily::kApple; fFamilyGroup = 1; #endif } } void Caps::initCaps(const id device) { // TODO } void Caps::initShaderCaps() { // TODO } void Caps::initFormatTable() { // TODO } skgpu::TextureInfo Caps::getDefaultSampledTextureInfo(SkColorType colorType, uint32_t levelCount, Protected, Renderable renderable) const { MTLTextureUsage usage = MTLTextureUsageShaderRead; if (renderable == Renderable::kYes) { usage |= MTLTextureUsageRenderTarget; } TextureInfo info; info.fSampleCount = 1; info.fLevelCount = levelCount; info.fFormat = SkColorTypeToFormat(colorType); info.fUsage = usage; info.fStorageMode = MTLStorageModePrivate; info.fFramebufferOnly = false; return info; } skgpu::TextureInfo Caps::getDefaultMSAATextureInfo(SkColorType colorType, uint32_t sampleCount, Protected) const { MTLTextureUsage usage = MTLTextureUsageRenderTarget; TextureInfo info; info.fSampleCount = sampleCount; info.fLevelCount = 1; info.fFormat = SkColorTypeToFormat(colorType); info.fUsage = usage; info.fStorageMode = MTLStorageModePrivate; info.fFramebufferOnly = false; return info; } skgpu::TextureInfo Caps::getDefaultDepthStencilTextureInfo(DepthStencilType depthStencilType, uint32_t sampleCount, Protected) const { TextureInfo info; info.fSampleCount = sampleCount; info.fLevelCount = 1; info.fFormat = DepthStencilTypeToFormat(depthStencilType); info.fUsage = MTLTextureUsageRenderTarget; info.fStorageMode = MTLStorageModePrivate; info.fFramebufferOnly = false; return info; } } // namespace skgpu::mtl