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