blob: c1c0d8356e3649d1d23d30be0c2cf68955f788a9 [file] [log] [blame]
/*
* 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<MTLDevice> 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<MTLDevice> 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<MTLDevice> 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<MTLDevice> 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<MTLDevice> 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;
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;
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;
return info;
}
} // namespace skgpu::mtl