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