1/* 2 * Copyright 2021 Google LLC 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 "include/core/SkStream.h" 9#include "include/gpu/ShaderErrorHandler.h" 10#include "include/gpu/graphite/Context.h" 11#include "include/gpu/graphite/mtl/MtlBackendContext.h" 12#include "src/core/SkTraceEvent.h" 13#include "src/gpu/graphite/ContextPriv.h" 14#include "src/gpu/graphite/TextureFormat.h" 15#include "src/gpu/graphite/mtl/MtlGraphiteUtils.h" 16#include "src/gpu/graphite/mtl/MtlQueueManager.h" 17#include "src/gpu/graphite/mtl/MtlSharedContext.h" 18#include "src/gpu/mtl/MtlUtilsPriv.h" 19 20#import <Metal/Metal.h> 21 22namespace skgpu::graphite { 23 24namespace ContextFactory { 25 26std::unique_ptr<Context> MakeMetal(const MtlBackendContext& backendContext, 27 const ContextOptions& options) { 28 sk_sp<SharedContext> sharedContext = MtlSharedContext::Make(backendContext, options); 29 if (!sharedContext) { 30 return nullptr; 31 } 32 33 sk_cfp<id<MTLCommandQueue>> queue = 34 sk_ret_cfp((id<MTLCommandQueue>)(backendContext.fQueue.get())); 35 auto queueManager = std::make_unique<MtlQueueManager>(std::move(queue), sharedContext.get()); 36 if (!queueManager) { 37 return nullptr; 38 } 39 40 return ContextCtorAccessor::MakeContext(std::move(sharedContext), 41 std::move(queueManager), 42 options); 43} 44 45} // namespace ContextFactory 46 47sk_cfp<id<MTLLibrary>> MtlCompileShaderLibrary(const MtlSharedContext* sharedContext, 48 std::string_view label, 49 std::string_view msl, 50 ShaderErrorHandler* errorHandler) { 51 TRACE_EVENT0("skia.shaders", "driver_compile_shader"); 52 NSString* nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.data()) 53 length:msl.size() 54 encoding:NSUTF8StringEncoding 55 freeWhenDone:NO]; 56 if (!nsSource) { 57 return nil; 58 } 59 MTLCompileOptions* options = [[MTLCompileOptions alloc] init]; 60 61 // Framebuffer fetch is supported in MSL 2.3 in MacOS 11+. 62 if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { 63 options.languageVersion = MTLLanguageVersion2_3; 64 65 // array<> is supported in MSL 2.0 on MacOS 10.13+ and iOS 11+, 66 // and in MSL 1.2 on iOS 10+ (but not MacOS). 67 } else if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { 68 options.languageVersion = MTLLanguageVersion2_0; 69#if defined(SK_BUILD_FOR_IOS) 70 } else if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) { 71 options.languageVersion = MTLLanguageVersion1_2; 72#endif 73 } 74 75 NSError* error = nil; 76 // TODO: do we need a version with a timeout? 77 sk_cfp<id<MTLLibrary>> compiledLibrary( 78 [sharedContext->device() newLibraryWithSource:(NSString* _Nonnull)nsSource 79 options:options 80 error:&error]); 81 if (!compiledLibrary) { 82 std::string mslStr(msl); 83 errorHandler->compileError( 84 mslStr.c_str(), error.debugDescription.UTF8String, /*shaderWasCached=*/false); 85 return nil; 86 } 87 88 NSString* nsLabel = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(label.data()) 89 length:label.size() 90 encoding:NSUTF8StringEncoding 91 freeWhenDone:NO]; 92 compiledLibrary.get().label = nsLabel; 93 return compiledLibrary; 94} 95 96TextureFormat MTLPixelFormatToTextureFormat(MTLPixelFormat format) { 97 switch (format) { 98 case MTLPixelFormatR8Unorm: return TextureFormat::kR8; 99 case MTLPixelFormatR16Unorm: return TextureFormat::kR16; 100 case MTLPixelFormatR16Float: return TextureFormat::kR16F; 101 case MTLPixelFormatR32Float: return TextureFormat::kR32F; 102 case MTLPixelFormatA8Unorm: return TextureFormat::kA8; 103 case MTLPixelFormatRG8Unorm: return TextureFormat::kRG8; 104 case MTLPixelFormatRG16Unorm: return TextureFormat::kRG16; 105 case MTLPixelFormatRG16Float: return TextureFormat::kRG16F; 106 case MTLPixelFormatRG32Float: return TextureFormat::kRG32F; 107 case MTLPixelFormatB5G6R5Unorm: return TextureFormat::kB5_G6_R5; 108 case MTLPixelFormatBGR10_XR: return TextureFormat::kBGR10_XR; 109 case MTLPixelFormatRGBA8Unorm: return TextureFormat::kRGBA8; 110 case MTLPixelFormatRGBA16Unorm: return TextureFormat::kRGBA16; 111 case MTLPixelFormatRGBA32Float: return TextureFormat::kRGBA32F; 112 case MTLPixelFormatRGB10A2Unorm: return TextureFormat::kRGB10_A2; 113 case MTLPixelFormatRGBA8Unorm_sRGB: return TextureFormat::kRGBA8_sRGB; 114 case MTLPixelFormatBGRA8Unorm: return TextureFormat::kBGRA8; 115 case MTLPixelFormatBGR10A2Unorm: return TextureFormat::kBGR10_A2; 116 case MTLPixelFormatBGRA8Unorm_sRGB: return TextureFormat::kBGRA8_sRGB; 117 case MTLPixelFormatABGR4Unorm: return TextureFormat::kABGR4; 118 case MTLPixelFormatBGRA10_XR: return TextureFormat::kBGRA10x6_XR; 119 case MTLPixelFormatETC2_RGB8: return TextureFormat::kRGB8_ETC2; 120 case MTLPixelFormatETC2_RGB8_sRGB: return TextureFormat::kRGB8_ETC2_sRGB; 121 case MTLPixelFormatStencil8: return TextureFormat::kS8; 122 case MTLPixelFormatDepth16Unorm: return TextureFormat::kD16; 123 case MTLPixelFormatDepth32Float: return TextureFormat::kD32F; 124 case MTLPixelFormatDepth32Float_Stencil8: return TextureFormat::kD32F_S8; 125#if defined(SK_BUILD_FOR_MAC) 126 case MTLPixelFormatDepth24Unorm_Stencil8: return TextureFormat::kD24_S8; 127 case MTLPixelFormatBC1_RGBA: return TextureFormat::kRGBA8_BC1; 128 case MTLPixelFormatBC1_RGBA_sRGB: return TextureFormat::kRGBA8_BC1_sRGB; 129#endif 130 default: return TextureFormat::kUnsupported; 131 } 132} 133 134} // namespace skgpu::graphite 135