xref: /aosp_15_r20/external/skia/src/gpu/ganesh/mtl/GrMtlUtil.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc.
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/ganesh/mtl/GrMtlUtil.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker#import <Metal/Metal.h>
11*c8dee2aaSAndroid Build Coastguard Worker
12*c8dee2aaSAndroid Build Coastguard Worker#include "include/core/SkTextureCompressionType.h"
13*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/GrBackendSurface.h"
14*c8dee2aaSAndroid Build Coastguard Worker#include "include/private/base/SkMutex.h"
15*c8dee2aaSAndroid Build Coastguard Worker#include "include/private/gpu/ganesh/GrTypesPriv.h"
16*c8dee2aaSAndroid Build Coastguard Worker#include "src/core/SkTraceEvent.h"
17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/GrSurface.h"
18*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
19*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlRenderTarget.h"
20*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlTexture.h"
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker#if !__has_feature(objc_arc)
23*c8dee2aaSAndroid Build Coastguard Worker#error This file must be compiled with Arc. Use -fobjc-arc flag
24*c8dee2aaSAndroid Build Coastguard Worker#endif
25*c8dee2aaSAndroid Build Coastguard Worker
26*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_BEGIN
27*c8dee2aaSAndroid Build Coastguard Worker
28*c8dee2aaSAndroid Build Coastguard WorkerNSError* GrCreateMtlError(NSString* description, GrMtlErrorCode errorCode) {
29*c8dee2aaSAndroid Build Coastguard Worker    NSDictionary* userInfo = [NSDictionary dictionaryWithObject:description
30*c8dee2aaSAndroid Build Coastguard Worker                                                         forKey:NSLocalizedDescriptionKey];
31*c8dee2aaSAndroid Build Coastguard Worker    return [NSError errorWithDomain:@"org.skia.ganesh"
32*c8dee2aaSAndroid Build Coastguard Worker                               code:(NSInteger)errorCode
33*c8dee2aaSAndroid Build Coastguard Worker                           userInfo:userInfo];
34*c8dee2aaSAndroid Build Coastguard Worker}
35*c8dee2aaSAndroid Build Coastguard Worker
36*c8dee2aaSAndroid Build Coastguard WorkerMTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
37*c8dee2aaSAndroid Build Coastguard Worker    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
38*c8dee2aaSAndroid Build Coastguard Worker    texDesc.textureType = mtlTexture.textureType;
39*c8dee2aaSAndroid Build Coastguard Worker    texDesc.pixelFormat = mtlTexture.pixelFormat;
40*c8dee2aaSAndroid Build Coastguard Worker    texDesc.width = mtlTexture.width;
41*c8dee2aaSAndroid Build Coastguard Worker    texDesc.height = mtlTexture.height;
42*c8dee2aaSAndroid Build Coastguard Worker    texDesc.depth = mtlTexture.depth;
43*c8dee2aaSAndroid Build Coastguard Worker    texDesc.mipmapLevelCount = mtlTexture.mipmapLevelCount;
44*c8dee2aaSAndroid Build Coastguard Worker    texDesc.arrayLength = mtlTexture.arrayLength;
45*c8dee2aaSAndroid Build Coastguard Worker    texDesc.sampleCount = mtlTexture.sampleCount;
46*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
47*c8dee2aaSAndroid Build Coastguard Worker        texDesc.usage = mtlTexture.usage;
48*c8dee2aaSAndroid Build Coastguard Worker    }
49*c8dee2aaSAndroid Build Coastguard Worker    return texDesc;
50*c8dee2aaSAndroid Build Coastguard Worker}
51*c8dee2aaSAndroid Build Coastguard Worker
52*c8dee2aaSAndroid Build Coastguard Workerid<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
53*c8dee2aaSAndroid Build Coastguard Worker                                         const std::string& msl,
54*c8dee2aaSAndroid Build Coastguard Worker                                         GrContextOptions::ShaderErrorHandler* errorHandler) {
55*c8dee2aaSAndroid Build Coastguard Worker    TRACE_EVENT0("skia.shaders", "driver_compile_shader");
56*c8dee2aaSAndroid Build Coastguard Worker    NSString* nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
57*c8dee2aaSAndroid Build Coastguard Worker                                                        length:msl.size()
58*c8dee2aaSAndroid Build Coastguard Worker                                                      encoding:NSUTF8StringEncoding
59*c8dee2aaSAndroid Build Coastguard Worker                                                  freeWhenDone:NO];
60*c8dee2aaSAndroid Build Coastguard Worker    if (!nsSource) {
61*c8dee2aaSAndroid Build Coastguard Worker        return nil;
62*c8dee2aaSAndroid Build Coastguard Worker    }
63*c8dee2aaSAndroid Build Coastguard Worker    MTLCompileOptions* options = [[MTLCompileOptions alloc] init];
64*c8dee2aaSAndroid Build Coastguard Worker    // array<> is supported in MSL 2.0 on MacOS 10.13+ and iOS 11+,
65*c8dee2aaSAndroid Build Coastguard Worker    // and in MSL 1.2 on iOS 10+ (but not MacOS).
66*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
67*c8dee2aaSAndroid Build Coastguard Worker        options.languageVersion = MTLLanguageVersion2_0;
68*c8dee2aaSAndroid Build Coastguard Worker#if defined(SK_BUILD_FOR_IOS)
69*c8dee2aaSAndroid Build Coastguard Worker    } else if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
70*c8dee2aaSAndroid Build Coastguard Worker        options.languageVersion = MTLLanguageVersion1_2;
71*c8dee2aaSAndroid Build Coastguard Worker#endif
72*c8dee2aaSAndroid Build Coastguard Worker    }
73*c8dee2aaSAndroid Build Coastguard Worker    options.fastMathEnabled = YES;
74*c8dee2aaSAndroid Build Coastguard Worker
75*c8dee2aaSAndroid Build Coastguard Worker    NSError* error = nil;
76*c8dee2aaSAndroid Build Coastguard Worker    id<MTLLibrary> compiledLibrary;
77*c8dee2aaSAndroid Build Coastguard Worker    if (@available(macOS 10.15, *)) {
78*c8dee2aaSAndroid Build Coastguard Worker        compiledLibrary = [gpu->device() newLibraryWithSource:(NSString* _Nonnull)nsSource
79*c8dee2aaSAndroid Build Coastguard Worker                                                      options:options
80*c8dee2aaSAndroid Build Coastguard Worker                                                        error:&error];
81*c8dee2aaSAndroid Build Coastguard Worker    } else {
82*c8dee2aaSAndroid Build Coastguard Worker        compiledLibrary = GrMtlNewLibraryWithSource(gpu->device(), (NSString* _Nonnull)nsSource,
83*c8dee2aaSAndroid Build Coastguard Worker                                                    options, &error);
84*c8dee2aaSAndroid Build Coastguard Worker    }
85*c8dee2aaSAndroid Build Coastguard Worker    if (!compiledLibrary) {
86*c8dee2aaSAndroid Build Coastguard Worker        errorHandler->compileError(
87*c8dee2aaSAndroid Build Coastguard Worker                msl.c_str(), error.debugDescription.UTF8String, /*shaderWasCached=*/false);
88*c8dee2aaSAndroid Build Coastguard Worker        return nil;
89*c8dee2aaSAndroid Build Coastguard Worker    }
90*c8dee2aaSAndroid Build Coastguard Worker
91*c8dee2aaSAndroid Build Coastguard Worker    return compiledLibrary;
92*c8dee2aaSAndroid Build Coastguard Worker}
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Workervoid GrPrecompileMtlShaderLibrary(const GrMtlGpu* gpu,
95*c8dee2aaSAndroid Build Coastguard Worker                                  const std::string& msl) {
96*c8dee2aaSAndroid Build Coastguard Worker    NSString* nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
97*c8dee2aaSAndroid Build Coastguard Worker                                                        length:msl.size()
98*c8dee2aaSAndroid Build Coastguard Worker                                                      encoding:NSUTF8StringEncoding
99*c8dee2aaSAndroid Build Coastguard Worker                                                  freeWhenDone:NO];
100*c8dee2aaSAndroid Build Coastguard Worker    if (!nsSource) {
101*c8dee2aaSAndroid Build Coastguard Worker        return;
102*c8dee2aaSAndroid Build Coastguard Worker    }
103*c8dee2aaSAndroid Build Coastguard Worker    // Do nothing after completion for now.
104*c8dee2aaSAndroid Build Coastguard Worker    // TODO: cache the result somewhere so we can use it later.
105*c8dee2aaSAndroid Build Coastguard Worker    MTLNewLibraryCompletionHandler completionHandler = ^(id<MTLLibrary> library, NSError* error) {};
106*c8dee2aaSAndroid Build Coastguard Worker    [gpu->device() newLibraryWithSource:(NSString* _Nonnull)nsSource
107*c8dee2aaSAndroid Build Coastguard Worker                                options:nil
108*c8dee2aaSAndroid Build Coastguard Worker                      completionHandler:completionHandler];
109*c8dee2aaSAndroid Build Coastguard Worker}
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker// Wrapper to get atomic assignment for compiles and pipeline creation
112*c8dee2aaSAndroid Build Coastguard Workerclass MtlCompileResult : public SkRefCnt {
113*c8dee2aaSAndroid Build Coastguard Workerpublic:
114*c8dee2aaSAndroid Build Coastguard Worker    MtlCompileResult() : fCompiledObject(nil), fError(nil) {}
115*c8dee2aaSAndroid Build Coastguard Worker    void set(id compiledObject, NSError* error) {
116*c8dee2aaSAndroid Build Coastguard Worker        SkAutoMutexExclusive automutex(fMutex);
117*c8dee2aaSAndroid Build Coastguard Worker        fCompiledObject = compiledObject;
118*c8dee2aaSAndroid Build Coastguard Worker        fError = error;
119*c8dee2aaSAndroid Build Coastguard Worker    }
120*c8dee2aaSAndroid Build Coastguard Worker    std::pair<id, NSError*> get() {
121*c8dee2aaSAndroid Build Coastguard Worker        SkAutoMutexExclusive automutex(fMutex);
122*c8dee2aaSAndroid Build Coastguard Worker        return std::make_pair(fCompiledObject, fError);
123*c8dee2aaSAndroid Build Coastguard Worker    }
124*c8dee2aaSAndroid Build Coastguard Workerprivate:
125*c8dee2aaSAndroid Build Coastguard Worker    SkMutex fMutex;
126*c8dee2aaSAndroid Build Coastguard Worker    id fCompiledObject SK_GUARDED_BY(fMutex);
127*c8dee2aaSAndroid Build Coastguard Worker    NSError* fError SK_GUARDED_BY(fMutex);
128*c8dee2aaSAndroid Build Coastguard Worker};
129*c8dee2aaSAndroid Build Coastguard Worker
130*c8dee2aaSAndroid Build Coastguard Workerid<MTLLibrary> GrMtlNewLibraryWithSource(id<MTLDevice> device, NSString* mslCode,
131*c8dee2aaSAndroid Build Coastguard Worker                                         MTLCompileOptions* options, NSError** error) {
132*c8dee2aaSAndroid Build Coastguard Worker    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
133*c8dee2aaSAndroid Build Coastguard Worker    sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
134*c8dee2aaSAndroid Build Coastguard Worker    // We have to increment the ref for the Obj-C block manually because it won't do it for us
135*c8dee2aaSAndroid Build Coastguard Worker    compileResult->ref();
136*c8dee2aaSAndroid Build Coastguard Worker    MTLNewLibraryCompletionHandler completionHandler =
137*c8dee2aaSAndroid Build Coastguard Worker            ^(id<MTLLibrary> library, NSError* compileError) {
138*c8dee2aaSAndroid Build Coastguard Worker                compileResult->set(library, compileError);
139*c8dee2aaSAndroid Build Coastguard Worker                dispatch_semaphore_signal(semaphore);
140*c8dee2aaSAndroid Build Coastguard Worker                compileResult->unref();
141*c8dee2aaSAndroid Build Coastguard Worker            };
142*c8dee2aaSAndroid Build Coastguard Worker
143*c8dee2aaSAndroid Build Coastguard Worker    [device newLibraryWithSource: mslCode
144*c8dee2aaSAndroid Build Coastguard Worker                         options: options
145*c8dee2aaSAndroid Build Coastguard Worker               completionHandler: completionHandler];
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker    // Wait 1 second for the compiler
148*c8dee2aaSAndroid Build Coastguard Worker    constexpr auto kTimeoutNS = 1000000000UL;
149*c8dee2aaSAndroid Build Coastguard Worker    if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
150*c8dee2aaSAndroid Build Coastguard Worker        if (error) {
151*c8dee2aaSAndroid Build Coastguard Worker            constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
152*c8dee2aaSAndroid Build Coastguard Worker            NSString* description =
153*c8dee2aaSAndroid Build Coastguard Worker                    [NSString stringWithFormat:@"Compilation took longer than %lu ms",
154*c8dee2aaSAndroid Build Coastguard Worker                                               kTimeoutMS];
155*c8dee2aaSAndroid Build Coastguard Worker            *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
156*c8dee2aaSAndroid Build Coastguard Worker        }
157*c8dee2aaSAndroid Build Coastguard Worker        return nil;
158*c8dee2aaSAndroid Build Coastguard Worker    }
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker    id<MTLLibrary> compiledLibrary;
161*c8dee2aaSAndroid Build Coastguard Worker    std::tie(compiledLibrary, *error) = compileResult->get();
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker    return compiledLibrary;
164*c8dee2aaSAndroid Build Coastguard Worker}
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Workerid<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
167*c8dee2aaSAndroid Build Coastguard Worker        id<MTLDevice> device, MTLRenderPipelineDescriptor* pipelineDescriptor, NSError** error) {
168*c8dee2aaSAndroid Build Coastguard Worker    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
169*c8dee2aaSAndroid Build Coastguard Worker    sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
170*c8dee2aaSAndroid Build Coastguard Worker    // We have to increment the ref for the Obj-C block manually because it won't do it for us
171*c8dee2aaSAndroid Build Coastguard Worker    compileResult->ref();
172*c8dee2aaSAndroid Build Coastguard Worker    MTLNewRenderPipelineStateCompletionHandler completionHandler =
173*c8dee2aaSAndroid Build Coastguard Worker            ^(id<MTLRenderPipelineState> state, NSError* compileError) {
174*c8dee2aaSAndroid Build Coastguard Worker                compileResult->set(state, compileError);
175*c8dee2aaSAndroid Build Coastguard Worker                dispatch_semaphore_signal(semaphore);
176*c8dee2aaSAndroid Build Coastguard Worker                compileResult->unref();
177*c8dee2aaSAndroid Build Coastguard Worker            };
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker    [device newRenderPipelineStateWithDescriptor: pipelineDescriptor
180*c8dee2aaSAndroid Build Coastguard Worker                               completionHandler: completionHandler];
181*c8dee2aaSAndroid Build Coastguard Worker
182*c8dee2aaSAndroid Build Coastguard Worker    // Wait 1 second for pipeline creation
183*c8dee2aaSAndroid Build Coastguard Worker    constexpr auto kTimeoutNS = 1000000000UL;
184*c8dee2aaSAndroid Build Coastguard Worker    if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
185*c8dee2aaSAndroid Build Coastguard Worker        if (error) {
186*c8dee2aaSAndroid Build Coastguard Worker            constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
187*c8dee2aaSAndroid Build Coastguard Worker            NSString* description =
188*c8dee2aaSAndroid Build Coastguard Worker                    [NSString stringWithFormat:@"Pipeline creation took longer than %lu ms",
189*c8dee2aaSAndroid Build Coastguard Worker                                               kTimeoutMS];
190*c8dee2aaSAndroid Build Coastguard Worker            *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
191*c8dee2aaSAndroid Build Coastguard Worker        }
192*c8dee2aaSAndroid Build Coastguard Worker        return nil;
193*c8dee2aaSAndroid Build Coastguard Worker    }
194*c8dee2aaSAndroid Build Coastguard Worker
195*c8dee2aaSAndroid Build Coastguard Worker    id<MTLRenderPipelineState> pipelineState;
196*c8dee2aaSAndroid Build Coastguard Worker    std::tie(pipelineState, *error) = compileResult->get();
197*c8dee2aaSAndroid Build Coastguard Worker
198*c8dee2aaSAndroid Build Coastguard Worker    return pipelineState;
199*c8dee2aaSAndroid Build Coastguard Worker}
200*c8dee2aaSAndroid Build Coastguard Worker
201*c8dee2aaSAndroid Build Coastguard Workerid<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface) {
202*c8dee2aaSAndroid Build Coastguard Worker    id<MTLTexture> mtlTexture = nil;
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker    GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
205*c8dee2aaSAndroid Build Coastguard Worker    GrMtlTexture* texture;
206*c8dee2aaSAndroid Build Coastguard Worker    if (renderTarget) {
207*c8dee2aaSAndroid Build Coastguard Worker        // We should not be using this for multisampled rendertargets with a separate resolve
208*c8dee2aaSAndroid Build Coastguard Worker        // texture.
209*c8dee2aaSAndroid Build Coastguard Worker        if (renderTarget->resolveAttachment()) {
210*c8dee2aaSAndroid Build Coastguard Worker            SkASSERT(renderTarget->numSamples() > 1);
211*c8dee2aaSAndroid Build Coastguard Worker            SkASSERT(false);
212*c8dee2aaSAndroid Build Coastguard Worker            return nil;
213*c8dee2aaSAndroid Build Coastguard Worker        }
214*c8dee2aaSAndroid Build Coastguard Worker        mtlTexture = renderTarget->colorMTLTexture();
215*c8dee2aaSAndroid Build Coastguard Worker    } else {
216*c8dee2aaSAndroid Build Coastguard Worker        texture = static_cast<GrMtlTexture*>(surface->asTexture());
217*c8dee2aaSAndroid Build Coastguard Worker        if (texture) {
218*c8dee2aaSAndroid Build Coastguard Worker            mtlTexture = texture->mtlTexture();
219*c8dee2aaSAndroid Build Coastguard Worker        }
220*c8dee2aaSAndroid Build Coastguard Worker    }
221*c8dee2aaSAndroid Build Coastguard Worker    return mtlTexture;
222*c8dee2aaSAndroid Build Coastguard Worker}
223*c8dee2aaSAndroid Build Coastguard Worker
224*c8dee2aaSAndroid Build Coastguard Worker
225*c8dee2aaSAndroid Build Coastguard Worker//////////////////////////////////////////////////////////////////////////////
226*c8dee2aaSAndroid Build Coastguard Worker// CPP Utils
227*c8dee2aaSAndroid Build Coastguard Worker
228*c8dee2aaSAndroid Build Coastguard WorkerGrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo& info) {
229*c8dee2aaSAndroid Build Coastguard Worker    id<MTLTexture> GR_NORETAIN mtlTexture = GrGetMTLTexture(info.fTexture.get());
230*c8dee2aaSAndroid Build Coastguard Worker    return static_cast<GrMTLPixelFormat>(mtlTexture.pixelFormat);
231*c8dee2aaSAndroid Build Coastguard Worker}
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard WorkerGrColorFormatDesc GrMtlFormatDesc(MTLPixelFormat mtlFormat) {
234*c8dee2aaSAndroid Build Coastguard Worker    switch (mtlFormat) {
235*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRGBA8Unorm:
236*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
237*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatR8Unorm:
238*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
239*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatA8Unorm:
240*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
241*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatBGRA8Unorm:
242*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
243*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatB5G6R5Unorm:
244*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
245*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRGBA16Float:
246*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
247*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatR16Float:
248*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
249*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRG8Unorm:
250*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
251*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRGB10A2Unorm:
252*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
253*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatBGR10A2Unorm:
254*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
255*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatABGR4Unorm:
256*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
257*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRGBA8Unorm_sRGB:
258*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
259*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatR16Unorm:
260*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
261*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRG16Unorm:
262*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
263*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRGBA16Unorm:
264*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
265*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatRG16Float:
266*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
267*c8dee2aaSAndroid Build Coastguard Worker
268*c8dee2aaSAndroid Build Coastguard Worker        // Compressed texture formats are not expected to have a description.
269*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatETC2_RGB8: return GrColorFormatDesc::MakeInvalid();
270*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
271*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatBC1_RGBA:  return GrColorFormatDesc::MakeInvalid();
272*c8dee2aaSAndroid Build Coastguard Worker#endif
273*c8dee2aaSAndroid Build Coastguard Worker
274*c8dee2aaSAndroid Build Coastguard Worker        // This type only describes color channels.
275*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatStencil8: return GrColorFormatDesc::MakeInvalid();
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker        default:
278*c8dee2aaSAndroid Build Coastguard Worker            return GrColorFormatDesc::MakeInvalid();
279*c8dee2aaSAndroid Build Coastguard Worker    }
280*c8dee2aaSAndroid Build Coastguard Worker}
281*c8dee2aaSAndroid Build Coastguard Worker
282*c8dee2aaSAndroid Build Coastguard WorkerSkTextureCompressionType GrMtlFormatToCompressionType(MTLPixelFormat format) {
283*c8dee2aaSAndroid Build Coastguard Worker    switch (format) {
284*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatETC2_RGB8: return SkTextureCompressionType::kETC2_RGB8_UNORM;
285*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_BUILD_FOR_MAC
286*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatBC1_RGBA:  return SkTextureCompressionType::kBC1_RGBA8_UNORM;
287*c8dee2aaSAndroid Build Coastguard Worker#endif
288*c8dee2aaSAndroid Build Coastguard Worker        default:                      return SkTextureCompressionType::kNone;
289*c8dee2aaSAndroid Build Coastguard Worker    }
290*c8dee2aaSAndroid Build Coastguard Worker
291*c8dee2aaSAndroid Build Coastguard Worker    SkUNREACHABLE;
292*c8dee2aaSAndroid Build Coastguard Worker}
293*c8dee2aaSAndroid Build Coastguard Worker
294*c8dee2aaSAndroid Build Coastguard Workerint GrMtlTextureInfoSampleCount(const GrMtlTextureInfo& info) {
295*c8dee2aaSAndroid Build Coastguard Worker    id<MTLTexture> texture = GrGetMTLTexture(info.fTexture.get());
296*c8dee2aaSAndroid Build Coastguard Worker    if (!texture) {
297*c8dee2aaSAndroid Build Coastguard Worker        return 0;
298*c8dee2aaSAndroid Build Coastguard Worker    }
299*c8dee2aaSAndroid Build Coastguard Worker    return texture.sampleCount;
300*c8dee2aaSAndroid Build Coastguard Worker}
301*c8dee2aaSAndroid Build Coastguard Worker
302*c8dee2aaSAndroid Build Coastguard Workerint GrMtlFormatStencilBits(MTLPixelFormat format) {
303*c8dee2aaSAndroid Build Coastguard Worker    switch (format) {
304*c8dee2aaSAndroid Build Coastguard Worker        case MTLPixelFormatStencil8:
305*c8dee2aaSAndroid Build Coastguard Worker            return 8;
306*c8dee2aaSAndroid Build Coastguard Worker        default:
307*c8dee2aaSAndroid Build Coastguard Worker            return 0;
308*c8dee2aaSAndroid Build Coastguard Worker    }
309*c8dee2aaSAndroid Build Coastguard Worker}
310*c8dee2aaSAndroid Build Coastguard Worker
311*c8dee2aaSAndroid Build Coastguard Worker#if defined(SK_DEBUG) || defined(GPU_TEST_UTILS)
312*c8dee2aaSAndroid Build Coastguard Workerbool GrMtlFormatIsBGRA8(GrMTLPixelFormat mtlFormat) {
313*c8dee2aaSAndroid Build Coastguard Worker    return mtlFormat == MTLPixelFormatBGRA8Unorm;
314*c8dee2aaSAndroid Build Coastguard Worker}
315*c8dee2aaSAndroid Build Coastguard Worker#endif
316*c8dee2aaSAndroid Build Coastguard Worker
317*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_END
318