xref: /aosp_15_r20/external/skia/src/gpu/graphite/mtl/MtlCaps.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlCaps.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker#include "include/core/SkTextureCompressionType.h"
11*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/TextureInfo.h"
12*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/mtl/MtlGraphiteTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/SwizzlePriv.h"
14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/CommandBuffer.h"
15*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/ComputePipelineDesc.h"
16*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/GraphicsPipelineDesc.h"
17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/GraphiteResourceKey.h"
18*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/RenderPassDesc.h"
19*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/RendererProvider.h"
20*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/TextureProxy.h"
21*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphicsPipeline.h"
22*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteTypesPriv.h"
23*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteUtilsPriv.h"
24*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h"
25*c8dee2aaSAndroid Build Coastguard Worker#include "src/sksl/SkSLUtil.h"
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Workernamespace skgpu::graphite {
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard WorkerMtlCaps::MtlCaps(const id<MTLDevice> device, const ContextOptions& options)
30*c8dee2aaSAndroid Build Coastguard Worker        : Caps() {
31*c8dee2aaSAndroid Build Coastguard Worker    this->initGPUFamily(device);
32*c8dee2aaSAndroid Build Coastguard Worker    this->initCaps(device);
33*c8dee2aaSAndroid Build Coastguard Worker    this->initShaderCaps();
34*c8dee2aaSAndroid Build Coastguard Worker
35*c8dee2aaSAndroid Build Coastguard Worker    this->initFormatTable(device);
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker    // Metal-specific MtlCaps
38*c8dee2aaSAndroid Build Coastguard Worker
39*c8dee2aaSAndroid Build Coastguard Worker    this->finishInitialization(options);
40*c8dee2aaSAndroid Build Coastguard Worker}
41*c8dee2aaSAndroid Build Coastguard Worker
42*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::GetGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group) {
43*c8dee2aaSAndroid Build Coastguard Worker#if SKGPU_GRAPHITE_METAL_SDK_VERSION >= 220
44*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
45*c8dee2aaSAndroid Build Coastguard Worker        // Apple Silicon
46*c8dee2aaSAndroid Build Coastguard Worker#if SKGPU_GRAPHITE_METAL_SDK_VERSION >= 230
47*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple7]) {
48*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
49*c8dee2aaSAndroid Build Coastguard Worker            *group = 7;
50*c8dee2aaSAndroid Build Coastguard Worker            return true;
51*c8dee2aaSAndroid Build Coastguard Worker        }
52*c8dee2aaSAndroid Build Coastguard Worker#endif
53*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_IOS
54*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple6]) {
55*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
56*c8dee2aaSAndroid Build Coastguard Worker            *group = 6;
57*c8dee2aaSAndroid Build Coastguard Worker            return true;
58*c8dee2aaSAndroid Build Coastguard Worker        }
59*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple5]) {
60*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
61*c8dee2aaSAndroid Build Coastguard Worker            *group = 5;
62*c8dee2aaSAndroid Build Coastguard Worker            return true;
63*c8dee2aaSAndroid Build Coastguard Worker        }
64*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple4]) {
65*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
66*c8dee2aaSAndroid Build Coastguard Worker            *group = 4;
67*c8dee2aaSAndroid Build Coastguard Worker            return true;
68*c8dee2aaSAndroid Build Coastguard Worker        }
69*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple3]) {
70*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
71*c8dee2aaSAndroid Build Coastguard Worker            *group = 3;
72*c8dee2aaSAndroid Build Coastguard Worker            return true;
73*c8dee2aaSAndroid Build Coastguard Worker        }
74*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple2]) {
75*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
76*c8dee2aaSAndroid Build Coastguard Worker            *group = 2;
77*c8dee2aaSAndroid Build Coastguard Worker            return true;
78*c8dee2aaSAndroid Build Coastguard Worker        }
79*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyApple1]) {
80*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kApple;
81*c8dee2aaSAndroid Build Coastguard Worker            *group = 1;
82*c8dee2aaSAndroid Build Coastguard Worker            return true;
83*c8dee2aaSAndroid Build Coastguard Worker        }
84*c8dee2aaSAndroid Build Coastguard Worker#endif
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker        // Older Macs
87*c8dee2aaSAndroid Build Coastguard Worker        // MTLGPUFamilyMac1, MTLGPUFamilyMacCatalyst1, and MTLGPUFamilyMacCatalyst2 are deprecated.
88*c8dee2aaSAndroid Build Coastguard Worker        // However, some MTLGPUFamilyMac1 only hardware is still supported.
89*c8dee2aaSAndroid Build Coastguard Worker        // MacCatalyst families have the same features as Mac, so treat them the same
90*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:MTLGPUFamilyMac2] ||
91*c8dee2aaSAndroid Build Coastguard Worker            [device supportsFamily:(MTLGPUFamily)4002/*MTLGPUFamilyMacCatalyst2*/]) {
92*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kMac;
93*c8dee2aaSAndroid Build Coastguard Worker            *group = 2;
94*c8dee2aaSAndroid Build Coastguard Worker            return true;
95*c8dee2aaSAndroid Build Coastguard Worker        }
96*c8dee2aaSAndroid Build Coastguard Worker        if ([device supportsFamily:(MTLGPUFamily)2001/*MTLGPUFamilyMac1*/] ||
97*c8dee2aaSAndroid Build Coastguard Worker            [device supportsFamily:(MTLGPUFamily)4001/*MTLGPUFamilyMacCatalyst1*/]) {
98*c8dee2aaSAndroid Build Coastguard Worker            *gpuFamily = GPUFamily::kMac;
99*c8dee2aaSAndroid Build Coastguard Worker            *group = 1;
100*c8dee2aaSAndroid Build Coastguard Worker            return true;
101*c8dee2aaSAndroid Build Coastguard Worker        }
102*c8dee2aaSAndroid Build Coastguard Worker    }
103*c8dee2aaSAndroid Build Coastguard Worker#endif
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker    // No supported GPU families were found
106*c8dee2aaSAndroid Build Coastguard Worker    return false;
107*c8dee2aaSAndroid Build Coastguard Worker}
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::initGPUFamily(id<MTLDevice> device) {
110*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
111*c8dee2aaSAndroid Build Coastguard Worker        if (GetGPUFamily(device, &fGPUFamily, &fFamilyGroup)) {
112*c8dee2aaSAndroid Build Coastguard Worker            return;
113*c8dee2aaSAndroid Build Coastguard Worker        }
114*c8dee2aaSAndroid Build Coastguard Worker    }
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker    // We don't know what this is, fall back to minimum defaults
117*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
118*c8dee2aaSAndroid Build Coastguard Worker    fGPUFamily = GPUFamily::kMac;
119*c8dee2aaSAndroid Build Coastguard Worker    fFamilyGroup = 1;
120*c8dee2aaSAndroid Build Coastguard Worker#else
121*c8dee2aaSAndroid Build Coastguard Worker    fGPUFamily = GPUFamily::kApple;
122*c8dee2aaSAndroid Build Coastguard Worker    fFamilyGroup = 1;
123*c8dee2aaSAndroid Build Coastguard Worker#endif
124*c8dee2aaSAndroid Build Coastguard Worker}
125*c8dee2aaSAndroid Build Coastguard Worker
126*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::initCaps(const id<MTLDevice> device) {
127*c8dee2aaSAndroid Build Coastguard Worker#if defined(GPU_TEST_UTILS)
128*c8dee2aaSAndroid Build Coastguard Worker    this->setDeviceName([[device name] UTF8String]);
129*c8dee2aaSAndroid Build Coastguard Worker#endif
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker    if (this->isMac() || fFamilyGroup >= 3) {
132*c8dee2aaSAndroid Build Coastguard Worker        fMaxTextureSize = 16384;
133*c8dee2aaSAndroid Build Coastguard Worker    } else {
134*c8dee2aaSAndroid Build Coastguard Worker        fMaxTextureSize = 8192;
135*c8dee2aaSAndroid Build Coastguard Worker    }
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker    // We use constant address space for our uniform buffers which has various alignment
138*c8dee2aaSAndroid Build Coastguard Worker    // requirements for the offset when binding the buffer. On MacOS Intel the offset must align
139*c8dee2aaSAndroid Build Coastguard Worker    // to 256. On iOS or Apple Silicon we must align to the max of the data type consumed by the
140*c8dee2aaSAndroid Build Coastguard Worker    // vertex function or 4 bytes, or we can ignore the data type and just use 16 bytes.
141*c8dee2aaSAndroid Build Coastguard Worker    //
142*c8dee2aaSAndroid Build Coastguard Worker    // On Mac, all copies must be aligned to at least 4 bytes; on iOS there is no alignment.
143*c8dee2aaSAndroid Build Coastguard Worker    if (this->isMac()) {
144*c8dee2aaSAndroid Build Coastguard Worker        fRequiredUniformBufferAlignment = 256;
145*c8dee2aaSAndroid Build Coastguard Worker        fRequiredTransferBufferAlignment = 4;
146*c8dee2aaSAndroid Build Coastguard Worker    } else {
147*c8dee2aaSAndroid Build Coastguard Worker        fRequiredUniformBufferAlignment = 16;
148*c8dee2aaSAndroid Build Coastguard Worker        fRequiredTransferBufferAlignment = 1;
149*c8dee2aaSAndroid Build Coastguard Worker    }
150*c8dee2aaSAndroid Build Coastguard Worker
151*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fUniformBufferLayout = Layout::kMetal;
152*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fStorageBufferLayout = Layout::kMetal;
153*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fDistinctIndexRanges = true;
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fIntrinsicBufferBinding =
156*c8dee2aaSAndroid Build Coastguard Worker            MtlGraphicsPipeline::kIntrinsicUniformBufferIndex;
157*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fRenderStepBufferBinding =
158*c8dee2aaSAndroid Build Coastguard Worker            MtlGraphicsPipeline::kRenderStepUniformBufferIndex;
159*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fPaintParamsBufferBinding = MtlGraphicsPipeline::kPaintUniformBufferIndex;
160*c8dee2aaSAndroid Build Coastguard Worker    fResourceBindingReqs.fGradientBufferBinding = MtlGraphicsPipeline::kGradientBufferIndex;
161*c8dee2aaSAndroid Build Coastguard Worker
162*c8dee2aaSAndroid Build Coastguard Worker    // Metal does not distinguish between uniform and storage buffers.
163*c8dee2aaSAndroid Build Coastguard Worker    fRequiredStorageBufferAlignment = fRequiredUniformBufferAlignment;
164*c8dee2aaSAndroid Build Coastguard Worker
165*c8dee2aaSAndroid Build Coastguard Worker    fStorageBufferSupport = true;
166*c8dee2aaSAndroid Build Coastguard Worker
167*c8dee2aaSAndroid Build Coastguard Worker    fComputeSupport = true;
168*c8dee2aaSAndroid Build Coastguard Worker
169*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.12, iOS 14.0, tvOS 14.0, *)) {
170*c8dee2aaSAndroid Build Coastguard Worker        fClampToBorderSupport = (this->isMac() || fFamilyGroup >= 7);
171*c8dee2aaSAndroid Build Coastguard Worker    } else {
172*c8dee2aaSAndroid Build Coastguard Worker        fClampToBorderSupport = false;
173*c8dee2aaSAndroid Build Coastguard Worker    }
174*c8dee2aaSAndroid Build Coastguard Worker
175*c8dee2aaSAndroid Build Coastguard Worker    // Init sample counts. All devices support 1 (i.e. 0 in skia).
176*c8dee2aaSAndroid Build Coastguard Worker    fColorSampleCounts.push_back(1);
177*c8dee2aaSAndroid Build Coastguard Worker    if (![device.name containsString:@"Intel"]) {
178*c8dee2aaSAndroid Build Coastguard Worker        if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
179*c8dee2aaSAndroid Build Coastguard Worker            for (auto sampleCnt : {2, 4, 8}) {
180*c8dee2aaSAndroid Build Coastguard Worker                if ([device supportsTextureSampleCount:sampleCnt]) {
181*c8dee2aaSAndroid Build Coastguard Worker                    fColorSampleCounts.push_back(sampleCnt);
182*c8dee2aaSAndroid Build Coastguard Worker                }
183*c8dee2aaSAndroid Build Coastguard Worker            }
184*c8dee2aaSAndroid Build Coastguard Worker        }
185*c8dee2aaSAndroid Build Coastguard Worker    }
186*c8dee2aaSAndroid Build Coastguard Worker}
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::initShaderCaps() {
189*c8dee2aaSAndroid Build Coastguard Worker    SkSL::ShaderCaps* shaderCaps = fShaderCaps.get();
190*c8dee2aaSAndroid Build Coastguard Worker
191*c8dee2aaSAndroid Build Coastguard Worker    // Dual source blending requires Metal 1.2.
192*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
193*c8dee2aaSAndroid Build Coastguard Worker        shaderCaps->fDualSourceBlendingSupport = true;
194*c8dee2aaSAndroid Build Coastguard Worker    }
195*c8dee2aaSAndroid Build Coastguard Worker
196*c8dee2aaSAndroid Build Coastguard Worker    // Setting this true with the assumption that this cap will eventually mean we support varying
197*c8dee2aaSAndroid Build Coastguard Worker    // precisions and not just via modifiers.
198*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fUsesPrecisionModifiers = true;
199*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fFlatInterpolationSupport = true;
200*c8dee2aaSAndroid Build Coastguard Worker
201*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fShaderDerivativeSupport = true;
202*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fInfinitySupport = true;
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 11.0, *)) {
205*c8dee2aaSAndroid Build Coastguard Worker        if (this->isApple()) {
206*c8dee2aaSAndroid Build Coastguard Worker            shaderCaps->fFBFetchSupport = true;
207*c8dee2aaSAndroid Build Coastguard Worker            shaderCaps->fFBFetchColorName = "sk_LastFragColor";
208*c8dee2aaSAndroid Build Coastguard Worker        }
209*c8dee2aaSAndroid Build Coastguard Worker    }
210*c8dee2aaSAndroid Build Coastguard Worker
211*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fIntegerSupport = true;
212*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fNonsquareMatrixSupport = true;
213*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fInverseHyperbolicSupport = true;
214*c8dee2aaSAndroid Build Coastguard Worker
215*c8dee2aaSAndroid Build Coastguard Worker    // Metal uses IEEE floats so assuming those values here.
216*c8dee2aaSAndroid Build Coastguard Worker    shaderCaps->fFloatIs32Bits = true;
217*c8dee2aaSAndroid Build Coastguard Worker}
218*c8dee2aaSAndroid Build Coastguard Worker
219*c8dee2aaSAndroid Build Coastguard Worker// Define this so we can use it to initialize arrays and work around
220*c8dee2aaSAndroid Build Coastguard Worker// the fact that these pixel formats are not always available.
221*c8dee2aaSAndroid Build Coastguard Worker#define kMTLPixelFormatB5G6R5Unorm MTLPixelFormat(40)
222*c8dee2aaSAndroid Build Coastguard Worker#define kMTLPixelFormatABGR4Unorm MTLPixelFormat(42)
223*c8dee2aaSAndroid Build Coastguard Worker#define kMTLPixelFormatETC2_RGB8 MTLPixelFormat(180)
224*c8dee2aaSAndroid Build Coastguard Worker
225*c8dee2aaSAndroid Build Coastguard Worker// These are all the valid MTLPixelFormats that we currently support in Skia.  They are roughly
226*c8dee2aaSAndroid Build Coastguard Worker// ordered from most frequently used to least to improve look up times in arrays.
227*c8dee2aaSAndroid Build Coastguard Workerstatic constexpr MTLPixelFormat kMtlFormats[] = {
228*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRGBA8Unorm,
229*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatR8Unorm,
230*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatA8Unorm,
231*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatBGRA8Unorm,
232*c8dee2aaSAndroid Build Coastguard Worker    kMTLPixelFormatB5G6R5Unorm,
233*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRGBA16Float,
234*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatR16Float,
235*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRG8Unorm,
236*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRGB10A2Unorm,
237*c8dee2aaSAndroid Build Coastguard Worker    // MTLPixelFormatBGR10A2Unorm
238*c8dee2aaSAndroid Build Coastguard Worker    kMTLPixelFormatABGR4Unorm,
239*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRGBA8Unorm_sRGB,
240*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatR16Unorm,
241*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRG16Unorm,
242*c8dee2aaSAndroid Build Coastguard Worker    kMTLPixelFormatETC2_RGB8,
243*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
244*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatBC1_RGBA,
245*c8dee2aaSAndroid Build Coastguard Worker#endif
246*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRGBA16Unorm,
247*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatRG16Float,
248*c8dee2aaSAndroid Build Coastguard Worker
249*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatStencil8,
250*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatDepth16Unorm,
251*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatDepth32Float,
252*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
253*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatDepth24Unorm_Stencil8,
254*c8dee2aaSAndroid Build Coastguard Worker#endif
255*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatDepth32Float_Stencil8,
256*c8dee2aaSAndroid Build Coastguard Worker
257*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormatInvalid,
258*c8dee2aaSAndroid Build Coastguard Worker};
259*c8dee2aaSAndroid Build Coastguard Worker
260*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::setColorType(SkColorType colorType, std::initializer_list<MTLPixelFormat> formats) {
261*c8dee2aaSAndroid Build Coastguard Worker    int idx = static_cast<int>(colorType);
262*c8dee2aaSAndroid Build Coastguard Worker    for (auto it = formats.begin(); it != formats.end(); ++it) {
263*c8dee2aaSAndroid Build Coastguard Worker        const auto& info = this->getFormatInfo(*it);
264*c8dee2aaSAndroid Build Coastguard Worker        for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
265*c8dee2aaSAndroid Build Coastguard Worker            if (info.fColorTypeInfos[i].fColorType == colorType) {
266*c8dee2aaSAndroid Build Coastguard Worker                fColorTypeToFormatTable[idx] = *it;
267*c8dee2aaSAndroid Build Coastguard Worker                return;
268*c8dee2aaSAndroid Build Coastguard Worker            }
269*c8dee2aaSAndroid Build Coastguard Worker        }
270*c8dee2aaSAndroid Build Coastguard Worker    }
271*c8dee2aaSAndroid Build Coastguard Worker}
272*c8dee2aaSAndroid Build Coastguard Worker
273*c8dee2aaSAndroid Build Coastguard Workersize_t MtlCaps::GetFormatIndex(MTLPixelFormat pixelFormat) {
274*c8dee2aaSAndroid Build Coastguard Worker    static_assert(std::size(kMtlFormats) == MtlCaps::kNumMtlFormats,
275*c8dee2aaSAndroid Build Coastguard Worker                  "Size of kMtlFormats array must match static value in header");
276*c8dee2aaSAndroid Build Coastguard Worker    for (size_t i = 0; i < MtlCaps::kNumMtlFormats; ++i) {
277*c8dee2aaSAndroid Build Coastguard Worker        if (kMtlFormats[i] == pixelFormat) {
278*c8dee2aaSAndroid Build Coastguard Worker            return i;
279*c8dee2aaSAndroid Build Coastguard Worker        }
280*c8dee2aaSAndroid Build Coastguard Worker    }
281*c8dee2aaSAndroid Build Coastguard Worker    return GetFormatIndex(MTLPixelFormatInvalid);
282*c8dee2aaSAndroid Build Coastguard Worker}
283*c8dee2aaSAndroid Build Coastguard Worker
284*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::initFormatTable(const id<MTLDevice> device) {
285*c8dee2aaSAndroid Build Coastguard Worker    FormatInfo* info;
286*c8dee2aaSAndroid Build Coastguard Worker
287*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
288*c8dee2aaSAndroid Build Coastguard Worker        if (this->isApple()) {
289*c8dee2aaSAndroid Build Coastguard Worker            SkASSERT(kMTLPixelFormatB5G6R5Unorm == MTLPixelFormatB5G6R5Unorm);
290*c8dee2aaSAndroid Build Coastguard Worker            SkASSERT(kMTLPixelFormatABGR4Unorm == MTLPixelFormatABGR4Unorm);
291*c8dee2aaSAndroid Build Coastguard Worker        }
292*c8dee2aaSAndroid Build Coastguard Worker    }
293*c8dee2aaSAndroid Build Coastguard Worker
294*c8dee2aaSAndroid Build Coastguard Worker    // Format: RGBA8Unorm
295*c8dee2aaSAndroid Build Coastguard Worker    {
296*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm)];
297*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
298*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 2;
299*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
300*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
301*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA8Unorm, Surface: kRGBA_8888
302*c8dee2aaSAndroid Build Coastguard Worker        {
303*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
304*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGBA_8888_SkColorType;
305*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
306*c8dee2aaSAndroid Build Coastguard Worker        }
307*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA8Unorm, Surface: kRGB_888x
308*c8dee2aaSAndroid Build Coastguard Worker        {
309*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
310*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGB_888x_SkColorType;
311*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
312*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
313*c8dee2aaSAndroid Build Coastguard Worker        }
314*c8dee2aaSAndroid Build Coastguard Worker    }
315*c8dee2aaSAndroid Build Coastguard Worker
316*c8dee2aaSAndroid Build Coastguard Worker    // Format: R8Unorm
317*c8dee2aaSAndroid Build Coastguard Worker    {
318*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR8Unorm)];
319*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
320*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 3;
321*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
322*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
323*c8dee2aaSAndroid Build Coastguard Worker        // Format: R8Unorm, Surface: kR8_unorm
324*c8dee2aaSAndroid Build Coastguard Worker        {
325*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
326*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kR8_unorm_SkColorType;
327*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
328*c8dee2aaSAndroid Build Coastguard Worker        }
329*c8dee2aaSAndroid Build Coastguard Worker        // Format: R8Unorm, Surface: kAlpha_8
330*c8dee2aaSAndroid Build Coastguard Worker        {
331*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
332*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kAlpha_8_SkColorType;
333*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
334*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
335*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
336*c8dee2aaSAndroid Build Coastguard Worker        }
337*c8dee2aaSAndroid Build Coastguard Worker        // Format: R8Unorm, Surface: kGray_8
338*c8dee2aaSAndroid Build Coastguard Worker        {
339*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
340*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kGray_8_SkColorType;
341*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
342*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
343*c8dee2aaSAndroid Build Coastguard Worker        }
344*c8dee2aaSAndroid Build Coastguard Worker    }
345*c8dee2aaSAndroid Build Coastguard Worker
346*c8dee2aaSAndroid Build Coastguard Worker    // Format: A8Unorm
347*c8dee2aaSAndroid Build Coastguard Worker    {
348*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatA8Unorm)];
349*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kTexturable_Flag;
350*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
351*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
352*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
353*c8dee2aaSAndroid Build Coastguard Worker        // Format: A8Unorm, Surface: kAlpha_8
354*c8dee2aaSAndroid Build Coastguard Worker        {
355*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
356*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kAlpha_8_SkColorType;
357*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
358*c8dee2aaSAndroid Build Coastguard Worker        }
359*c8dee2aaSAndroid Build Coastguard Worker    }
360*c8dee2aaSAndroid Build Coastguard Worker
361*c8dee2aaSAndroid Build Coastguard Worker    // Format: BGRA8Unorm
362*c8dee2aaSAndroid Build Coastguard Worker    {
363*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatBGRA8Unorm)];
364*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
365*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
366*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
367*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
368*c8dee2aaSAndroid Build Coastguard Worker        // Format: BGRA8Unorm, Surface: kBGRA_8888
369*c8dee2aaSAndroid Build Coastguard Worker        {
370*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
371*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kBGRA_8888_SkColorType;
372*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
373*c8dee2aaSAndroid Build Coastguard Worker        }
374*c8dee2aaSAndroid Build Coastguard Worker    }
375*c8dee2aaSAndroid Build Coastguard Worker
376*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
377*c8dee2aaSAndroid Build Coastguard Worker        if (this->isApple()) {
378*c8dee2aaSAndroid Build Coastguard Worker            // Format: B5G6R5Unorm
379*c8dee2aaSAndroid Build Coastguard Worker            {
380*c8dee2aaSAndroid Build Coastguard Worker                info = &fFormatTable[GetFormatIndex(MTLPixelFormatB5G6R5Unorm)];
381*c8dee2aaSAndroid Build Coastguard Worker                info->fFlags = FormatInfo::kAllFlags;
382*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfoCount = 1;
383*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfos =
384*c8dee2aaSAndroid Build Coastguard Worker                        std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
385*c8dee2aaSAndroid Build Coastguard Worker                int ctIdx = 0;
386*c8dee2aaSAndroid Build Coastguard Worker                // Format: B5G6R5Unorm, Surface: kBGR_565
387*c8dee2aaSAndroid Build Coastguard Worker                {
388*c8dee2aaSAndroid Build Coastguard Worker                    auto& ctInfo = info->fColorTypeInfos[ctIdx++];
389*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fColorType = kRGB_565_SkColorType;
390*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
391*c8dee2aaSAndroid Build Coastguard Worker                                    ColorTypeInfo::kRenderable_Flag;
392*c8dee2aaSAndroid Build Coastguard Worker                }
393*c8dee2aaSAndroid Build Coastguard Worker            }
394*c8dee2aaSAndroid Build Coastguard Worker
395*c8dee2aaSAndroid Build Coastguard Worker            // Format: ABGR4Unorm
396*c8dee2aaSAndroid Build Coastguard Worker            {
397*c8dee2aaSAndroid Build Coastguard Worker                info = &fFormatTable[GetFormatIndex(MTLPixelFormatABGR4Unorm)];
398*c8dee2aaSAndroid Build Coastguard Worker                info->fFlags = FormatInfo::kAllFlags;
399*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfoCount = 1;
400*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfos =
401*c8dee2aaSAndroid Build Coastguard Worker                        std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
402*c8dee2aaSAndroid Build Coastguard Worker                int ctIdx = 0;
403*c8dee2aaSAndroid Build Coastguard Worker                // Format: ABGR4Unorm, Surface: kABGR_4444
404*c8dee2aaSAndroid Build Coastguard Worker                {
405*c8dee2aaSAndroid Build Coastguard Worker                    auto& ctInfo = info->fColorTypeInfos[ctIdx++];
406*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fColorType = kARGB_4444_SkColorType;
407*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
408*c8dee2aaSAndroid Build Coastguard Worker                                    ColorTypeInfo::kRenderable_Flag;
409*c8dee2aaSAndroid Build Coastguard Worker                }
410*c8dee2aaSAndroid Build Coastguard Worker            }
411*c8dee2aaSAndroid Build Coastguard Worker        }
412*c8dee2aaSAndroid Build Coastguard Worker    }
413*c8dee2aaSAndroid Build Coastguard Worker
414*c8dee2aaSAndroid Build Coastguard Worker    // Format: RGBA8Unorm_sRGB
415*c8dee2aaSAndroid Build Coastguard Worker    {
416*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm_sRGB)];
417*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
418*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
419*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
420*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
421*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA8Unorm_sRGB, Surface: kSRGBA_8888
422*c8dee2aaSAndroid Build Coastguard Worker        {
423*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
424*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kSRGBA_8888_SkColorType;
425*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
426*c8dee2aaSAndroid Build Coastguard Worker        }
427*c8dee2aaSAndroid Build Coastguard Worker    }
428*c8dee2aaSAndroid Build Coastguard Worker
429*c8dee2aaSAndroid Build Coastguard Worker    // Format: RGB10A2Unorm
430*c8dee2aaSAndroid Build Coastguard Worker    {
431*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGB10A2Unorm)];
432*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac() || fFamilyGroup >= 3) {
433*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kAllFlags;
434*c8dee2aaSAndroid Build Coastguard Worker        } else {
435*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kTexturable_Flag;
436*c8dee2aaSAndroid Build Coastguard Worker        }
437*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 2;
438*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
439*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
440*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGB10A2Unorm, Surface: kRGBA_1010102
441*c8dee2aaSAndroid Build Coastguard Worker        {
442*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
443*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGBA_1010102_SkColorType;
444*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
445*c8dee2aaSAndroid Build Coastguard Worker        }
446*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGB10A2Unorm, Surface: kRGB_101010x
447*c8dee2aaSAndroid Build Coastguard Worker        {
448*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
449*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGB_101010x_SkColorType;
450*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
451*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
452*c8dee2aaSAndroid Build Coastguard Worker        }
453*c8dee2aaSAndroid Build Coastguard Worker    }
454*c8dee2aaSAndroid Build Coastguard Worker
455*c8dee2aaSAndroid Build Coastguard Worker    // Format: RGBA16Float
456*c8dee2aaSAndroid Build Coastguard Worker    {
457*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Float)];
458*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
459*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 3;
460*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
461*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
462*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA16Float, Surface: RGBA_F16
463*c8dee2aaSAndroid Build Coastguard Worker        {
464*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
465*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGBA_F16_SkColorType;
466*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
467*c8dee2aaSAndroid Build Coastguard Worker        }
468*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA16Float, Surface: RGBA_F16Norm
469*c8dee2aaSAndroid Build Coastguard Worker        {
470*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
471*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGBA_F16Norm_SkColorType;
472*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
473*c8dee2aaSAndroid Build Coastguard Worker        }
474*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA16Float, Surface: RGB_F16F16F16x
475*c8dee2aaSAndroid Build Coastguard Worker        {
476*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
477*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kRGBA_F16_SkColorType;
478*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
479*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
480*c8dee2aaSAndroid Build Coastguard Worker        }
481*c8dee2aaSAndroid Build Coastguard Worker    }
482*c8dee2aaSAndroid Build Coastguard Worker
483*c8dee2aaSAndroid Build Coastguard Worker    // Format: R16Float
484*c8dee2aaSAndroid Build Coastguard Worker    {
485*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Float)];
486*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
487*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
488*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
489*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
490*c8dee2aaSAndroid Build Coastguard Worker        // Format: R16Float, Surface: kA16_float
491*c8dee2aaSAndroid Build Coastguard Worker        {
492*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
493*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kA16_float_SkColorType;
494*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
495*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
496*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
497*c8dee2aaSAndroid Build Coastguard Worker        }
498*c8dee2aaSAndroid Build Coastguard Worker    }
499*c8dee2aaSAndroid Build Coastguard Worker
500*c8dee2aaSAndroid Build Coastguard Worker    // Format: RG8Unorm
501*c8dee2aaSAndroid Build Coastguard Worker    {
502*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG8Unorm)];
503*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
504*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
505*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
506*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
507*c8dee2aaSAndroid Build Coastguard Worker        // Format: RG8Unorm, Surface: kR8G8_unorm
508*c8dee2aaSAndroid Build Coastguard Worker        {
509*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
510*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kR8G8_unorm_SkColorType;
511*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
512*c8dee2aaSAndroid Build Coastguard Worker        }
513*c8dee2aaSAndroid Build Coastguard Worker    }
514*c8dee2aaSAndroid Build Coastguard Worker
515*c8dee2aaSAndroid Build Coastguard Worker    // Format: RGBA16Unorm
516*c8dee2aaSAndroid Build Coastguard Worker    {
517*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Unorm)];
518*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac()) {
519*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kAllFlags;
520*c8dee2aaSAndroid Build Coastguard Worker        } else {
521*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
522*c8dee2aaSAndroid Build Coastguard Worker        }
523*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
524*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
525*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
526*c8dee2aaSAndroid Build Coastguard Worker        // Format: RGBA16Unorm, Surface: kR16G16B16A16_unorm
527*c8dee2aaSAndroid Build Coastguard Worker        {
528*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
529*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kR16G16B16A16_unorm_SkColorType;
530*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
531*c8dee2aaSAndroid Build Coastguard Worker        }
532*c8dee2aaSAndroid Build Coastguard Worker    }
533*c8dee2aaSAndroid Build Coastguard Worker
534*c8dee2aaSAndroid Build Coastguard Worker    // Format: RG16Float
535*c8dee2aaSAndroid Build Coastguard Worker    {
536*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Float)];
537*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kAllFlags;
538*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
539*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
540*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
541*c8dee2aaSAndroid Build Coastguard Worker        // Format: RG16Float, Surface: kR16G16_float
542*c8dee2aaSAndroid Build Coastguard Worker        {
543*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
544*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kR16G16_float_SkColorType;
545*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
546*c8dee2aaSAndroid Build Coastguard Worker        }
547*c8dee2aaSAndroid Build Coastguard Worker    }
548*c8dee2aaSAndroid Build Coastguard Worker
549*c8dee2aaSAndroid Build Coastguard Worker    // Format: R16Unorm
550*c8dee2aaSAndroid Build Coastguard Worker    {
551*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Unorm)];
552*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac()) {
553*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kAllFlags;
554*c8dee2aaSAndroid Build Coastguard Worker        } else {
555*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
556*c8dee2aaSAndroid Build Coastguard Worker        }
557*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
558*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
559*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
560*c8dee2aaSAndroid Build Coastguard Worker        // Format: R16Unorm, Surface: kA16_unorm
561*c8dee2aaSAndroid Build Coastguard Worker        {
562*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
563*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kA16_unorm_SkColorType;
564*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
565*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
566*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
567*c8dee2aaSAndroid Build Coastguard Worker        }
568*c8dee2aaSAndroid Build Coastguard Worker    }
569*c8dee2aaSAndroid Build Coastguard Worker
570*c8dee2aaSAndroid Build Coastguard Worker    // Format: RG16Unorm
571*c8dee2aaSAndroid Build Coastguard Worker    {
572*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Unorm)];
573*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac()) {
574*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kAllFlags;
575*c8dee2aaSAndroid Build Coastguard Worker        } else {
576*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
577*c8dee2aaSAndroid Build Coastguard Worker        }
578*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 1;
579*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
580*c8dee2aaSAndroid Build Coastguard Worker        int ctIdx = 0;
581*c8dee2aaSAndroid Build Coastguard Worker        // Format: RG16Unorm, Surface: kR16G16_unorm
582*c8dee2aaSAndroid Build Coastguard Worker        {
583*c8dee2aaSAndroid Build Coastguard Worker            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
584*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fColorType = kR16G16_unorm_SkColorType;
585*c8dee2aaSAndroid Build Coastguard Worker            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
586*c8dee2aaSAndroid Build Coastguard Worker        }
587*c8dee2aaSAndroid Build Coastguard Worker    }
588*c8dee2aaSAndroid Build Coastguard Worker
589*c8dee2aaSAndroid Build Coastguard Worker    // Format: ETC2_RGB8
590*c8dee2aaSAndroid Build Coastguard Worker    {
591*c8dee2aaSAndroid Build Coastguard Worker        if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
592*c8dee2aaSAndroid Build Coastguard Worker            if (this->isApple()) {
593*c8dee2aaSAndroid Build Coastguard Worker                info = &fFormatTable[GetFormatIndex(MTLPixelFormatETC2_RGB8)];
594*c8dee2aaSAndroid Build Coastguard Worker                info->fFlags = FormatInfo::kTexturable_Flag;
595*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfoCount = 1;
596*c8dee2aaSAndroid Build Coastguard Worker                info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
597*c8dee2aaSAndroid Build Coastguard Worker                int ctIdx = 0;
598*c8dee2aaSAndroid Build Coastguard Worker                // Format: ETC2_RGB8, Surface: kRGB_888x
599*c8dee2aaSAndroid Build Coastguard Worker                {
600*c8dee2aaSAndroid Build Coastguard Worker                    auto& ctInfo = info->fColorTypeInfos[ctIdx++];
601*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fColorType = kRGB_888x_SkColorType;
602*c8dee2aaSAndroid Build Coastguard Worker                    ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
603*c8dee2aaSAndroid Build Coastguard Worker                }
604*c8dee2aaSAndroid Build Coastguard Worker            }
605*c8dee2aaSAndroid Build Coastguard Worker        }
606*c8dee2aaSAndroid Build Coastguard Worker    }
607*c8dee2aaSAndroid Build Coastguard Worker
608*c8dee2aaSAndroid Build Coastguard Worker    // Format: BC1_RGBA
609*c8dee2aaSAndroid Build Coastguard Worker    {
610*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
611*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac()) {
612*c8dee2aaSAndroid Build Coastguard Worker            info = &fFormatTable[GetFormatIndex(MTLPixelFormatBC1_RGBA)];
613*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kTexturable_Flag;
614*c8dee2aaSAndroid Build Coastguard Worker            info->fColorTypeInfoCount = 1;
615*c8dee2aaSAndroid Build Coastguard Worker            info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
616*c8dee2aaSAndroid Build Coastguard Worker            int ctIdx = 0;
617*c8dee2aaSAndroid Build Coastguard Worker            // Format: BC1_RGBA, Surface: kRGBA_8888
618*c8dee2aaSAndroid Build Coastguard Worker            {
619*c8dee2aaSAndroid Build Coastguard Worker                auto& ctInfo = info->fColorTypeInfos[ctIdx++];
620*c8dee2aaSAndroid Build Coastguard Worker                ctInfo.fColorType = kRGBA_8888_SkColorType;
621*c8dee2aaSAndroid Build Coastguard Worker                ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
622*c8dee2aaSAndroid Build Coastguard Worker            }
623*c8dee2aaSAndroid Build Coastguard Worker        }
624*c8dee2aaSAndroid Build Coastguard Worker#endif
625*c8dee2aaSAndroid Build Coastguard Worker    }
626*c8dee2aaSAndroid Build Coastguard Worker
627*c8dee2aaSAndroid Build Coastguard Worker    /*
628*c8dee2aaSAndroid Build Coastguard Worker     * Non-color formats
629*c8dee2aaSAndroid Build Coastguard Worker     */
630*c8dee2aaSAndroid Build Coastguard Worker
631*c8dee2aaSAndroid Build Coastguard Worker    // Format: Stencil8
632*c8dee2aaSAndroid Build Coastguard Worker    {
633*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatStencil8)];
634*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kMSAA_Flag;
635*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 0;
636*c8dee2aaSAndroid Build Coastguard Worker    }
637*c8dee2aaSAndroid Build Coastguard Worker
638*c8dee2aaSAndroid Build Coastguard Worker    // Format: Depth16Unorm
639*c8dee2aaSAndroid Build Coastguard Worker    {
640*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth16Unorm)];
641*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kMSAA_Flag;
642*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac() || fFamilyGroup >= 3) {
643*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags |= FormatInfo::kResolve_Flag;
644*c8dee2aaSAndroid Build Coastguard Worker        }
645*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 0;
646*c8dee2aaSAndroid Build Coastguard Worker    }
647*c8dee2aaSAndroid Build Coastguard Worker
648*c8dee2aaSAndroid Build Coastguard Worker    // Format: Depth32Float
649*c8dee2aaSAndroid Build Coastguard Worker    {
650*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth32Float)];
651*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kMSAA_Flag;
652*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac() || fFamilyGroup >= 3) {
653*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags |= FormatInfo::kResolve_Flag;
654*c8dee2aaSAndroid Build Coastguard Worker        }
655*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 0;
656*c8dee2aaSAndroid Build Coastguard Worker    }
657*c8dee2aaSAndroid Build Coastguard Worker
658*c8dee2aaSAndroid Build Coastguard Worker    // Format: Depth24Unorm_Stencil8
659*c8dee2aaSAndroid Build Coastguard Worker    {
660*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
661*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac() && [device isDepth24Stencil8PixelFormatSupported]) {
662*c8dee2aaSAndroid Build Coastguard Worker            info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth24Unorm_Stencil8)];
663*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags = FormatInfo::kMSAA_Flag | FormatInfo::kResolve_Flag;
664*c8dee2aaSAndroid Build Coastguard Worker            info->fColorTypeInfoCount = 0;
665*c8dee2aaSAndroid Build Coastguard Worker        }
666*c8dee2aaSAndroid Build Coastguard Worker#endif
667*c8dee2aaSAndroid Build Coastguard Worker    }
668*c8dee2aaSAndroid Build Coastguard Worker
669*c8dee2aaSAndroid Build Coastguard Worker    // Format: Depth32Float_Stencil8
670*c8dee2aaSAndroid Build Coastguard Worker    {
671*c8dee2aaSAndroid Build Coastguard Worker        info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth32Float_Stencil8)];
672*c8dee2aaSAndroid Build Coastguard Worker        info->fFlags = FormatInfo::kMSAA_Flag;
673*c8dee2aaSAndroid Build Coastguard Worker        if (this->isMac() || fFamilyGroup >= 3) {
674*c8dee2aaSAndroid Build Coastguard Worker            info->fFlags |= FormatInfo::kResolve_Flag;
675*c8dee2aaSAndroid Build Coastguard Worker        }
676*c8dee2aaSAndroid Build Coastguard Worker        info->fColorTypeInfoCount = 0;
677*c8dee2aaSAndroid Build Coastguard Worker    }
678*c8dee2aaSAndroid Build Coastguard Worker
679*c8dee2aaSAndroid Build Coastguard Worker    ////////////////////////////////////////////////////////////////////////////
680*c8dee2aaSAndroid Build Coastguard Worker    // Map SkColorTypes (used for creating SkSurfaces) to MTLPixelFormats. The order in which the
681*c8dee2aaSAndroid Build Coastguard Worker    // formats are passed into the setColorType function indicates the priority in selecting which
682*c8dee2aaSAndroid Build Coastguard Worker    // format we use for a given SkColorType.
683*c8dee2aaSAndroid Build Coastguard Worker
684*c8dee2aaSAndroid Build Coastguard Worker    std::fill_n(fColorTypeToFormatTable, kSkColorTypeCnt, MTLPixelFormatInvalid);
685*c8dee2aaSAndroid Build Coastguard Worker
686*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kAlpha_8_SkColorType,          { MTLPixelFormatR8Unorm,
687*c8dee2aaSAndroid Build Coastguard Worker                                                        MTLPixelFormatA8Unorm });
688*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
689*c8dee2aaSAndroid Build Coastguard Worker        if (this->isApple()) {
690*c8dee2aaSAndroid Build Coastguard Worker            this->setColorType(kRGB_565_SkColorType,   {MTLPixelFormatB5G6R5Unorm});
691*c8dee2aaSAndroid Build Coastguard Worker            this->setColorType(kARGB_4444_SkColorType, { MTLPixelFormatABGR4Unorm });
692*c8dee2aaSAndroid Build Coastguard Worker        }
693*c8dee2aaSAndroid Build Coastguard Worker    }
694*c8dee2aaSAndroid Build Coastguard Worker
695*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGBA_8888_SkColorType,        { MTLPixelFormatRGBA8Unorm });
696*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGB_888x_SkColorType,         { MTLPixelFormatRGBA8Unorm });
697*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kBGRA_8888_SkColorType,        { MTLPixelFormatBGRA8Unorm });
698*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGBA_1010102_SkColorType,     { MTLPixelFormatRGB10A2Unorm });
699*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGB_101010x_SkColorType,      { MTLPixelFormatRGB10A2Unorm });
700*c8dee2aaSAndroid Build Coastguard Worker    // kBGRA_1010102_SkColorType
701*c8dee2aaSAndroid Build Coastguard Worker    // kBGR_101010x_SkColorType
702*c8dee2aaSAndroid Build Coastguard Worker    // kBGR_101010x_XR_SkColorType
703*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kGray_8_SkColorType,           { MTLPixelFormatR8Unorm });
704*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGBA_F16Norm_SkColorType,     { MTLPixelFormatRGBA16Float });
705*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGBA_F16_SkColorType,         { MTLPixelFormatRGBA16Float });
706*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kRGB_F16F16F16x_SkColorType,   { MTLPixelFormatRGBA16Float });
707*c8dee2aaSAndroid Build Coastguard Worker    // kRGBA_F32_SkColorType
708*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kR8G8_unorm_SkColorType,       { MTLPixelFormatRG8Unorm });
709*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kA16_float_SkColorType,        { MTLPixelFormatR16Float });
710*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kR16G16_float_SkColorType,     { MTLPixelFormatRG16Float });
711*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kA16_unorm_SkColorType,        { MTLPixelFormatR16Unorm });
712*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kR16G16_unorm_SkColorType,     { MTLPixelFormatRG16Unorm });
713*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kR16G16B16A16_unorm_SkColorType,{ MTLPixelFormatRGBA16Unorm });
714*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kSRGBA_8888_SkColorType,       { MTLPixelFormatRGBA8Unorm_sRGB });
715*c8dee2aaSAndroid Build Coastguard Worker    this->setColorType(kR8_unorm_SkColorType,         { MTLPixelFormatR8Unorm });
716*c8dee2aaSAndroid Build Coastguard Worker
717*c8dee2aaSAndroid Build Coastguard Worker}
718*c8dee2aaSAndroid Build Coastguard Worker
719*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getDefaultSampledTextureInfo(SkColorType colorType,
720*c8dee2aaSAndroid Build Coastguard Worker                                                  Mipmapped mipmapped,
721*c8dee2aaSAndroid Build Coastguard Worker                                                  Protected,
722*c8dee2aaSAndroid Build Coastguard Worker                                                  Renderable renderable) const {
723*c8dee2aaSAndroid Build Coastguard Worker    MTLTextureUsage usage = MTLTextureUsageShaderRead;
724*c8dee2aaSAndroid Build Coastguard Worker    if (renderable == Renderable::kYes) {
725*c8dee2aaSAndroid Build Coastguard Worker        usage |= MTLTextureUsageRenderTarget;
726*c8dee2aaSAndroid Build Coastguard Worker    }
727*c8dee2aaSAndroid Build Coastguard Worker
728*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat format = this->getFormatFromColorType(colorType);
729*c8dee2aaSAndroid Build Coastguard Worker    if (format == MTLPixelFormatInvalid) {
730*c8dee2aaSAndroid Build Coastguard Worker        return {};
731*c8dee2aaSAndroid Build Coastguard Worker    }
732*c8dee2aaSAndroid Build Coastguard Worker
733*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
734*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = 1;
735*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = mipmapped;
736*c8dee2aaSAndroid Build Coastguard Worker    info.fFormat = format;
737*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = usage;
738*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = MTLStorageModePrivate;
739*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
740*c8dee2aaSAndroid Build Coastguard Worker
741*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
742*c8dee2aaSAndroid Build Coastguard Worker}
743*c8dee2aaSAndroid Build Coastguard Worker
744*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getTextureInfoForSampledCopy(const TextureInfo& textureInfo,
745*c8dee2aaSAndroid Build Coastguard Worker                                                  Mipmapped mipmapped) const {
746*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
747*c8dee2aaSAndroid Build Coastguard Worker    if (!TextureInfos::GetMtlTextureInfo(textureInfo, &info)) {
748*c8dee2aaSAndroid Build Coastguard Worker        return {};
749*c8dee2aaSAndroid Build Coastguard Worker    }
750*c8dee2aaSAndroid Build Coastguard Worker
751*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = 1;
752*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = mipmapped;
753*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = MTLTextureUsageShaderRead;
754*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = MTLStorageModePrivate;
755*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
756*c8dee2aaSAndroid Build Coastguard Worker
757*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
758*c8dee2aaSAndroid Build Coastguard Worker}
759*c8dee2aaSAndroid Build Coastguard Worker
760*c8dee2aaSAndroid Build Coastguard Workernamespace {
761*c8dee2aaSAndroid Build Coastguard Worker
762*c8dee2aaSAndroid Build Coastguard Workerskgpu::UniqueKey::Domain get_domain() {
763*c8dee2aaSAndroid Build Coastguard Worker    static const skgpu::UniqueKey::Domain kMtlGraphicsPipelineDomain =
764*c8dee2aaSAndroid Build Coastguard Worker            skgpu::UniqueKey::GenerateDomain();
765*c8dee2aaSAndroid Build Coastguard Worker
766*c8dee2aaSAndroid Build Coastguard Worker    return kMtlGraphicsPipelineDomain;
767*c8dee2aaSAndroid Build Coastguard Worker}
768*c8dee2aaSAndroid Build Coastguard Worker
769*c8dee2aaSAndroid Build Coastguard WorkerMTLPixelFormat format_from_compression(SkTextureCompressionType compression) {
770*c8dee2aaSAndroid Build Coastguard Worker    switch (compression) {
771*c8dee2aaSAndroid Build Coastguard Worker        case SkTextureCompressionType::kETC2_RGB8_UNORM:
772*c8dee2aaSAndroid Build Coastguard Worker            return kMTLPixelFormatETC2_RGB8;
773*c8dee2aaSAndroid Build Coastguard Worker        case SkTextureCompressionType::kBC1_RGBA8_UNORM:
774*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
775*c8dee2aaSAndroid Build Coastguard Worker            return MTLPixelFormatBC1_RGBA;
776*c8dee2aaSAndroid Build Coastguard Worker#endif
777*c8dee2aaSAndroid Build Coastguard Worker        default:
778*c8dee2aaSAndroid Build Coastguard Worker            return MTLPixelFormatInvalid;
779*c8dee2aaSAndroid Build Coastguard Worker    }
780*c8dee2aaSAndroid Build Coastguard Worker}
781*c8dee2aaSAndroid Build Coastguard Worker}
782*c8dee2aaSAndroid Build Coastguard Worker
783*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getDefaultCompressedTextureInfo(SkTextureCompressionType compression,
784*c8dee2aaSAndroid Build Coastguard Worker                                                     Mipmapped mipmapped,
785*c8dee2aaSAndroid Build Coastguard Worker                                                     Protected) const {
786*c8dee2aaSAndroid Build Coastguard Worker    MTLTextureUsage usage = MTLTextureUsageShaderRead;
787*c8dee2aaSAndroid Build Coastguard Worker
788*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat format = format_from_compression(compression);
789*c8dee2aaSAndroid Build Coastguard Worker    if (format == MTLPixelFormatInvalid) {
790*c8dee2aaSAndroid Build Coastguard Worker        return {};
791*c8dee2aaSAndroid Build Coastguard Worker    }
792*c8dee2aaSAndroid Build Coastguard Worker
793*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
794*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = 1;
795*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = mipmapped;
796*c8dee2aaSAndroid Build Coastguard Worker    info.fFormat = format;
797*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = usage;
798*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = MTLStorageModePrivate;
799*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
800*c8dee2aaSAndroid Build Coastguard Worker
801*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
802*c8dee2aaSAndroid Build Coastguard Worker}
803*c8dee2aaSAndroid Build Coastguard Worker
804*c8dee2aaSAndroid Build Coastguard WorkerMTLStorageMode MtlCaps::getDefaultMSAAStorageMode(Discardable discardable) const {
805*c8dee2aaSAndroid Build Coastguard Worker    // Try to use memoryless if it's available (only on new Apple silicon)
806*c8dee2aaSAndroid Build Coastguard Worker    if (discardable == Discardable::kYes && this->isApple()) {
807*c8dee2aaSAndroid Build Coastguard Worker        if (@available(macOS 11.0, iOS 10.0, tvOS 10.0, *)) {
808*c8dee2aaSAndroid Build Coastguard Worker            return MTLStorageModeMemoryless;
809*c8dee2aaSAndroid Build Coastguard Worker        }
810*c8dee2aaSAndroid Build Coastguard Worker    }
811*c8dee2aaSAndroid Build Coastguard Worker    // If it's not discardable or not available, private is the best option
812*c8dee2aaSAndroid Build Coastguard Worker    return MTLStorageModePrivate;
813*c8dee2aaSAndroid Build Coastguard Worker}
814*c8dee2aaSAndroid Build Coastguard Worker
815*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
816*c8dee2aaSAndroid Build Coastguard Worker                                               Discardable discardable) const {
817*c8dee2aaSAndroid Build Coastguard Worker    if (fDefaultMSAASamples <= 1) {
818*c8dee2aaSAndroid Build Coastguard Worker        return {};
819*c8dee2aaSAndroid Build Coastguard Worker    }
820*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat format = TextureInfos::GetMTLPixelFormat(singleSampledInfo);
821*c8dee2aaSAndroid Build Coastguard Worker    if (!this->isRenderable(format, fDefaultMSAASamples)) {
822*c8dee2aaSAndroid Build Coastguard Worker        return {};
823*c8dee2aaSAndroid Build Coastguard Worker    }
824*c8dee2aaSAndroid Build Coastguard Worker
825*c8dee2aaSAndroid Build Coastguard Worker    MTLTextureUsage usage = MTLTextureUsageRenderTarget;
826*c8dee2aaSAndroid Build Coastguard Worker
827*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
828*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = fDefaultMSAASamples;
829*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = Mipmapped::kNo;
830*c8dee2aaSAndroid Build Coastguard Worker    info.fFormat = format;
831*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = usage;
832*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = this->getDefaultMSAAStorageMode(discardable);
833*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
834*c8dee2aaSAndroid Build Coastguard Worker
835*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
836*c8dee2aaSAndroid Build Coastguard Worker}
837*c8dee2aaSAndroid Build Coastguard Worker
838*c8dee2aaSAndroid Build Coastguard WorkerMTLPixelFormat MtlCaps::getFormatFromDepthStencilFlags(
839*c8dee2aaSAndroid Build Coastguard Worker        SkEnumBitMask<DepthStencilFlags> mask) const {
840*c8dee2aaSAndroid Build Coastguard Worker    // TODO: Decide if we want to change this to always return a combined depth and stencil format
841*c8dee2aaSAndroid Build Coastguard Worker    // to allow more sharing of depth stencil allocations.
842*c8dee2aaSAndroid Build Coastguard Worker    if (mask == DepthStencilFlags::kDepth) {
843*c8dee2aaSAndroid Build Coastguard Worker        // Graphite only needs 16-bits for depth values, so save some memory. If needed for
844*c8dee2aaSAndroid Build Coastguard Worker        // workarounds, MTLPixelFormatDepth32Float is also available.
845*c8dee2aaSAndroid Build Coastguard Worker        return MTLPixelFormatDepth16Unorm;
846*c8dee2aaSAndroid Build Coastguard Worker    } else if (mask == DepthStencilFlags::kStencil) {
847*c8dee2aaSAndroid Build Coastguard Worker        return MTLPixelFormatStencil8;
848*c8dee2aaSAndroid Build Coastguard Worker    } else if (mask == DepthStencilFlags::kDepthStencil) {
849*c8dee2aaSAndroid Build Coastguard Worker#if defined(SK_BUILD_FOR_MAC)
850*c8dee2aaSAndroid Build Coastguard Worker        if (SkToBool(this->getFormatInfo(MTLPixelFormatDepth24Unorm_Stencil8).fFlags)) {
851*c8dee2aaSAndroid Build Coastguard Worker            return MTLPixelFormatDepth24Unorm_Stencil8;
852*c8dee2aaSAndroid Build Coastguard Worker        }
853*c8dee2aaSAndroid Build Coastguard Worker#endif
854*c8dee2aaSAndroid Build Coastguard Worker        return MTLPixelFormatDepth32Float_Stencil8;
855*c8dee2aaSAndroid Build Coastguard Worker    }
856*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(false);
857*c8dee2aaSAndroid Build Coastguard Worker    return MTLPixelFormatInvalid;
858*c8dee2aaSAndroid Build Coastguard Worker}
859*c8dee2aaSAndroid Build Coastguard Worker
860*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getDefaultDepthStencilTextureInfo(
861*c8dee2aaSAndroid Build Coastguard Worker            SkEnumBitMask<DepthStencilFlags> depthStencilType,
862*c8dee2aaSAndroid Build Coastguard Worker            uint32_t sampleCount,
863*c8dee2aaSAndroid Build Coastguard Worker            Protected) const {
864*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
865*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = sampleCount;
866*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = Mipmapped::kNo;
867*c8dee2aaSAndroid Build Coastguard Worker    info.fFormat = this->getFormatFromDepthStencilFlags(depthStencilType);
868*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = MTLTextureUsageRenderTarget;
869*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = this->getDefaultMSAAStorageMode(Discardable::kYes);
870*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
871*c8dee2aaSAndroid Build Coastguard Worker
872*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
873*c8dee2aaSAndroid Build Coastguard Worker}
874*c8dee2aaSAndroid Build Coastguard Worker
875*c8dee2aaSAndroid Build Coastguard WorkerTextureInfo MtlCaps::getDefaultStorageTextureInfo(SkColorType colorType) const {
876*c8dee2aaSAndroid Build Coastguard Worker    // Storage textures are currently always sampleable from a shader.
877*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat format = static_cast<MTLPixelFormat>(this->getFormatFromColorType(colorType));
878*c8dee2aaSAndroid Build Coastguard Worker    if (format == MTLPixelFormatInvalid) {
879*c8dee2aaSAndroid Build Coastguard Worker        return {};
880*c8dee2aaSAndroid Build Coastguard Worker    }
881*c8dee2aaSAndroid Build Coastguard Worker
882*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& formatInfo = this->getFormatInfo(format);
883*c8dee2aaSAndroid Build Coastguard Worker    if (!SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags)) {
884*c8dee2aaSAndroid Build Coastguard Worker        return {};
885*c8dee2aaSAndroid Build Coastguard Worker    }
886*c8dee2aaSAndroid Build Coastguard Worker
887*c8dee2aaSAndroid Build Coastguard Worker    MTLTextureUsage usage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead;
888*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo info;
889*c8dee2aaSAndroid Build Coastguard Worker    info.fSampleCount = 1;
890*c8dee2aaSAndroid Build Coastguard Worker    info.fMipmapped = Mipmapped::kNo;
891*c8dee2aaSAndroid Build Coastguard Worker    info.fFormat = format;
892*c8dee2aaSAndroid Build Coastguard Worker    info.fUsage = usage;
893*c8dee2aaSAndroid Build Coastguard Worker    info.fStorageMode = MTLStorageModePrivate;
894*c8dee2aaSAndroid Build Coastguard Worker    info.fFramebufferOnly = false;
895*c8dee2aaSAndroid Build Coastguard Worker
896*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfos::MakeMetal(info);
897*c8dee2aaSAndroid Build Coastguard Worker}
898*c8dee2aaSAndroid Build Coastguard Worker
899*c8dee2aaSAndroid Build Coastguard Workerconst Caps::ColorTypeInfo* MtlCaps::getColorTypeInfo(
900*c8dee2aaSAndroid Build Coastguard Worker        SkColorType ct, const TextureInfo& textureInfo) const {
901*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat mtlFormat = TextureInfos::GetMTLPixelFormat(textureInfo);
902*c8dee2aaSAndroid Build Coastguard Worker    if (mtlFormat == MTLPixelFormatInvalid) {
903*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
904*c8dee2aaSAndroid Build Coastguard Worker    }
905*c8dee2aaSAndroid Build Coastguard Worker
906*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& info = this->getFormatInfo(mtlFormat);
907*c8dee2aaSAndroid Build Coastguard Worker    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
908*c8dee2aaSAndroid Build Coastguard Worker        const ColorTypeInfo& ctInfo = info.fColorTypeInfos[i];
909*c8dee2aaSAndroid Build Coastguard Worker        if (ctInfo.fColorType == ct) {
910*c8dee2aaSAndroid Build Coastguard Worker            return &ctInfo;
911*c8dee2aaSAndroid Build Coastguard Worker        }
912*c8dee2aaSAndroid Build Coastguard Worker    }
913*c8dee2aaSAndroid Build Coastguard Worker
914*c8dee2aaSAndroid Build Coastguard Worker    return nullptr;
915*c8dee2aaSAndroid Build Coastguard Worker}
916*c8dee2aaSAndroid Build Coastguard Worker
917*c8dee2aaSAndroid Build Coastguard Workerstatic const int kMtlGraphicsPipelineKeyData32Count = 5;
918*c8dee2aaSAndroid Build Coastguard Worker
919*c8dee2aaSAndroid Build Coastguard WorkerUniqueKey MtlCaps::makeGraphicsPipelineKey(const GraphicsPipelineDesc& pipelineDesc,
920*c8dee2aaSAndroid Build Coastguard Worker                                           const RenderPassDesc& renderPassDesc) const {
921*c8dee2aaSAndroid Build Coastguard Worker    UniqueKey pipelineKey;
922*c8dee2aaSAndroid Build Coastguard Worker    {
923*c8dee2aaSAndroid Build Coastguard Worker        // 5 uint32_t's (render step id, paint id, uint64 renderpass desc, uint16 write swizzle key)
924*c8dee2aaSAndroid Build Coastguard Worker        UniqueKey::Builder builder(&pipelineKey, get_domain(),
925*c8dee2aaSAndroid Build Coastguard Worker                                   kMtlGraphicsPipelineKeyData32Count, "MtlGraphicsPipeline");
926*c8dee2aaSAndroid Build Coastguard Worker        // add GraphicsPipelineDesc key
927*c8dee2aaSAndroid Build Coastguard Worker        builder[0] = pipelineDesc.renderStepID();
928*c8dee2aaSAndroid Build Coastguard Worker        builder[1] = pipelineDesc.paintParamsID().asUInt();
929*c8dee2aaSAndroid Build Coastguard Worker
930*c8dee2aaSAndroid Build Coastguard Worker        // add RenderPassDesc key
931*c8dee2aaSAndroid Build Coastguard Worker        uint64_t renderPassKey = this->getRenderPassDescKey(renderPassDesc);
932*c8dee2aaSAndroid Build Coastguard Worker        builder[2] = renderPassKey & 0xFFFFFFFF;
933*c8dee2aaSAndroid Build Coastguard Worker        builder[3] = (renderPassKey >> 32) & 0xFFFFFFFF;
934*c8dee2aaSAndroid Build Coastguard Worker        builder[4] = renderPassDesc.fWriteSwizzle.asKey();
935*c8dee2aaSAndroid Build Coastguard Worker
936*c8dee2aaSAndroid Build Coastguard Worker        builder.finish();
937*c8dee2aaSAndroid Build Coastguard Worker    }
938*c8dee2aaSAndroid Build Coastguard Worker
939*c8dee2aaSAndroid Build Coastguard Worker    return pipelineKey;
940*c8dee2aaSAndroid Build Coastguard Worker}
941*c8dee2aaSAndroid Build Coastguard Worker
942*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::extractGraphicsDescs(const UniqueKey& key,
943*c8dee2aaSAndroid Build Coastguard Worker                                   GraphicsPipelineDesc* pipelineDesc,
944*c8dee2aaSAndroid Build Coastguard Worker                                   RenderPassDesc* renderPassDesc,
945*c8dee2aaSAndroid Build Coastguard Worker                                   const RendererProvider* rendererProvider) const {
946*c8dee2aaSAndroid Build Coastguard Worker    struct UnpackedKeyData {
947*c8dee2aaSAndroid Build Coastguard Worker        // From the GraphicsPipelineDesc
948*c8dee2aaSAndroid Build Coastguard Worker        uint32_t fRenderStepID = 0;
949*c8dee2aaSAndroid Build Coastguard Worker        UniquePaintParamsID fPaintParamsID;
950*c8dee2aaSAndroid Build Coastguard Worker
951*c8dee2aaSAndroid Build Coastguard Worker        // From the RenderPassDesc
952*c8dee2aaSAndroid Build Coastguard Worker        MTLPixelFormat fColorFormat = MTLPixelFormatInvalid;
953*c8dee2aaSAndroid Build Coastguard Worker        uint32_t fColorSampleCount = 1;
954*c8dee2aaSAndroid Build Coastguard Worker
955*c8dee2aaSAndroid Build Coastguard Worker        MTLPixelFormat fDSFormat = MTLPixelFormatInvalid;
956*c8dee2aaSAndroid Build Coastguard Worker        uint32_t fDSSampleCount = 1;
957*c8dee2aaSAndroid Build Coastguard Worker
958*c8dee2aaSAndroid Build Coastguard Worker        Swizzle fWriteSwizzle;
959*c8dee2aaSAndroid Build Coastguard Worker    } keyData;
960*c8dee2aaSAndroid Build Coastguard Worker
961*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(key.domain() == get_domain());
962*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(key.dataSize() == 4 * kMtlGraphicsPipelineKeyData32Count);
963*c8dee2aaSAndroid Build Coastguard Worker
964*c8dee2aaSAndroid Build Coastguard Worker    const uint32_t* rawKeyData = key.data();
965*c8dee2aaSAndroid Build Coastguard Worker
966*c8dee2aaSAndroid Build Coastguard Worker    keyData.fRenderStepID = rawKeyData[0];
967*c8dee2aaSAndroid Build Coastguard Worker    keyData.fPaintParamsID = rawKeyData[1] ? UniquePaintParamsID(rawKeyData[1])
968*c8dee2aaSAndroid Build Coastguard Worker                                           : UniquePaintParamsID::InvalidID();
969*c8dee2aaSAndroid Build Coastguard Worker
970*c8dee2aaSAndroid Build Coastguard Worker    keyData.fDSFormat = static_cast<MTLPixelFormat>((rawKeyData[2] >> 16) & 0xFFFF);
971*c8dee2aaSAndroid Build Coastguard Worker    keyData.fDSSampleCount = rawKeyData[2] & 0xFFFF;
972*c8dee2aaSAndroid Build Coastguard Worker
973*c8dee2aaSAndroid Build Coastguard Worker    keyData.fColorFormat = static_cast<MTLPixelFormat>((rawKeyData[3] >> 16) & 0xFFFF);
974*c8dee2aaSAndroid Build Coastguard Worker    keyData.fColorSampleCount = rawKeyData[3] & 0xFFFF;
975*c8dee2aaSAndroid Build Coastguard Worker
976*c8dee2aaSAndroid Build Coastguard Worker    keyData.fWriteSwizzle = SwizzleCtorAccessor::Make(rawKeyData[4]);
977*c8dee2aaSAndroid Build Coastguard Worker
978*c8dee2aaSAndroid Build Coastguard Worker    // Recreate the RenderPassDesc
979*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(keyData.fColorSampleCount == keyData.fDSSampleCount);
980*c8dee2aaSAndroid Build Coastguard Worker
981*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat dsFormat = keyData.fDSFormat;
982*c8dee2aaSAndroid Build Coastguard Worker    SkEnumBitMask<DepthStencilFlags> dsFlags = DepthStencilFlags::kNone;
983*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsDepth(dsFormat)) {
984*c8dee2aaSAndroid Build Coastguard Worker        dsFlags |= DepthStencilFlags::kDepth;
985*c8dee2aaSAndroid Build Coastguard Worker    }
986*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsStencil(dsFormat)) {
987*c8dee2aaSAndroid Build Coastguard Worker        dsFlags |= DepthStencilFlags::kStencil;
988*c8dee2aaSAndroid Build Coastguard Worker    }
989*c8dee2aaSAndroid Build Coastguard Worker
990*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo mtlInfo(keyData.fColorSampleCount,
991*c8dee2aaSAndroid Build Coastguard Worker                           skgpu::Mipmapped::kNo,
992*c8dee2aaSAndroid Build Coastguard Worker                           keyData.fColorFormat,
993*c8dee2aaSAndroid Build Coastguard Worker                           MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget,
994*c8dee2aaSAndroid Build Coastguard Worker                           MTLStorageModePrivate,
995*c8dee2aaSAndroid Build Coastguard Worker                           /* framebufferOnly= */ false);
996*c8dee2aaSAndroid Build Coastguard Worker    TextureInfo info = TextureInfos::MakeMetal(mtlInfo);
997*c8dee2aaSAndroid Build Coastguard Worker
998*c8dee2aaSAndroid Build Coastguard Worker    *renderPassDesc = RenderPassDesc::Make(this,
999*c8dee2aaSAndroid Build Coastguard Worker                                           info,
1000*c8dee2aaSAndroid Build Coastguard Worker                                           LoadOp::kClear,
1001*c8dee2aaSAndroid Build Coastguard Worker                                           StoreOp::kStore,
1002*c8dee2aaSAndroid Build Coastguard Worker                                           dsFlags,
1003*c8dee2aaSAndroid Build Coastguard Worker                                           /* clearColor= */ { .0f, .0f, .0f, .0f },
1004*c8dee2aaSAndroid Build Coastguard Worker                                           /* requiresMSAA= */ keyData.fColorSampleCount > 1,
1005*c8dee2aaSAndroid Build Coastguard Worker                                           keyData.fWriteSwizzle);
1006*c8dee2aaSAndroid Build Coastguard Worker
1007*c8dee2aaSAndroid Build Coastguard Worker    // Recreate the GraphicsPipelineDesc
1008*c8dee2aaSAndroid Build Coastguard Worker    const RenderStep* renderStep = rendererProvider->lookup(keyData.fRenderStepID);
1009*c8dee2aaSAndroid Build Coastguard Worker
1010*c8dee2aaSAndroid Build Coastguard Worker    UniquePaintParamsID paintID = renderStep->performsShading() ? keyData.fPaintParamsID
1011*c8dee2aaSAndroid Build Coastguard Worker                                                                : UniquePaintParamsID::InvalidID();
1012*c8dee2aaSAndroid Build Coastguard Worker
1013*c8dee2aaSAndroid Build Coastguard Worker    *pipelineDesc = GraphicsPipelineDesc(renderStep, paintID);
1014*c8dee2aaSAndroid Build Coastguard Worker
1015*c8dee2aaSAndroid Build Coastguard Worker    return true;
1016*c8dee2aaSAndroid Build Coastguard Worker}
1017*c8dee2aaSAndroid Build Coastguard Worker
1018*c8dee2aaSAndroid Build Coastguard Workeruint64_t MtlCaps::getRenderPassDescKey(const RenderPassDesc& renderPassDesc) const {
1019*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo colorInfo, depthStencilInfo;
1020*c8dee2aaSAndroid Build Coastguard Worker    SkAssertResult(TextureInfos::GetMtlTextureInfo(renderPassDesc.fColorAttachment.fTextureInfo,
1021*c8dee2aaSAndroid Build Coastguard Worker                                                   &colorInfo));
1022*c8dee2aaSAndroid Build Coastguard Worker    SkAssertResult(TextureInfos::GetMtlTextureInfo(
1023*c8dee2aaSAndroid Build Coastguard Worker            renderPassDesc.fDepthStencilAttachment.fTextureInfo, &depthStencilInfo));
1024*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(colorInfo.fFormat < 65535 && depthStencilInfo.fFormat < 65535);
1025*c8dee2aaSAndroid Build Coastguard Worker    uint32_t colorAttachmentKey = colorInfo.fFormat << 16 | colorInfo.fSampleCount;
1026*c8dee2aaSAndroid Build Coastguard Worker    uint32_t dsAttachmentKey = depthStencilInfo.fFormat << 16 | depthStencilInfo.fSampleCount;
1027*c8dee2aaSAndroid Build Coastguard Worker    return (((uint64_t) colorAttachmentKey) << 32) | dsAttachmentKey;
1028*c8dee2aaSAndroid Build Coastguard Worker}
1029*c8dee2aaSAndroid Build Coastguard Worker
1030*c8dee2aaSAndroid Build Coastguard WorkerUniqueKey MtlCaps::makeComputePipelineKey(const ComputePipelineDesc& pipelineDesc) const {
1031*c8dee2aaSAndroid Build Coastguard Worker    UniqueKey pipelineKey;
1032*c8dee2aaSAndroid Build Coastguard Worker    {
1033*c8dee2aaSAndroid Build Coastguard Worker        static const skgpu::UniqueKey::Domain kComputePipelineDomain = UniqueKey::GenerateDomain();
1034*c8dee2aaSAndroid Build Coastguard Worker        // The key is made up of a single uint32_t corresponding to the compute step ID.
1035*c8dee2aaSAndroid Build Coastguard Worker        UniqueKey::Builder builder(&pipelineKey, kComputePipelineDomain, 1, "ComputePipeline");
1036*c8dee2aaSAndroid Build Coastguard Worker        builder[0] = pipelineDesc.computeStep()->uniqueID();
1037*c8dee2aaSAndroid Build Coastguard Worker
1038*c8dee2aaSAndroid Build Coastguard Worker        // TODO(b/240615224): The local work group size should factor into the key on platforms
1039*c8dee2aaSAndroid Build Coastguard Worker        // that don't support specialization constants and require the workgroup/threadgroup size to
1040*c8dee2aaSAndroid Build Coastguard Worker        // be specified in the shader text (D3D12, Vulkan 1.0, and OpenGL).
1041*c8dee2aaSAndroid Build Coastguard Worker
1042*c8dee2aaSAndroid Build Coastguard Worker        builder.finish();
1043*c8dee2aaSAndroid Build Coastguard Worker    }
1044*c8dee2aaSAndroid Build Coastguard Worker    return pipelineKey;
1045*c8dee2aaSAndroid Build Coastguard Worker}
1046*c8dee2aaSAndroid Build Coastguard Worker
1047*c8dee2aaSAndroid Build Coastguard Workeruint32_t MtlCaps::channelMask(const TextureInfo& info) const {
1048*c8dee2aaSAndroid Build Coastguard Worker    return skgpu::MtlFormatChannels(TextureInfos::GetMTLPixelFormat(info));
1049*c8dee2aaSAndroid Build Coastguard Worker}
1050*c8dee2aaSAndroid Build Coastguard Worker
1051*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::onIsTexturable(const TextureInfo& info) const {
1052*c8dee2aaSAndroid Build Coastguard Worker    if (!info.isValid()) {
1053*c8dee2aaSAndroid Build Coastguard Worker        return false;
1054*c8dee2aaSAndroid Build Coastguard Worker    }
1055*c8dee2aaSAndroid Build Coastguard Worker    if (!(TextureInfos::GetMTLTextureUsage(info) & MTLTextureUsageShaderRead)) {
1056*c8dee2aaSAndroid Build Coastguard Worker        return false;
1057*c8dee2aaSAndroid Build Coastguard Worker    }
1058*c8dee2aaSAndroid Build Coastguard Worker    if (TextureInfos::GetMtlFramebufferOnly(info)) {
1059*c8dee2aaSAndroid Build Coastguard Worker        return false;
1060*c8dee2aaSAndroid Build Coastguard Worker    }
1061*c8dee2aaSAndroid Build Coastguard Worker    return this->isTexturable(TextureInfos::GetMTLPixelFormat(info));
1062*c8dee2aaSAndroid Build Coastguard Worker}
1063*c8dee2aaSAndroid Build Coastguard Worker
1064*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::isTexturable(MTLPixelFormat format) const {
1065*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& formatInfo = this->getFormatInfo(format);
1066*c8dee2aaSAndroid Build Coastguard Worker    return SkToBool(FormatInfo::kTexturable_Flag & formatInfo.fFlags);
1067*c8dee2aaSAndroid Build Coastguard Worker}
1068*c8dee2aaSAndroid Build Coastguard Worker
1069*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::isRenderable(const TextureInfo& info) const {
1070*c8dee2aaSAndroid Build Coastguard Worker    return info.isValid() &&
1071*c8dee2aaSAndroid Build Coastguard Worker           (TextureInfos::GetMTLTextureUsage(info) & MTLTextureUsageRenderTarget) &&
1072*c8dee2aaSAndroid Build Coastguard Worker           this->isRenderable(TextureInfos::GetMTLPixelFormat(info), info.numSamples());
1073*c8dee2aaSAndroid Build Coastguard Worker}
1074*c8dee2aaSAndroid Build Coastguard Worker
1075*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::isRenderable(MTLPixelFormat format, uint32_t sampleCount) const {
1076*c8dee2aaSAndroid Build Coastguard Worker    return sampleCount <= this->maxRenderTargetSampleCount(format);
1077*c8dee2aaSAndroid Build Coastguard Worker}
1078*c8dee2aaSAndroid Build Coastguard Worker
1079*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::isStorage(const TextureInfo& info) const {
1080*c8dee2aaSAndroid Build Coastguard Worker    if (!info.isValid()) {
1081*c8dee2aaSAndroid Build Coastguard Worker        return false;
1082*c8dee2aaSAndroid Build Coastguard Worker    }
1083*c8dee2aaSAndroid Build Coastguard Worker    if (!(TextureInfos::GetMTLTextureUsage(info) & MTLTextureUsageShaderWrite)) {
1084*c8dee2aaSAndroid Build Coastguard Worker        return false;
1085*c8dee2aaSAndroid Build Coastguard Worker    }
1086*c8dee2aaSAndroid Build Coastguard Worker    if (TextureInfos::GetMtlFramebufferOnly(info)) {
1087*c8dee2aaSAndroid Build Coastguard Worker        return false;
1088*c8dee2aaSAndroid Build Coastguard Worker    }
1089*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& formatInfo = this->getFormatInfo(TextureInfos::GetMTLPixelFormat(info));
1090*c8dee2aaSAndroid Build Coastguard Worker    return info.numSamples() == 1 && SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags);
1091*c8dee2aaSAndroid Build Coastguard Worker}
1092*c8dee2aaSAndroid Build Coastguard Worker
1093*c8dee2aaSAndroid Build Coastguard Workeruint32_t MtlCaps::maxRenderTargetSampleCount(MTLPixelFormat format) const {
1094*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& formatInfo = this->getFormatInfo(format);
1095*c8dee2aaSAndroid Build Coastguard Worker    if (!SkToBool(formatInfo.fFlags & FormatInfo::kRenderable_Flag)) {
1096*c8dee2aaSAndroid Build Coastguard Worker        return 0;
1097*c8dee2aaSAndroid Build Coastguard Worker    }
1098*c8dee2aaSAndroid Build Coastguard Worker    if (SkToBool(formatInfo.fFlags & FormatInfo::kMSAA_Flag)) {
1099*c8dee2aaSAndroid Build Coastguard Worker        return fColorSampleCounts[fColorSampleCounts.size() - 1];
1100*c8dee2aaSAndroid Build Coastguard Worker    } else {
1101*c8dee2aaSAndroid Build Coastguard Worker        return 1;
1102*c8dee2aaSAndroid Build Coastguard Worker    }
1103*c8dee2aaSAndroid Build Coastguard Worker}
1104*c8dee2aaSAndroid Build Coastguard Worker
1105*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::supportsWritePixels(const TextureInfo& texInfo) const {
1106*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo mtlInfo;
1107*c8dee2aaSAndroid Build Coastguard Worker    if (!TextureInfos::GetMtlTextureInfo(texInfo, &mtlInfo)) {
1108*c8dee2aaSAndroid Build Coastguard Worker        return false;
1109*c8dee2aaSAndroid Build Coastguard Worker    }
1110*c8dee2aaSAndroid Build Coastguard Worker    if (mtlInfo.fFramebufferOnly) {
1111*c8dee2aaSAndroid Build Coastguard Worker        return false;
1112*c8dee2aaSAndroid Build Coastguard Worker    }
1113*c8dee2aaSAndroid Build Coastguard Worker
1114*c8dee2aaSAndroid Build Coastguard Worker    if (texInfo.numSamples() > 1) {
1115*c8dee2aaSAndroid Build Coastguard Worker        return false;
1116*c8dee2aaSAndroid Build Coastguard Worker    }
1117*c8dee2aaSAndroid Build Coastguard Worker
1118*c8dee2aaSAndroid Build Coastguard Worker    return true;
1119*c8dee2aaSAndroid Build Coastguard Worker}
1120*c8dee2aaSAndroid Build Coastguard Worker
1121*c8dee2aaSAndroid Build Coastguard Workerbool MtlCaps::supportsReadPixels(const TextureInfo& texInfo) const {
1122*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo mtlInfo;
1123*c8dee2aaSAndroid Build Coastguard Worker    if (!TextureInfos::GetMtlTextureInfo(texInfo, &mtlInfo)) {
1124*c8dee2aaSAndroid Build Coastguard Worker        return false;
1125*c8dee2aaSAndroid Build Coastguard Worker    }
1126*c8dee2aaSAndroid Build Coastguard Worker    if (mtlInfo.fFramebufferOnly) {
1127*c8dee2aaSAndroid Build Coastguard Worker        return false;
1128*c8dee2aaSAndroid Build Coastguard Worker    }
1129*c8dee2aaSAndroid Build Coastguard Worker
1130*c8dee2aaSAndroid Build Coastguard Worker    // We disallow reading back directly from compressed textures.
1131*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsCompressed(mtlInfo.fFormat)) {
1132*c8dee2aaSAndroid Build Coastguard Worker        return false;
1133*c8dee2aaSAndroid Build Coastguard Worker    }
1134*c8dee2aaSAndroid Build Coastguard Worker
1135*c8dee2aaSAndroid Build Coastguard Worker    if (texInfo.numSamples() > 1) {
1136*c8dee2aaSAndroid Build Coastguard Worker        return false;
1137*c8dee2aaSAndroid Build Coastguard Worker    }
1138*c8dee2aaSAndroid Build Coastguard Worker
1139*c8dee2aaSAndroid Build Coastguard Worker    return true;
1140*c8dee2aaSAndroid Build Coastguard Worker}
1141*c8dee2aaSAndroid Build Coastguard Worker
1142*c8dee2aaSAndroid Build Coastguard Workerstd::pair<SkColorType, bool /*isRGBFormat*/> MtlCaps::supportedWritePixelsColorType(
1143*c8dee2aaSAndroid Build Coastguard Worker        SkColorType dstColorType,
1144*c8dee2aaSAndroid Build Coastguard Worker        const TextureInfo& dstTextureInfo,
1145*c8dee2aaSAndroid Build Coastguard Worker        SkColorType srcColorType) const {
1146*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo mtlInfo;
1147*c8dee2aaSAndroid Build Coastguard Worker    if (!TextureInfos::GetMtlTextureInfo(dstTextureInfo, &mtlInfo)) {
1148*c8dee2aaSAndroid Build Coastguard Worker        return {kUnknown_SkColorType, false};
1149*c8dee2aaSAndroid Build Coastguard Worker    }
1150*c8dee2aaSAndroid Build Coastguard Worker
1151*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& info = this->getFormatInfo(mtlInfo.fFormat);
1152*c8dee2aaSAndroid Build Coastguard Worker    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1153*c8dee2aaSAndroid Build Coastguard Worker        const auto& ctInfo = info.fColorTypeInfos[i];
1154*c8dee2aaSAndroid Build Coastguard Worker        if (ctInfo.fColorType == dstColorType) {
1155*c8dee2aaSAndroid Build Coastguard Worker            return {dstColorType, false};
1156*c8dee2aaSAndroid Build Coastguard Worker        }
1157*c8dee2aaSAndroid Build Coastguard Worker    }
1158*c8dee2aaSAndroid Build Coastguard Worker    return {kUnknown_SkColorType, false};
1159*c8dee2aaSAndroid Build Coastguard Worker}
1160*c8dee2aaSAndroid Build Coastguard Worker
1161*c8dee2aaSAndroid Build Coastguard Workerstd::pair<SkColorType, bool /*isRGBFormat*/> MtlCaps::supportedReadPixelsColorType(
1162*c8dee2aaSAndroid Build Coastguard Worker        SkColorType srcColorType,
1163*c8dee2aaSAndroid Build Coastguard Worker        const TextureInfo& srcTextureInfo,
1164*c8dee2aaSAndroid Build Coastguard Worker        SkColorType dstColorType) const {
1165*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfo mtlInfo;
1166*c8dee2aaSAndroid Build Coastguard Worker    if (!TextureInfos::GetMtlTextureInfo(srcTextureInfo, &mtlInfo)) {
1167*c8dee2aaSAndroid Build Coastguard Worker        return {kUnknown_SkColorType, false};
1168*c8dee2aaSAndroid Build Coastguard Worker    }
1169*c8dee2aaSAndroid Build Coastguard Worker
1170*c8dee2aaSAndroid Build Coastguard Worker    // TODO: handle compressed formats
1171*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsCompressed(mtlInfo.fFormat)) {
1172*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(this->isTexturable(mtlInfo.fFormat));
1173*c8dee2aaSAndroid Build Coastguard Worker        return {kUnknown_SkColorType, false};
1174*c8dee2aaSAndroid Build Coastguard Worker    }
1175*c8dee2aaSAndroid Build Coastguard Worker
1176*c8dee2aaSAndroid Build Coastguard Worker    const FormatInfo& info = this->getFormatInfo(mtlInfo.fFormat);
1177*c8dee2aaSAndroid Build Coastguard Worker    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1178*c8dee2aaSAndroid Build Coastguard Worker        const auto& ctInfo = info.fColorTypeInfos[i];
1179*c8dee2aaSAndroid Build Coastguard Worker        if (ctInfo.fColorType == srcColorType) {
1180*c8dee2aaSAndroid Build Coastguard Worker            return {srcColorType, false};
1181*c8dee2aaSAndroid Build Coastguard Worker        }
1182*c8dee2aaSAndroid Build Coastguard Worker    }
1183*c8dee2aaSAndroid Build Coastguard Worker    return {kUnknown_SkColorType, false};
1184*c8dee2aaSAndroid Build Coastguard Worker}
1185*c8dee2aaSAndroid Build Coastguard Worker
1186*c8dee2aaSAndroid Build Coastguard Workervoid MtlCaps::buildKeyForTexture(SkISize dimensions,
1187*c8dee2aaSAndroid Build Coastguard Worker                                 const TextureInfo& info,
1188*c8dee2aaSAndroid Build Coastguard Worker                                 ResourceType type,
1189*c8dee2aaSAndroid Build Coastguard Worker                                 Shareable shareable,
1190*c8dee2aaSAndroid Build Coastguard Worker                                 GraphiteResourceKey* key) const {
1191*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureSpec mtlSpec = TextureInfos::GetMtlTextureSpec(info);
1192*c8dee2aaSAndroid Build Coastguard Worker
1193*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(!dimensions.isEmpty());
1194*c8dee2aaSAndroid Build Coastguard Worker
1195*c8dee2aaSAndroid Build Coastguard Worker    // A MTLPixelFormat is an NSUInteger type which is documented to be 32 bits in 32 bit
1196*c8dee2aaSAndroid Build Coastguard Worker    // applications and 64 bits in 64 bit applications. So it should fit in an uint64_t, but adding
1197*c8dee2aaSAndroid Build Coastguard Worker    // the assert heere to make sure.
1198*c8dee2aaSAndroid Build Coastguard Worker    static_assert(sizeof(MTLPixelFormat) <= sizeof(uint64_t));
1199*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlSpec.fFormat != MTLPixelFormatInvalid);
1200*c8dee2aaSAndroid Build Coastguard Worker    uint64_t formatKey = static_cast<uint64_t>(mtlSpec.fFormat);
1201*c8dee2aaSAndroid Build Coastguard Worker
1202*c8dee2aaSAndroid Build Coastguard Worker    uint32_t samplesKey = SamplesToKey(info.numSamples());
1203*c8dee2aaSAndroid Build Coastguard Worker    // We don't have to key the number of mip levels because it is inherit in the combination of
1204*c8dee2aaSAndroid Build Coastguard Worker    // isMipped and dimensions.
1205*c8dee2aaSAndroid Build Coastguard Worker    bool isMipped = info.mipmapped() == Mipmapped::kYes;
1206*c8dee2aaSAndroid Build Coastguard Worker    Protected isProtected = info.isProtected();
1207*c8dee2aaSAndroid Build Coastguard Worker    bool isFBOnly = mtlSpec.fFramebufferOnly;
1208*c8dee2aaSAndroid Build Coastguard Worker
1209*c8dee2aaSAndroid Build Coastguard Worker    // Confirm all the below parts of the key can fit in a single uint32_t. The sum of the shift
1210*c8dee2aaSAndroid Build Coastguard Worker    // amounts in the asserts must be less than or equal to 32.
1211*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(samplesKey                         < (1u << 3));
1212*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(static_cast<uint32_t>(isMipped)    < (1u << 1));
1213*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(static_cast<uint32_t>(isProtected) < (1u << 1));
1214*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlSpec.fUsage                     < (1u << 5));
1215*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlSpec.fStorageMode               < (1u << 2));
1216*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(static_cast<uint32_t>(isFBOnly)    < (1u << 1));
1217*c8dee2aaSAndroid Build Coastguard Worker
1218*c8dee2aaSAndroid Build Coastguard Worker    // We need two uint32_ts for dimensions, 2 for format, and 1 for the rest of the key;
1219*c8dee2aaSAndroid Build Coastguard Worker    static int kNum32DataCnt = 2 + 2 + 1;
1220*c8dee2aaSAndroid Build Coastguard Worker
1221*c8dee2aaSAndroid Build Coastguard Worker    GraphiteResourceKey::Builder builder(key, type, kNum32DataCnt, shareable);
1222*c8dee2aaSAndroid Build Coastguard Worker
1223*c8dee2aaSAndroid Build Coastguard Worker    builder[0] = dimensions.width();
1224*c8dee2aaSAndroid Build Coastguard Worker    builder[1] = dimensions.height();
1225*c8dee2aaSAndroid Build Coastguard Worker    builder[2] = formatKey & 0xFFFFFFFF;
1226*c8dee2aaSAndroid Build Coastguard Worker    builder[3] = (formatKey >> 32) & 0xFFFFFFFF;
1227*c8dee2aaSAndroid Build Coastguard Worker    builder[4] = (samplesKey                                  << 0) |
1228*c8dee2aaSAndroid Build Coastguard Worker                 (static_cast<uint32_t>(isMipped)             << 3) |
1229*c8dee2aaSAndroid Build Coastguard Worker                 (static_cast<uint32_t>(isProtected)          << 4) |
1230*c8dee2aaSAndroid Build Coastguard Worker                 (static_cast<uint32_t>(mtlSpec.fUsage)       << 5) |
1231*c8dee2aaSAndroid Build Coastguard Worker                 (static_cast<uint32_t>(mtlSpec.fStorageMode) << 10)|
1232*c8dee2aaSAndroid Build Coastguard Worker                 (static_cast<uint32_t>(isFBOnly)             << 12);
1233*c8dee2aaSAndroid Build Coastguard Worker
1234*c8dee2aaSAndroid Build Coastguard Worker}
1235*c8dee2aaSAndroid Build Coastguard Worker
1236*c8dee2aaSAndroid Build Coastguard Worker} // namespace skgpu::graphite
1237