1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "experimental/graphite/src/mtl/MtlCaps.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "experimental/graphite/include/TextureInfo.h" 11cb93a386Sopenharmony_ci#include "experimental/graphite/include/mtl/MtlTypes.h" 12cb93a386Sopenharmony_ci#include "experimental/graphite/src/mtl/MtlUtils.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cinamespace skgpu::mtl { 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciCaps::Caps(const id<MTLDevice> device) 17cb93a386Sopenharmony_ci : skgpu::Caps() { 18cb93a386Sopenharmony_ci // TODO: allocate shadercaps 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci this->initGPUFamily(device); 21cb93a386Sopenharmony_ci this->initCaps(device); 22cb93a386Sopenharmony_ci this->initShaderCaps(); 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci this->initFormatTable(); 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci // Metal-specific caps 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci// translates from older MTLFeatureSet interface to MTLGPUFamily interface 30cb93a386Sopenharmony_cibool Caps::GetGPUFamilyFromFeatureSet(id<MTLDevice> device, GPUFamily* gpuFamily, int* group) { 31cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_MAC) 32cb93a386Sopenharmony_ci // Apple Silicon is only available in later OSes 33cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kMac; 34cb93a386Sopenharmony_ci // Mac OSX 14 35cb93a386Sopenharmony_ci if (@available(macOS 10.14, *)) { 36cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1]) { 37cb93a386Sopenharmony_ci *group = 2; 38cb93a386Sopenharmony_ci return true; 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v4]) { 41cb93a386Sopenharmony_ci *group = 1; 42cb93a386Sopenharmony_ci return true; 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci // Mac OSX 13 46cb93a386Sopenharmony_ci if (@available(macOS 10.13, *)) { 47cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v3]) { 48cb93a386Sopenharmony_ci *group = 1; 49cb93a386Sopenharmony_ci return true; 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci // Mac OSX 12 53cb93a386Sopenharmony_ci if (@available(macOS 10.12, *)) { 54cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v2]) { 55cb93a386Sopenharmony_ci *group = 1; 56cb93a386Sopenharmony_ci return true; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci // Mac OSX 11 60cb93a386Sopenharmony_ci if (@available(macOS 10.11, *)) { 61cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1]) { 62cb93a386Sopenharmony_ci *group = 1; 63cb93a386Sopenharmony_ci return true; 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci#elif defined(SK_BUILD_FOR_IOS) 67cb93a386Sopenharmony_ci // TODO: support tvOS 68cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 69cb93a386Sopenharmony_ci // iOS 12 70cb93a386Sopenharmony_ci if (@available(iOS 12.0, *)) { 71cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily5_v1]) { 72cb93a386Sopenharmony_ci *group = 5; 73cb93a386Sopenharmony_ci return true; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v2]) { 76cb93a386Sopenharmony_ci *group = 4; 77cb93a386Sopenharmony_ci return true; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v4]) { 80cb93a386Sopenharmony_ci *group = 3; 81cb93a386Sopenharmony_ci return true; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v5]) { 84cb93a386Sopenharmony_ci *group = 2; 85cb93a386Sopenharmony_ci return true; 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v5]) { 88cb93a386Sopenharmony_ci *group = 1; 89cb93a386Sopenharmony_ci return true; 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci } 92cb93a386Sopenharmony_ci // iOS 11 93cb93a386Sopenharmony_ci if (@available(iOS 11.0, *)) { 94cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]) { 95cb93a386Sopenharmony_ci *group = 4; 96cb93a386Sopenharmony_ci return true; 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v3]) { 99cb93a386Sopenharmony_ci *group = 3; 100cb93a386Sopenharmony_ci return true; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v4]) { 103cb93a386Sopenharmony_ci *group = 2; 104cb93a386Sopenharmony_ci return true; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v4]) { 107cb93a386Sopenharmony_ci *group = 1; 108cb93a386Sopenharmony_ci return true; 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci // iOS 10 112cb93a386Sopenharmony_ci if (@available(iOS 10.0, *)) { 113cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2]) { 114cb93a386Sopenharmony_ci *group = 3; 115cb93a386Sopenharmony_ci return true; 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v3]) { 118cb93a386Sopenharmony_ci *group = 2; 119cb93a386Sopenharmony_ci return true; 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v3]) { 122cb93a386Sopenharmony_ci *group = 1; 123cb93a386Sopenharmony_ci return true; 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci } 126cb93a386Sopenharmony_ci // We don't support earlier OSes 127cb93a386Sopenharmony_ci#endif 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci // No supported GPU families were found 130cb93a386Sopenharmony_ci return false; 131cb93a386Sopenharmony_ci} 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_cibool Caps::GetGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group) { 134cb93a386Sopenharmony_ci#if GR_METAL_SDK_VERSION >= 220 135cb93a386Sopenharmony_ci if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { 136cb93a386Sopenharmony_ci // Apple Silicon 137cb93a386Sopenharmony_ci#if GR_METAL_SDK_VERSION >= 230 138cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple7]) { 139cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 140cb93a386Sopenharmony_ci *group = 7; 141cb93a386Sopenharmony_ci return true; 142cb93a386Sopenharmony_ci } 143cb93a386Sopenharmony_ci#endif 144cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS 145cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple6]) { 146cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 147cb93a386Sopenharmony_ci *group = 6; 148cb93a386Sopenharmony_ci return true; 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple5]) { 151cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 152cb93a386Sopenharmony_ci *group = 5; 153cb93a386Sopenharmony_ci return true; 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple4]) { 156cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 157cb93a386Sopenharmony_ci *group = 4; 158cb93a386Sopenharmony_ci return true; 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple3]) { 161cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 162cb93a386Sopenharmony_ci *group = 3; 163cb93a386Sopenharmony_ci return true; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple2]) { 166cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 167cb93a386Sopenharmony_ci *group = 2; 168cb93a386Sopenharmony_ci return true; 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyApple1]) { 171cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kApple; 172cb93a386Sopenharmony_ci *group = 1; 173cb93a386Sopenharmony_ci return true; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci#endif 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci // Older Macs 178cb93a386Sopenharmony_ci // At the moment MacCatalyst families have the same features as Mac, 179cb93a386Sopenharmony_ci // so we treat them the same 180cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyMac2] || 181cb93a386Sopenharmony_ci [device supportsFamily:MTLGPUFamilyMacCatalyst2]) { 182cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kMac; 183cb93a386Sopenharmony_ci *group = 2; 184cb93a386Sopenharmony_ci return true; 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci if ([device supportsFamily:MTLGPUFamilyMac1] || 187cb93a386Sopenharmony_ci [device supportsFamily:MTLGPUFamilyMacCatalyst1]) { 188cb93a386Sopenharmony_ci *gpuFamily = GPUFamily::kMac; 189cb93a386Sopenharmony_ci *group = 1; 190cb93a386Sopenharmony_ci return true; 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci } 193cb93a386Sopenharmony_ci#endif 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_ci // No supported GPU families were found 196cb93a386Sopenharmony_ci return false; 197cb93a386Sopenharmony_ci} 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_civoid Caps::initGPUFamily(id<MTLDevice> device) { 200cb93a386Sopenharmony_ci if (!GetGPUFamily(device, &fGPUFamily, &fFamilyGroup) && 201cb93a386Sopenharmony_ci !GetGPUFamilyFromFeatureSet(device, &fGPUFamily, &fFamilyGroup)) { 202cb93a386Sopenharmony_ci // We don't know what this is, fall back to minimum defaults 203cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC 204cb93a386Sopenharmony_ci fGPUFamily = GPUFamily::kMac; 205cb93a386Sopenharmony_ci fFamilyGroup = 1; 206cb93a386Sopenharmony_ci#else 207cb93a386Sopenharmony_ci fGPUFamily = GPUFamily::kApple; 208cb93a386Sopenharmony_ci fFamilyGroup = 1; 209cb93a386Sopenharmony_ci#endif 210cb93a386Sopenharmony_ci } 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_civoid Caps::initCaps(const id<MTLDevice> device) { 214cb93a386Sopenharmony_ci // TODO 215cb93a386Sopenharmony_ci} 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_civoid Caps::initShaderCaps() { 218cb93a386Sopenharmony_ci // TODO 219cb93a386Sopenharmony_ci} 220cb93a386Sopenharmony_ci 221cb93a386Sopenharmony_civoid Caps::initFormatTable() { 222cb93a386Sopenharmony_ci // TODO 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_ciskgpu::TextureInfo Caps::getDefaultSampledTextureInfo(SkColorType colorType, 226cb93a386Sopenharmony_ci uint32_t levelCount, 227cb93a386Sopenharmony_ci Protected, 228cb93a386Sopenharmony_ci Renderable renderable) const { 229cb93a386Sopenharmony_ci MTLTextureUsage usage = MTLTextureUsageShaderRead; 230cb93a386Sopenharmony_ci if (renderable == Renderable::kYes) { 231cb93a386Sopenharmony_ci usage |= MTLTextureUsageRenderTarget; 232cb93a386Sopenharmony_ci } 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ci TextureInfo info; 235cb93a386Sopenharmony_ci info.fSampleCount = 1; 236cb93a386Sopenharmony_ci info.fLevelCount = levelCount; 237cb93a386Sopenharmony_ci info.fFormat = SkColorTypeToFormat(colorType); 238cb93a386Sopenharmony_ci info.fUsage = usage; 239cb93a386Sopenharmony_ci info.fStorageMode = MTLStorageModePrivate; 240cb93a386Sopenharmony_ci info.fFramebufferOnly = false; 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ci return info; 243cb93a386Sopenharmony_ci} 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ciskgpu::TextureInfo Caps::getDefaultMSAATextureInfo(SkColorType colorType, 246cb93a386Sopenharmony_ci uint32_t sampleCount, 247cb93a386Sopenharmony_ci Protected) const { 248cb93a386Sopenharmony_ci MTLTextureUsage usage = MTLTextureUsageRenderTarget; 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci TextureInfo info; 251cb93a386Sopenharmony_ci info.fSampleCount = sampleCount; 252cb93a386Sopenharmony_ci info.fLevelCount = 1; 253cb93a386Sopenharmony_ci info.fFormat = SkColorTypeToFormat(colorType); 254cb93a386Sopenharmony_ci info.fUsage = usage; 255cb93a386Sopenharmony_ci info.fStorageMode = MTLStorageModePrivate; 256cb93a386Sopenharmony_ci info.fFramebufferOnly = false; 257cb93a386Sopenharmony_ci 258cb93a386Sopenharmony_ci return info; 259cb93a386Sopenharmony_ci} 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ciskgpu::TextureInfo Caps::getDefaultDepthStencilTextureInfo(DepthStencilType depthStencilType, 262cb93a386Sopenharmony_ci uint32_t sampleCount, 263cb93a386Sopenharmony_ci Protected) const { 264cb93a386Sopenharmony_ci TextureInfo info; 265cb93a386Sopenharmony_ci info.fSampleCount = sampleCount; 266cb93a386Sopenharmony_ci info.fLevelCount = 1; 267cb93a386Sopenharmony_ci info.fFormat = DepthStencilTypeToFormat(depthStencilType); 268cb93a386Sopenharmony_ci info.fUsage = MTLTextureUsageRenderTarget; 269cb93a386Sopenharmony_ci info.fStorageMode = MTLStorageModePrivate; 270cb93a386Sopenharmony_ci info.fFramebufferOnly = false; 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ci return info; 273cb93a386Sopenharmony_ci} 274cb93a386Sopenharmony_ci 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_ci 278cb93a386Sopenharmony_ci} // namespace skgpu::mtl 279