• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/mtl/GrMtlCaps.h"
9
10#include "include/core/SkRect.h"
11#include "include/gpu/GrBackendSurface.h"
12#include "src/gpu/GrRenderTarget.h"
13#include "src/gpu/GrRenderTargetProxy.h"
14#include "src/gpu/GrShaderCaps.h"
15#include "src/gpu/GrSurfaceProxy.h"
16#include "src/gpu/mtl/GrMtlUtil.h"
17
18#if !__has_feature(objc_arc)
19#error This file must be compiled with Arc. Use -fobjc-arc flag
20#endif
21
22GrMtlCaps::GrMtlCaps(const GrContextOptions& contextOptions, const id<MTLDevice> device,
23                     MTLFeatureSet featureSet)
24        : INHERITED(contextOptions) {
25    fShaderCaps.reset(new GrShaderCaps(contextOptions));
26
27    this->initFeatureSet(featureSet);
28    this->initGrCaps(device);
29    this->initShaderCaps();
30    this->initFormatTable();
31    this->initStencilFormat(device);
32
33    this->applyOptionsOverrides(contextOptions);
34    fShaderCaps->applyOptionsOverrides(contextOptions);
35
36    // The following are disabled due to the unfinished Metal backend, not because Metal itself
37    // doesn't support it.
38    fFenceSyncSupport = false;           // Fences are not implemented yet
39    fSemaphoreSupport = false;           // Semaphores are not implemented yet
40    fCrossContextTextureSupport = false; // GrMtlGpu::prepareTextureForCrossContextUsage() not impl
41}
42
43void GrMtlCaps::initFeatureSet(MTLFeatureSet featureSet) {
44    // Mac OSX
45#ifdef SK_BUILD_FOR_MAC
46    if (MTLFeatureSet_OSX_GPUFamily1_v2 == featureSet) {
47        fPlatform = Platform::kMac;
48        fFamilyGroup = 1;
49        fVersion = 2;
50        return;
51    }
52    if (MTLFeatureSet_OSX_GPUFamily1_v1 == featureSet) {
53        fPlatform = Platform::kMac;
54        fFamilyGroup = 1;
55        fVersion = 1;
56        return;
57    }
58#endif
59
60    // iOS Family group 3
61#ifdef SK_BUILD_FOR_IOS
62    if (MTLFeatureSet_iOS_GPUFamily3_v2 == featureSet) {
63        fPlatform = Platform::kIOS;
64        fFamilyGroup = 3;
65        fVersion = 2;
66        return;
67    }
68    if (MTLFeatureSet_iOS_GPUFamily3_v1 == featureSet) {
69        fPlatform = Platform::kIOS;
70        fFamilyGroup = 3;
71        fVersion = 1;
72        return;
73    }
74
75    // iOS Family group 2
76    if (MTLFeatureSet_iOS_GPUFamily2_v3 == featureSet) {
77        fPlatform = Platform::kIOS;
78        fFamilyGroup = 2;
79        fVersion = 3;
80        return;
81    }
82    if (MTLFeatureSet_iOS_GPUFamily2_v2 == featureSet) {
83        fPlatform = Platform::kIOS;
84        fFamilyGroup = 2;
85        fVersion = 2;
86        return;
87    }
88    if (MTLFeatureSet_iOS_GPUFamily2_v1 == featureSet) {
89        fPlatform = Platform::kIOS;
90        fFamilyGroup = 2;
91        fVersion = 1;
92        return;
93    }
94
95    // iOS Family group 1
96    if (MTLFeatureSet_iOS_GPUFamily1_v3 == featureSet) {
97        fPlatform = Platform::kIOS;
98        fFamilyGroup = 1;
99        fVersion = 3;
100        return;
101    }
102    if (MTLFeatureSet_iOS_GPUFamily1_v2 == featureSet) {
103        fPlatform = Platform::kIOS;
104        fFamilyGroup = 1;
105        fVersion = 2;
106        return;
107    }
108    if (MTLFeatureSet_iOS_GPUFamily1_v1 == featureSet) {
109        fPlatform = Platform::kIOS;
110        fFamilyGroup = 1;
111        fVersion = 1;
112        return;
113    }
114#endif
115    // No supported feature sets were found
116    SK_ABORT("Requested an unsupported feature set");
117}
118
119bool GrMtlCaps::canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount,
120                              MTLPixelFormat srcFormat, int srcSampleCount,
121                              const SkIRect& srcRect, const SkIPoint& dstPoint,
122                              bool areDstSrcSameObj) const {
123    if (!dstFormat || dstFormat != srcFormat) {
124        return false;
125    }
126    if ((dstSampleCount > 1 || srcSampleCount > 1) && (dstSampleCount != srcSampleCount)) {
127        return false;
128    }
129    if (areDstSrcSameObj) {
130        SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
131                                            srcRect.width(), srcRect.height());
132        if (dstRect.intersect(srcRect)) {
133            return false;
134        }
135    }
136    return true;
137}
138
139bool GrMtlCaps::canCopyAsResolve(GrSurface* dst, int dstSampleCount,
140                                 GrSurface* src, int srcSampleCount,
141                                 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
142    if (dst == src) {
143        return false;
144    }
145    if (dst->backendFormat() != src->backendFormat()) {
146        return false;
147    }
148    if (dstSampleCount > 1 || srcSampleCount == 1 || !src->asRenderTarget()) {
149        return false;
150    }
151
152    // TODO: Support copying subrectangles
153    if (dstPoint != SkIPoint::Make(0, 0)) {
154        return false;
155    }
156    if (srcRect != SkIRect::MakeXYWH(0, 0, src->width(), src->height())) {
157        return false;
158    }
159
160    return true;
161}
162
163bool GrMtlCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
164                                 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
165    int dstSampleCnt = 0;
166    int srcSampleCnt = 0;
167    if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
168        dstSampleCnt = rtProxy->numSamples();
169    }
170    if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
171        srcSampleCnt = rtProxy->numSamples();
172    }
173    SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
174    SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
175
176    return this->canCopyAsBlit(GrBackendFormatAsMTLPixelFormat(dst->backendFormat()), dstSampleCnt,
177                               GrBackendFormatAsMTLPixelFormat(src->backendFormat()), srcSampleCnt,
178                               srcRect, dstPoint, dst == src);
179}
180
181void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
182    // Max vertex attribs is the same on all devices
183    fMaxVertexAttributes = 31;
184
185    // Metal does not support scissor + clear
186    fPerformPartialClearsAsDraws = true;
187
188    // We always copy in/out of a transfer buffer so it's trivial to support row bytes.
189    fReadPixelsRowBytesSupport = true;
190    fWritePixelsRowBytesSupport = true;
191
192    // RenderTarget and Texture size
193    if (this->isMac()) {
194        fMaxRenderTargetSize = 16384;
195    } else {
196        if (3 == fFamilyGroup) {
197            fMaxRenderTargetSize = 16384;
198        } else {
199            // Family group 1 and 2 support 8192 for version 2 and above, 4096 for v1
200            if (1 == fVersion) {
201                fMaxRenderTargetSize = 4096;
202            } else {
203                fMaxRenderTargetSize = 8192;
204            }
205        }
206    }
207    fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
208    fMaxTextureSize = fMaxRenderTargetSize;
209
210    // Init sample counts. All devices support 1 (i.e. 0 in skia).
211    fSampleCounts.push_back(1);
212    for (auto sampleCnt : {2, 4, 8}) {
213        if ([device supportsTextureSampleCount:sampleCnt]) {
214            fSampleCounts.push_back(sampleCnt);
215        }
216    }
217
218    // Clamp to border is supported on Mac 10.12 and higher (gpu family.version >= 1.2). It is not
219    // supported on iOS.
220    if (this->isMac()) {
221        if (fFamilyGroup == 1 && fVersion < 2) {
222            fClampToBorderSupport = false;
223        }
224    } else {
225        fClampToBorderSupport = false;
226    }
227
228    // Starting with the assumption that there isn't a reason to not map small buffers.
229    fBufferMapThreshold = 0;
230
231    // Buffers are always fully mapped.
232    fMapBufferFlags = kCanMap_MapFlag;
233
234    fOversizedStencilSupport = true;
235
236    fSRGBSupport = true;   // always available in Metal
237    fSRGBWriteControl = false;
238    fMipMapSupport = true;   // always available in Metal
239    fNPOTTextureTileSupport = true;  // always available in Metal
240
241    fReuseScratchTextures = true; // Assuming this okay
242
243    fTextureBarrierSupport = false; // Need to figure out if we can do this
244
245    fSampleLocationsSupport = false;
246    fMultisampleDisableSupport = false;
247
248    if (this->isMac() || 3 == fFamilyGroup) {
249        fInstanceAttribSupport = true;
250    }
251
252    fMixedSamplesSupport = false;
253    fGpuTracingSupport = false;
254
255    fFenceSyncSupport = true;   // always available in Metal
256    fCrossContextTextureSupport = false;
257    fHalfFloatVertexAttributeSupport = true;
258}
259
260static bool format_is_srgb(MTLPixelFormat format) {
261    switch (format) {
262        case MTLPixelFormatRGBA8Unorm_sRGB:
263        case MTLPixelFormatBGRA8Unorm_sRGB:
264            return true;
265        default:
266            return false;
267    }
268}
269
270bool GrMtlCaps::isFormatSRGB(const GrBackendFormat& format) const {
271    return format_is_srgb(GrBackendFormatAsMTLPixelFormat(format));
272}
273
274bool GrMtlCaps::isFormatCompressed(const GrBackendFormat& format) const {
275#ifdef SK_BUILD_FOR_MAC
276    return false;
277#else
278    return GrBackendFormatAsMTLPixelFormat(format) == MTLPixelFormatETC2_RGB8;
279#endif
280}
281
282bool GrMtlCaps::isFormatTexturableAndUploadable(GrColorType ct,
283                                                const GrBackendFormat& format) const {
284    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
285
286    uint32_t ctFlags = this->getFormatInfo(mtlFormat).colorTypeFlags(ct);
287    return this->isFormatTexturable(mtlFormat) &&
288           SkToBool(ctFlags & ColorTypeInfo::kUploadData_Flag);
289}
290
291bool GrMtlCaps::isFormatTexturable(const GrBackendFormat& format) const {
292    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
293    return this->isFormatTexturable(mtlFormat);
294}
295
296bool GrMtlCaps::isFormatTexturable(MTLPixelFormat format) const {
297    const FormatInfo& formatInfo = this->getFormatInfo(format);
298    return SkToBool(FormatInfo::kTexturable_Flag && formatInfo.fFlags);
299}
300
301bool GrMtlCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
302                                              int sampleCount) const {
303    if (!this->isFormatRenderable(format, sampleCount)) {
304        return false;
305    }
306    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
307    SkASSERT(mtlFormat != MTLPixelFormatInvalid);
308    const auto& info = this->getFormatInfo(mtlFormat);
309    if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
310        return false;
311    }
312    return true;
313}
314
315bool GrMtlCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
316    return this->isFormatRenderable(GrBackendFormatAsMTLPixelFormat(format), sampleCount);
317}
318
319bool GrMtlCaps::isFormatRenderable(MTLPixelFormat format, int sampleCount) const {
320    return sampleCount <= this->maxRenderTargetSampleCount(format);
321}
322
323int GrMtlCaps::maxRenderTargetSampleCount(const GrBackendFormat& format) const {
324    return this->maxRenderTargetSampleCount(GrBackendFormatAsMTLPixelFormat(format));
325}
326
327int GrMtlCaps::maxRenderTargetSampleCount(MTLPixelFormat format) const {
328    const FormatInfo& formatInfo = this->getFormatInfo(format);
329    if (formatInfo.fFlags & FormatInfo::kMSAA_Flag) {
330        return fSampleCounts[fSampleCounts.count() - 1];
331    } else if (formatInfo.fFlags & FormatInfo::kRenderable_Flag) {
332        return 1;
333    }
334    return 0;
335}
336
337int GrMtlCaps::getRenderTargetSampleCount(int requestedCount,
338                                          const GrBackendFormat& format) const {
339    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
340
341    return this->getRenderTargetSampleCount(requestedCount, mtlFormat);
342}
343
344int GrMtlCaps::getRenderTargetSampleCount(int requestedCount, MTLPixelFormat format) const {
345    requestedCount = SkTMax(requestedCount, 1);
346    const FormatInfo& formatInfo = this->getFormatInfo(format);
347    if (!(formatInfo.fFlags & FormatInfo::kRenderable_Flag)) {
348        return 0;
349    }
350    if (formatInfo.fFlags & FormatInfo::kMSAA_Flag) {
351        int count = fSampleCounts.count();
352        for (int i = 0; i < count; ++i) {
353            if (fSampleCounts[i] >= requestedCount) {
354                return fSampleCounts[i];
355            }
356        }
357    }
358    return 1 == requestedCount ? 1 : 0;
359}
360
361void GrMtlCaps::initShaderCaps() {
362    GrShaderCaps* shaderCaps = fShaderCaps.get();
363
364    // Setting this true with the assumption that this cap will eventually mean we support varying
365    // precisions and not just via modifiers.
366    shaderCaps->fUsesPrecisionModifiers = true;
367    shaderCaps->fFlatInterpolationSupport = true;
368    // We haven't yet tested that using flat attributes perform well.
369    shaderCaps->fPreferFlatInterpolation = true;
370
371    shaderCaps->fShaderDerivativeSupport = true;
372    shaderCaps->fGeometryShaderSupport = false;
373
374    if ((this->isMac() && fVersion >= 2) ||
375        (this->isIOS() && ((1 == fFamilyGroup && 4 == fVersion) ||
376                           (2 == fFamilyGroup && 4 == fVersion) ||
377                           (3 == fFamilyGroup && 3 == fVersion)))) {
378        shaderCaps->fDualSourceBlendingSupport = true;
379    }
380
381    // TODO: Re-enable this once skbug:8720 is fixed. Will also need to remove asserts in
382    // GrMtlPipelineStateBuilder which assert we aren't using this feature.
383#if 0
384    if (this->isIOS()) {
385        shaderCaps->fFBFetchSupport = true;
386        shaderCaps->fFBFetchNeedsCustomOutput = true; // ??
387        shaderCaps->fFBFetchColorName = ""; // Somehow add [[color(0)]] to arguments to frag shader
388    }
389#endif
390    shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
391
392    shaderCaps->fIntegerSupport = true;
393    shaderCaps->fVertexIDSupport = false;
394
395    // Metal uses IEEE float and half floats so assuming those values here.
396    shaderCaps->fFloatIs32Bits = true;
397    shaderCaps->fHalfIs32Bits = false;
398
399    shaderCaps->fMaxFragmentSamplers = 16;
400}
401
402// These are all the valid MTLPixelFormats that we support in Skia.  They are roughly ordered from
403// most frequently used to least to improve look up times in arrays.
404static constexpr MTLPixelFormat kMtlFormats[] = {
405    MTLPixelFormatRGBA8Unorm,
406    MTLPixelFormatR8Unorm,
407    MTLPixelFormatA8Unorm,
408    MTLPixelFormatBGRA8Unorm,
409#ifdef SK_BUILD_FOR_IOS
410    MTLPixelFormatB5G6R5Unorm,
411#endif
412    MTLPixelFormatRGBA16Float,
413    MTLPixelFormatR16Float,
414    MTLPixelFormatRG8Unorm,
415    MTLPixelFormatRGB10A2Unorm,
416#ifdef SK_BUILD_FOR_IOS
417    MTLPixelFormatABGR4Unorm,
418#endif
419    MTLPixelFormatRGBA32Float,
420    MTLPixelFormatRGBA8Unorm_sRGB,
421    MTLPixelFormatR16Unorm,
422    MTLPixelFormatRG16Unorm,
423#ifdef SK_BUILD_FOR_IOS
424    MTLPixelFormatETC2_RGB8,
425#endif
426    // Experimental (for Y416 and mutant P016/P010)
427    MTLPixelFormatRGBA16Unorm,
428    MTLPixelFormatRG16Float,
429
430    MTLPixelFormatInvalid,
431};
432
433void GrMtlCaps::setColorType(GrColorType colorType, std::initializer_list<MTLPixelFormat> formats) {
434#ifdef SK_DEBUG
435    for (size_t i = 0; i < kNumMtlFormats; ++i) {
436        const auto& formatInfo = fFormatTable[i];
437        for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
438            const auto& ctInfo = formatInfo.fColorTypeInfos[j];
439            if (ctInfo.fColorType == colorType) {
440                bool found = false;
441                for (auto it = formats.begin(); it != formats.end(); ++it) {
442                    if (kMtlFormats[i] == *it) {
443                        found = true;
444                    }
445                }
446                SkASSERT(found);
447            }
448        }
449    }
450#endif
451    int idx = static_cast<int>(colorType);
452    for (auto it = formats.begin(); it != formats.end(); ++it) {
453        const auto& info = this->getFormatInfo(*it);
454        for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
455            if (info.fColorTypeInfos[i].fColorType == colorType) {
456                fColorTypeToFormatTable[idx] = *it;
457                return;
458            }
459        }
460    }
461}
462
463size_t GrMtlCaps::GetFormatIndex(MTLPixelFormat pixelFormat) {
464    static_assert(SK_ARRAY_COUNT(kMtlFormats) == GrMtlCaps::kNumMtlFormats,
465                  "Size of kMtlFormats array must match static value in header");
466    for (size_t i = 0; i < GrMtlCaps::kNumMtlFormats; ++i) {
467        if (kMtlFormats[i] == pixelFormat) {
468            return i;
469        }
470    }
471    SK_ABORT("Invalid MTLPixelFormat");
472}
473
474void GrMtlCaps::initFormatTable() {
475    FormatInfo* info;
476
477    // Format: R8Unorm
478    {
479        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR8Unorm)];
480        info->fFlags = FormatInfo::kAllFlags;
481        info->fColorTypeInfoCount = 2;
482        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
483        int ctIdx = 0;
484        // Format: R8Unorm, Surface: kAlpha_8
485        {
486            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
487            ctInfo.fColorType = GrColorType::kAlpha_8;
488            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
489            ctInfo.fTextureSwizzle = GrSwizzle::RRRR();
490            ctInfo.fOutputSwizzle = GrSwizzle::AAAA();
491        }
492        // Format: R8Unorm, Surface: kGray_8
493        {
494            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
495            ctInfo.fColorType = GrColorType::kGray_8;
496            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
497            ctInfo.fTextureSwizzle = GrSwizzle("rrr1");
498        }
499    }
500
501    // Format: A8Unorm
502    {
503        info = &fFormatTable[GetFormatIndex(MTLPixelFormatA8Unorm)];
504        info->fFlags = FormatInfo::kTexturable_Flag;
505        info->fColorTypeInfoCount = 1;
506        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
507        int ctIdx = 0;
508        // Format: A8Unorm, Surface: kAlpha_8
509        {
510            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
511            ctInfo.fColorType = GrColorType::kAlpha_8;
512            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
513            ctInfo.fTextureSwizzle = GrSwizzle::AAAA();
514        }
515    }
516
517#ifdef SK_BUILD_FOR_IOS
518    // Format: B5G6R5Unorm
519    {
520        info = &fFormatTable[GetFormatIndex(MTLPixelFormatB5G6R5Unorm)];
521        info->fFlags = FormatInfo::kAllFlags;
522        info->fColorTypeInfoCount = 1;
523        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
524        int ctIdx = 0;
525        // Format: B5G6R5Unorm, Surface: kBGR_565
526        {
527            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
528            ctInfo.fColorType = GrColorType::kBGR_565;
529            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
530        }
531    }
532
533    // Format: ABGR4Unorm
534    {
535        info = &fFormatTable[GetFormatIndex(MTLPixelFormatABGR4Unorm)];
536        info->fFlags = FormatInfo::kAllFlags;
537        info->fColorTypeInfoCount = 1;
538        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
539        int ctIdx = 0;
540        // Format: ABGR4Unorm, Surface: kABGR_4444
541        {
542            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
543            ctInfo.fColorType = GrColorType::kABGR_4444;
544            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
545        }
546    }
547#endif
548
549    // Format: RGBA8Unorm
550    {
551        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm)];
552        info->fFlags = FormatInfo::kAllFlags;
553        info->fColorTypeInfoCount = 2;
554        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
555        int ctIdx = 0;
556        // Format: RGBA8Unorm, Surface: kRGBA_8888
557        {
558            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
559            ctInfo.fColorType = GrColorType::kRGBA_8888;
560            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
561        }
562        // Format: RGBA8Unorm, Surface: kRGB_888x
563        {
564            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
565            ctInfo.fColorType = GrColorType::kRGB_888x;
566            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
567            ctInfo.fTextureSwizzle = GrSwizzle::RGB1();
568        }
569    }
570
571    // Format: RG8Unorm
572    {
573        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG8Unorm)];
574        info->fFlags = FormatInfo::kTexturable_Flag;
575        info->fColorTypeInfoCount = 1;
576        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
577        int ctIdx = 0;
578        // Format: RG8Unorm, Surface: kRG_88
579        {
580            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
581            ctInfo.fColorType = GrColorType::kRG_88;
582            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
583        }
584    }
585
586    // Format: BGRA8Unorm
587    {
588        info = &fFormatTable[GetFormatIndex(MTLPixelFormatBGRA8Unorm)];
589        info->fFlags = FormatInfo::kAllFlags;
590        info->fColorTypeInfoCount = 1;
591        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
592        int ctIdx = 0;
593        // Format: BGRA8Unorm, Surface: kBGRA_8888
594        {
595            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
596            ctInfo.fColorType = GrColorType::kBGRA_8888;
597            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
598        }
599    }
600
601    // Format: RGBA8Unorm_sRGB
602    {
603        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm_sRGB)];
604        info->fFlags = FormatInfo::kAllFlags;
605        info->fColorTypeInfoCount = 1;
606        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
607        int ctIdx = 0;
608        // Format: RGBA8Unorm_sRGB, Surface: kRGBA_8888_SRGB
609        {
610            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
611            ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
612            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
613        }
614    }
615
616    // Format: RGB10A2Unorm
617    {
618        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGB10A2Unorm)];
619        if (this->isMac() || fFamilyGroup >= 3) {
620            info->fFlags = FormatInfo::kAllFlags;
621        } else {
622            info->fFlags = FormatInfo::kTexturable_Flag;
623        }
624        info->fColorTypeInfoCount = 1;
625        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
626        int ctIdx = 0;
627        // Format: RGB10A2Unorm, Surface: kRGBA_1010102
628        {
629            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
630            ctInfo.fColorType = GrColorType::kRGBA_1010102;
631            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
632        }
633    }
634
635    // Format: RGBA32Float
636    {
637        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA32Float)];
638        if (this->isMac()) {
639            info->fFlags = FormatInfo::kAllFlags;
640        } else {
641            info->fFlags = 0;
642        }
643        info->fColorTypeInfoCount = 1;
644        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
645        int ctIdx = 0;
646        // Format: RGBA32Float, Surface: kRGBA_F32
647        if (info->fFlags) {
648            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
649            ctInfo.fColorType = GrColorType::kRGBA_F32;
650            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
651        }
652    }
653
654    // Format: R16Float
655    {
656        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Float)];
657        info->fFlags = FormatInfo::kAllFlags;
658        info->fColorTypeInfoCount = 1;
659        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
660        int ctIdx = 0;
661        // Format: R16Float, Surface: kAlpha_F16
662        {
663            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
664            ctInfo.fColorType = GrColorType::kAlpha_F16;
665            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
666            ctInfo.fTextureSwizzle = GrSwizzle::RRRR();
667            ctInfo.fOutputSwizzle = GrSwizzle::AAAA();
668        }
669    }
670
671    // Format: RGBA16Float
672    {
673        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Float)];
674        info->fFlags = FormatInfo::kAllFlags;
675        info->fColorTypeInfoCount = 2;
676        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
677        int ctIdx = 0;
678        // Format: RGBA16Float, Surface: kRGBA_F16
679        {
680            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
681            ctInfo.fColorType = GrColorType::kRGBA_F16;
682            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
683        }
684        // Format: RGBA16Float, Surface: kRGBA_F16_Clamped
685        {
686            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
687            ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
688            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
689        }
690    }
691
692    // Format: R16Unorm
693    {
694        info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Unorm)];
695        if (this->isMac()) {
696            info->fFlags = FormatInfo::kAllFlags;
697        } else {
698            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
699        }
700        info->fColorTypeInfoCount = 1;
701        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
702        int ctIdx = 0;
703        // Format: R16Unorm, Surface: kR_16
704        {
705            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
706            ctInfo.fColorType = GrColorType::kR_16;
707            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
708        }
709    }
710
711    // Format: RG16Unorm
712    {
713        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Unorm)];
714        if (this->isMac()) {
715            info->fFlags = FormatInfo::kAllFlags;
716        } else {
717            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
718        }
719        info->fColorTypeInfoCount = 1;
720        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
721        int ctIdx = 0;
722        // Format: RG16Unorm, Surface: kRG_1616
723        {
724            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
725            ctInfo.fColorType = GrColorType::kRG_1616;
726            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
727        }
728    }
729
730#ifdef SK_BUILD_FOR_IOS
731    // ETC2_RGB8
732    info = &fFormatTable[GetFormatIndex(MTLPixelFormatETC2_RGB8)];
733    // GrMtlGpu::onCreateCompressedTexture() not implemented.
734    info->fFlags = 0;
735    // NO supported colorTypes
736#endif
737
738    // Experimental (for Y416 and mutant P016/P010)
739
740    // Format: RGBA16Unorm
741    {
742        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Unorm)];
743        if (this->isMac()) {
744            info->fFlags = FormatInfo::kAllFlags;
745        } else {
746            info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
747        }
748        info->fColorTypeInfoCount = 1;
749        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
750        int ctIdx = 0;
751        // Format: RGBA16Unorm, Surface: kRGBA_16161616
752        {
753            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
754            ctInfo.fColorType = GrColorType::kRGBA_16161616;
755            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
756        }
757    }
758
759    // Format: RG16Float
760    {
761        info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Float)];
762        info->fFlags = FormatInfo::kAllFlags;
763        info->fColorTypeInfoCount = 1;
764        info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
765        int ctIdx = 0;
766        // Format: RG16Float, Surface: kRG_F16
767        {
768            auto& ctInfo = info->fColorTypeInfos[ctIdx++];
769            ctInfo.fColorType = GrColorType::kRG_F16;
770            ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
771        }
772    }
773
774    ////////////////////////////////////////////////////////////////////////////
775    // Map GrColorTypes (used for creating GrSurfaces) to MTLPixelFormats. The order in which the
776    // formats are passed into the setColorType function indicates the priority in selecting which
777    // format we use for a given GrcolorType.
778
779    std::fill_n(fColorTypeToFormatTable, kGrColorTypeCnt, MTLPixelFormatInvalid);
780
781    this->setColorType(GrColorType::kAlpha_8,          { MTLPixelFormatR8Unorm,
782                                                         MTLPixelFormatA8Unorm });
783#ifdef SK_BUILD_FOR_IOS
784    this->setColorType(GrColorType::kBGR_565,          { MTLPixelFormatB5G6R5Unorm });
785    this->setColorType(GrColorType::kABGR_4444,        { MTLPixelFormatABGR4Unorm });
786#endif
787    this->setColorType(GrColorType::kRGBA_8888,        { MTLPixelFormatRGBA8Unorm });
788    this->setColorType(GrColorType::kRGBA_8888_SRGB,   { MTLPixelFormatRGBA8Unorm_sRGB });
789    this->setColorType(GrColorType::kRGB_888x,         { MTLPixelFormatRGBA8Unorm });
790    this->setColorType(GrColorType::kRG_88,            { MTLPixelFormatRG8Unorm });
791    this->setColorType(GrColorType::kBGRA_8888,        { MTLPixelFormatBGRA8Unorm });
792    this->setColorType(GrColorType::kRGBA_1010102,     { MTLPixelFormatRGB10A2Unorm });
793    this->setColorType(GrColorType::kGray_8,           { MTLPixelFormatR8Unorm });
794    this->setColorType(GrColorType::kAlpha_F16,        { MTLPixelFormatR16Float });
795    this->setColorType(GrColorType::kRGBA_F16,         { MTLPixelFormatRGBA16Float });
796    this->setColorType(GrColorType::kRGBA_F16_Clamped, { MTLPixelFormatRGBA16Float });
797    this->setColorType(GrColorType::kRGBA_F32,         { MTLPixelFormatRGBA32Float });
798    this->setColorType(GrColorType::kR_16,             { MTLPixelFormatR16Unorm });
799    this->setColorType(GrColorType::kRG_1616,          { MTLPixelFormatRG16Unorm });
800    this->setColorType(GrColorType::kRGBA_16161616,    { MTLPixelFormatRGBA16Unorm });
801    this->setColorType(GrColorType::kRG_F16,           { MTLPixelFormatRG16Float });
802}
803
804void GrMtlCaps::initStencilFormat(id<MTLDevice> physDev) {
805    fPreferredStencilFormat = StencilFormat{ MTLPixelFormatStencil8, 8, 8, true };
806}
807
808bool GrMtlCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
809    if (auto rt = surface->asRenderTarget()) {
810        return rt->numSamples() <= 1 && SkToBool(surface->asTexture());
811    }
812    return true;
813}
814
815static constexpr GrPixelConfig validate_sized_format(GrMTLPixelFormat grFormat, GrColorType ct) {
816    MTLPixelFormat format = static_cast<MTLPixelFormat>(grFormat);
817    switch (ct) {
818        case GrColorType::kUnknown:
819            return kUnknown_GrPixelConfig;
820        case GrColorType::kAlpha_8:
821            if (MTLPixelFormatA8Unorm == format) {
822                return kAlpha_8_as_Alpha_GrPixelConfig;
823            } else if (MTLPixelFormatR8Unorm == format) {
824                return kAlpha_8_as_Red_GrPixelConfig;
825            }
826            break;
827#ifdef SK_BUILD_FOR_MAC
828        case GrColorType::kBGR_565:
829        case GrColorType::kABGR_4444:
830            return kUnknown_GrPixelConfig;
831#else
832        case GrColorType::kBGR_565:
833            if (MTLPixelFormatB5G6R5Unorm == format) {
834                return kRGB_565_GrPixelConfig;
835            }
836            break;
837        case GrColorType::kABGR_4444:
838            if (MTLPixelFormatABGR4Unorm == format) {
839                return kRGBA_4444_GrPixelConfig;
840            }
841            break;
842#endif
843        case GrColorType::kRGBA_8888:
844            if (MTLPixelFormatRGBA8Unorm == format) {
845                return kRGBA_8888_GrPixelConfig;
846            }
847            break;
848        case GrColorType::kRGBA_8888_SRGB:
849            if (MTLPixelFormatRGBA8Unorm_sRGB == format) {
850                return kSRGBA_8888_GrPixelConfig;
851            }
852            break;
853        case GrColorType::kRGB_888x:
854            if (MTLPixelFormatRGBA8Unorm == format) {
855                return kRGB_888X_GrPixelConfig;
856            }
857#ifdef SK_BUILD_FOR_IOS
858            else if (MTLPixelFormatETC2_RGB8 == format) {
859                return kRGB_ETC1_GrPixelConfig;
860            }
861#endif
862            break;
863        case GrColorType::kRG_88:
864            if (MTLPixelFormatRG8Unorm == format) {
865                return kRG_88_GrPixelConfig;
866            }
867            break;
868        case GrColorType::kBGRA_8888:
869            if (MTLPixelFormatBGRA8Unorm == format) {
870                return kBGRA_8888_GrPixelConfig;
871            }
872            break;
873        case GrColorType::kRGBA_1010102:
874            if (MTLPixelFormatRGB10A2Unorm == format) {
875                return kRGBA_1010102_GrPixelConfig;
876            }
877            break;
878        case GrColorType::kGray_8:
879            if (MTLPixelFormatR8Unorm == format) {
880                return kGray_8_as_Red_GrPixelConfig;
881            }
882            break;
883        case GrColorType::kAlpha_F16:
884            if (MTLPixelFormatR16Float == format) {
885                return kAlpha_half_as_Red_GrPixelConfig;
886            }
887            break;
888        case GrColorType::kRGBA_F16:
889            if (MTLPixelFormatRGBA16Float == format) {
890                return kRGBA_half_GrPixelConfig;
891            }
892            break;
893        case GrColorType::kRGBA_F16_Clamped:
894            if (MTLPixelFormatRGBA16Float == format) {
895                return kRGBA_half_Clamped_GrPixelConfig;
896            }
897            break;
898        case GrColorType::kRGBA_F32:
899            if (MTLPixelFormatRGBA32Float == format) {
900                return kRGBA_float_GrPixelConfig;
901            }
902            break;
903        case GrColorType::kR_16:
904            if (MTLPixelFormatR16Unorm == format) {
905                return kR_16_GrPixelConfig;
906            }
907            break;
908        case GrColorType::kRG_1616:
909            if (MTLPixelFormatRG16Unorm == format) {
910                return kRG_1616_GrPixelConfig;
911            }
912            break;
913        case GrColorType::kRGBA_16161616:
914            if (MTLPixelFormatRGBA16Unorm == format) {
915                return kRGBA_16161616_GrPixelConfig;
916            }
917            break;
918        case GrColorType::kRG_F16:
919            if (MTLPixelFormatRG16Float == format) {
920                return kRG_half_GrPixelConfig;
921            }
922            break;
923        case GrColorType::kAlpha_8xxx:
924        case GrColorType::kAlpha_F32xxx:
925        case GrColorType::kGray_8xxx:
926            return kUnknown_GrPixelConfig;
927    }
928    SkUNREACHABLE;
929}
930
931bool GrMtlCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
932                                                  const GrBackendFormat& format) const {
933    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
934    const auto& info = this->getFormatInfo(mtlFormat);
935    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
936        if (info.fColorTypeInfos[i].fColorType == ct) {
937            return true;
938        }
939    }
940    return false;
941}
942
943GrPixelConfig GrMtlCaps::onGetConfigFromBackendFormat(const GrBackendFormat& format,
944                                                      GrColorType ct) const {
945    return validate_sized_format(GrBackendFormatAsMTLPixelFormat(format), ct);
946}
947
948GrColorType GrMtlCaps::getYUVAColorTypeFromBackendFormat(const GrBackendFormat& format,
949                                                         bool isAlphaChannel) const {
950    switch (GrBackendFormatAsMTLPixelFormat(format)) {
951        case MTLPixelFormatA8Unorm:           // fall through
952        case MTLPixelFormatR8Unorm:           return isAlphaChannel ? GrColorType::kAlpha_8
953                                                                    : GrColorType::kGray_8;
954        case MTLPixelFormatRG8Unorm:          return GrColorType::kRG_88;
955        case MTLPixelFormatRGBA8Unorm:        return GrColorType::kRGBA_8888;
956        case MTLPixelFormatBGRA8Unorm:        return GrColorType::kBGRA_8888;
957        case MTLPixelFormatRGB10A2Unorm:      return GrColorType::kRGBA_1010102;
958        case MTLPixelFormatR16Unorm:          return GrColorType::kR_16;
959        case MTLPixelFormatRG16Unorm:         return GrColorType::kRG_1616;
960        // Experimental (for Y416 and mutant P016/P010)
961        case MTLPixelFormatRGBA16Unorm:       return GrColorType::kRGBA_16161616;
962        case MTLPixelFormatRG16Float:         return GrColorType::kRG_F16;
963        default:                              return GrColorType::kUnknown;
964    }
965}
966
967GrBackendFormat GrMtlCaps::onGetDefaultBackendFormat(GrColorType ct,
968                                                     GrRenderable renderable) const {
969    MTLPixelFormat format = this->getFormatFromColorType(ct);
970    if (!format) {
971        return GrBackendFormat();
972    }
973    return GrBackendFormat::MakeMtl(format);
974}
975
976GrBackendFormat GrMtlCaps::getBackendFormatFromCompressionType(
977        SkImage::CompressionType compressionType) const {
978    switch (compressionType) {
979        case SkImage::kETC1_CompressionType:
980#ifdef SK_BUILD_FOR_MAC
981            return {};
982#else
983            return GrBackendFormat::MakeMtl(MTLPixelFormatETC2_RGB8);
984#endif
985    }
986    SK_ABORT("Invalid compression type");
987}
988
989GrSwizzle GrMtlCaps::getTextureSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
990    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
991    SkASSERT(mtlFormat != MTLPixelFormatInvalid);
992    const auto& info = this->getFormatInfo(mtlFormat);
993    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
994        const auto& ctInfo = info.fColorTypeInfos[i];
995        if (ctInfo.fColorType == colorType) {
996            return ctInfo.fTextureSwizzle;
997        }
998    }
999    return GrSwizzle::RGBA();
1000}
1001GrSwizzle GrMtlCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
1002    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
1003    SkASSERT(mtlFormat != MTLPixelFormatInvalid);
1004    const auto& info = this->getFormatInfo(mtlFormat);
1005    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1006        const auto& ctInfo = info.fColorTypeInfos[i];
1007        if (ctInfo.fColorType == colorType) {
1008            return ctInfo.fOutputSwizzle;
1009        }
1010    }
1011    return GrSwizzle::RGBA();
1012}
1013
1014GrCaps::SupportedWrite GrMtlCaps::supportedWritePixelsColorType(
1015        GrColorType surfaceColorType, const GrBackendFormat& surfaceFormat,
1016        GrColorType srcColorType) const {
1017    // Metal requires the destination offset for copyFromTexture to be a multiple of the textures
1018    // pixels size.
1019    size_t offsetAlignment = GrColorTypeBytesPerPixel(surfaceColorType);
1020
1021    const auto& info = this->getFormatInfo(GrBackendFormatAsMTLPixelFormat(surfaceFormat));
1022    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1023        const auto& ctInfo = info.fColorTypeInfos[i];
1024        if (ctInfo.fColorType == surfaceColorType) {
1025            return {surfaceColorType, offsetAlignment};
1026        }
1027    }
1028    return {GrColorType::kUnknown, 0};
1029}
1030
1031GrCaps::SupportedRead GrMtlCaps::onSupportedReadPixelsColorType(
1032        GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
1033        GrColorType dstColorType) const {
1034    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(srcBackendFormat);
1035
1036    // Metal requires the destination offset for copyFromTexture to be a multiple of the textures
1037    // pixels size.
1038    size_t offsetAlignment = GrColorTypeBytesPerPixel(srcColorType);
1039
1040    const auto& info = this->getFormatInfo(mtlFormat);
1041    for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1042        const auto& ctInfo = info.fColorTypeInfos[i];
1043        if (ctInfo.fColorType == srcColorType) {
1044            return {srcColorType, offsetAlignment};
1045        }
1046    }
1047    return {GrColorType::kUnknown, 0};
1048}
1049
1050#if GR_TEST_UTILS
1051std::vector<GrCaps::TestFormatColorTypeCombination> GrMtlCaps::getTestingCombinations() const {
1052    std::vector<GrCaps::TestFormatColorTypeCombination> combos = {
1053        { GrColorType::kAlpha_8,          GrBackendFormat::MakeMtl(MTLPixelFormatA8Unorm)         },
1054        { GrColorType::kAlpha_8,          GrBackendFormat::MakeMtl(MTLPixelFormatR8Unorm)         },
1055#ifdef SK_BUILD_FOR_IOS
1056        { GrColorType::kBGR_565,          GrBackendFormat::MakeMtl(MTLPixelFormatB5G6R5Unorm)     },
1057        { GrColorType::kABGR_4444,        GrBackendFormat::MakeMtl(MTLPixelFormatABGR4Unorm)      },
1058#endif
1059        { GrColorType::kRGBA_8888,        GrBackendFormat::MakeMtl(MTLPixelFormatRGBA8Unorm)      },
1060        { GrColorType::kRGBA_8888_SRGB,   GrBackendFormat::MakeMtl(MTLPixelFormatRGBA8Unorm_sRGB) },
1061        { GrColorType::kRGB_888x,         GrBackendFormat::MakeMtl(MTLPixelFormatRGBA8Unorm)      },
1062#ifdef SK_BUILD_FOR_IOS
1063        { GrColorType::kRGB_888x,         GrBackendFormat::MakeMtl(MTLPixelFormatETC2_RGB8)       },
1064#endif
1065        { GrColorType::kRG_88,            GrBackendFormat::MakeMtl(MTLPixelFormatRG8Unorm)        },
1066        { GrColorType::kBGRA_8888,        GrBackendFormat::MakeMtl(MTLPixelFormatBGRA8Unorm)      },
1067        { GrColorType::kRGBA_1010102,     GrBackendFormat::MakeMtl(MTLPixelFormatRGB10A2Unorm)    },
1068        { GrColorType::kGray_8,           GrBackendFormat::MakeMtl(MTLPixelFormatR8Unorm)         },
1069        { GrColorType::kAlpha_F16,        GrBackendFormat::MakeMtl(MTLPixelFormatR16Float)        },
1070        { GrColorType::kRGBA_F16,         GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Float)     },
1071        { GrColorType::kRGBA_F16_Clamped, GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Float)     },
1072        { GrColorType::kRGBA_F32,         GrBackendFormat::MakeMtl(MTLPixelFormatRGBA32Float)     },
1073        { GrColorType::kR_16,             GrBackendFormat::MakeMtl(MTLPixelFormatR16Unorm)        },
1074        { GrColorType::kRG_1616,          GrBackendFormat::MakeMtl(MTLPixelFormatRG16Unorm)       },
1075        { GrColorType::kRGBA_16161616,    GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Unorm)     },
1076        { GrColorType::kRG_F16,           GrBackendFormat::MakeMtl(MTLPixelFormatRG16Float)       },
1077    };
1078
1079#ifdef SK_DEBUG
1080    for (auto combo : combos) {
1081        SkASSERT(this->onAreColorTypeAndFormatCompatible(combo.fColorType, combo.fFormat));
1082    }
1083#endif
1084
1085    return combos;
1086}
1087#endif
1088