• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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