1*c8dee2aaSAndroid Build Coastguard Worker/* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 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 "include/gpu/graphite/mtl/MtlGraphiteUtils.h" 9*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteUtilsPriv.h" 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ShaderErrorHandler.h" 12*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/Context.h" 13*c8dee2aaSAndroid Build Coastguard Worker#include "src/core/SkTraceEvent.h" 14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/ContextPriv.h" 15*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlQueueManager.h" 16*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlSharedContext.h" 17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h" 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Workernamespace skgpu::graphite { 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Workernamespace ContextFactory { 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Workerstd::unique_ptr<Context> MakeMetal(const MtlBackendContext& backendContext, 24*c8dee2aaSAndroid Build Coastguard Worker const ContextOptions& options) { 25*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SharedContext> sharedContext = MtlSharedContext::Make(backendContext, options); 26*c8dee2aaSAndroid Build Coastguard Worker if (!sharedContext) { 27*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 28*c8dee2aaSAndroid Build Coastguard Worker } 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker sk_cfp<id<MTLCommandQueue>> queue = 31*c8dee2aaSAndroid Build Coastguard Worker sk_ret_cfp((id<MTLCommandQueue>)(backendContext.fQueue.get())); 32*c8dee2aaSAndroid Build Coastguard Worker auto queueManager = std::make_unique<MtlQueueManager>(std::move(queue), sharedContext.get()); 33*c8dee2aaSAndroid Build Coastguard Worker if (!queueManager) { 34*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 35*c8dee2aaSAndroid Build Coastguard Worker } 36*c8dee2aaSAndroid Build Coastguard Worker 37*c8dee2aaSAndroid Build Coastguard Worker return ContextCtorAccessor::MakeContext(std::move(sharedContext), 38*c8dee2aaSAndroid Build Coastguard Worker std::move(queueManager), 39*c8dee2aaSAndroid Build Coastguard Worker options); 40*c8dee2aaSAndroid Build Coastguard Worker} 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker} // namespace ContextFactory 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Workersk_cfp<id<MTLLibrary>> MtlCompileShaderLibrary(const MtlSharedContext* sharedContext, 45*c8dee2aaSAndroid Build Coastguard Worker std::string_view label, 46*c8dee2aaSAndroid Build Coastguard Worker std::string_view msl, 47*c8dee2aaSAndroid Build Coastguard Worker ShaderErrorHandler* errorHandler) { 48*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", "driver_compile_shader"); 49*c8dee2aaSAndroid Build Coastguard Worker NSString* nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.data()) 50*c8dee2aaSAndroid Build Coastguard Worker length:msl.size() 51*c8dee2aaSAndroid Build Coastguard Worker encoding:NSUTF8StringEncoding 52*c8dee2aaSAndroid Build Coastguard Worker freeWhenDone:NO]; 53*c8dee2aaSAndroid Build Coastguard Worker if (!nsSource) { 54*c8dee2aaSAndroid Build Coastguard Worker return nil; 55*c8dee2aaSAndroid Build Coastguard Worker } 56*c8dee2aaSAndroid Build Coastguard Worker MTLCompileOptions* options = [[MTLCompileOptions alloc] init]; 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker // Framebuffer fetch is supported in MSL 2.3 in MacOS 11+. 59*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { 60*c8dee2aaSAndroid Build Coastguard Worker options.languageVersion = MTLLanguageVersion2_3; 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker // array<> is supported in MSL 2.0 on MacOS 10.13+ and iOS 11+, 63*c8dee2aaSAndroid Build Coastguard Worker // and in MSL 1.2 on iOS 10+ (but not MacOS). 64*c8dee2aaSAndroid Build Coastguard Worker } else if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { 65*c8dee2aaSAndroid Build Coastguard Worker options.languageVersion = MTLLanguageVersion2_0; 66*c8dee2aaSAndroid Build Coastguard Worker#if defined(SK_BUILD_FOR_IOS) 67*c8dee2aaSAndroid Build Coastguard Worker } else if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) { 68*c8dee2aaSAndroid Build Coastguard Worker options.languageVersion = MTLLanguageVersion1_2; 69*c8dee2aaSAndroid Build Coastguard Worker#endif 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker NSError* error = nil; 73*c8dee2aaSAndroid Build Coastguard Worker // TODO: do we need a version with a timeout? 74*c8dee2aaSAndroid Build Coastguard Worker sk_cfp<id<MTLLibrary>> compiledLibrary( 75*c8dee2aaSAndroid Build Coastguard Worker [sharedContext->device() newLibraryWithSource:(NSString* _Nonnull)nsSource 76*c8dee2aaSAndroid Build Coastguard Worker options:options 77*c8dee2aaSAndroid Build Coastguard Worker error:&error]); 78*c8dee2aaSAndroid Build Coastguard Worker if (!compiledLibrary) { 79*c8dee2aaSAndroid Build Coastguard Worker std::string mslStr(msl); 80*c8dee2aaSAndroid Build Coastguard Worker errorHandler->compileError( 81*c8dee2aaSAndroid Build Coastguard Worker mslStr.c_str(), error.debugDescription.UTF8String, /*shaderWasCached=*/false); 82*c8dee2aaSAndroid Build Coastguard Worker return nil; 83*c8dee2aaSAndroid Build Coastguard Worker } 84*c8dee2aaSAndroid Build Coastguard Worker 85*c8dee2aaSAndroid Build Coastguard Worker NSString* nsLabel = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(label.data()) 86*c8dee2aaSAndroid Build Coastguard Worker length:label.size() 87*c8dee2aaSAndroid Build Coastguard Worker encoding:NSUTF8StringEncoding 88*c8dee2aaSAndroid Build Coastguard Worker freeWhenDone:NO]; 89*c8dee2aaSAndroid Build Coastguard Worker compiledLibrary.get().label = nsLabel; 90*c8dee2aaSAndroid Build Coastguard Worker return compiledLibrary; 91*c8dee2aaSAndroid Build Coastguard Worker} 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker} // namespace skgpu::graphite 94