• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2017 Google Inc.
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 "GrMtlUtil.h"
9
10#include "GrTypesPriv.h"
11#include "GrSurface.h"
12#include "mtl/GrMtlGpu.h"
13#include "mtl/GrMtlTexture.h"
14#include "mtl/GrMtlRenderTarget.h"
15#include "SkSLCompiler.h"
16
17#import <Metal/Metal.h>
18
19#define PRINT_MSL 0 // print out the MSL code generated
20
21bool GrPixelConfigToMTLFormat(GrPixelConfig config, MTLPixelFormat* format) {
22    MTLPixelFormat dontCare;
23    if (!format) {
24        format = &dontCare;
25    }
26
27    switch (config) {
28        case kUnknown_GrPixelConfig:
29            return false;
30        case kRGBA_8888_GrPixelConfig:
31            *format = MTLPixelFormatRGBA8Unorm;
32            return true;
33        case kRGB_888_GrPixelConfig:
34            // TODO: MTLPixelFormatRGB8Unorm
35            return false;
36        case kRGB_888X_GrPixelConfig:
37            *format = MTLPixelFormatRGBA8Unorm;
38            return true;
39        case kRG_88_GrPixelConfig:
40            // TODO: MTLPixelFormatRG8Unorm
41            return false;
42        case kBGRA_8888_GrPixelConfig:
43            *format = MTLPixelFormatBGRA8Unorm;
44            return true;
45        case kSRGBA_8888_GrPixelConfig:
46            *format = MTLPixelFormatRGBA8Unorm_sRGB;
47            return true;
48        case kSBGRA_8888_GrPixelConfig:
49            *format = MTLPixelFormatBGRA8Unorm_sRGB;
50            return true;
51        case kRGBA_1010102_GrPixelConfig:
52            *format = MTLPixelFormatRGB10A2Unorm;
53            return true;
54        case kRGB_565_GrPixelConfig:
55#ifdef SK_BUILD_FOR_IOS
56            *format = MTLPixelFormatB5G6R5Unorm;
57            return true;
58#else
59            return false;
60#endif
61        case kRGBA_4444_GrPixelConfig:
62#ifdef SK_BUILD_FOR_IOS
63            *format = MTLPixelFormatABGR4Unorm;
64            return true;
65#else
66            return false;
67#endif
68        case kAlpha_8_GrPixelConfig: // fall through
69        case kAlpha_8_as_Red_GrPixelConfig:
70            *format = MTLPixelFormatR8Unorm;
71            return true;
72        case kAlpha_8_as_Alpha_GrPixelConfig:
73            return false;
74        case kGray_8_GrPixelConfig: // fall through
75        case kGray_8_as_Red_GrPixelConfig:
76            *format = MTLPixelFormatR8Unorm;
77            return true;
78        case kGray_8_as_Lum_GrPixelConfig:
79            return false;
80        case kRGBA_float_GrPixelConfig:
81            *format = MTLPixelFormatRGBA32Float;
82            return true;
83        case kRG_float_GrPixelConfig:
84            *format = MTLPixelFormatRG32Float;
85            return true;
86        case kRGBA_half_GrPixelConfig:
87            *format = MTLPixelFormatRGBA16Float;
88            return true;
89        case kRGBA_half_Clamped_GrPixelConfig:
90            *format = MTLPixelFormatRGBA16Float;
91            return true;
92        case kAlpha_half_GrPixelConfig: // fall through
93        case kAlpha_half_as_Red_GrPixelConfig:
94            *format = MTLPixelFormatR16Float;
95            return true;
96        case kRGB_ETC1_GrPixelConfig:
97#ifdef SK_BUILD_FOR_IOS
98            *format = MTLPixelFormatETC2_RGB8;
99            return true;
100#else
101            return false;
102#endif
103    }
104    SK_ABORT("Unexpected config");
105    return false;
106}
107
108id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership wrapOwnership) {
109    if (GrWrapOwnership::kAdopt_GrWrapOwnership == wrapOwnership) {
110        return (__bridge_transfer id<MTLTexture>)mtlTexture;
111    } else {
112        return (__bridge id<MTLTexture>)mtlTexture;
113    }
114}
115
116const void* GrGetPtrFromId(id idObject) {
117    return (__bridge const void*)idObject;
118}
119
120const void* GrReleaseId(id idObject) {
121    return (__bridge_retained const void*)idObject;
122}
123
124MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
125    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
126    texDesc.textureType = mtlTexture.textureType;
127    texDesc.pixelFormat = mtlTexture.pixelFormat;
128    texDesc.width = mtlTexture.width;
129    texDesc.height = mtlTexture.height;
130    texDesc.depth = mtlTexture.depth;
131    texDesc.mipmapLevelCount = mtlTexture.mipmapLevelCount;
132    texDesc.arrayLength = mtlTexture.arrayLength;
133    texDesc.sampleCount = mtlTexture.sampleCount;
134    texDesc.usage = mtlTexture.usage;
135    return texDesc;
136}
137
138#if PRINT_MSL
139void print_msl(const char* source) {
140    SkTArray<SkString> lines;
141    SkStrSplit(source, "\n", kStrict_SkStrSplitMode, &lines);
142    for (int i = 0; i < lines.count(); i++) {
143        SkString& line = lines[i];
144        line.prependf("%4i\t", i + 1);
145        SkDebugf("%s\n", line.c_str());
146    }
147}
148#endif
149
150id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
151                                         const char* shaderString,
152                                         SkSL::Program::Kind kind,
153                                         const SkSL::Program::Settings& settings,
154                                         SkSL::Program::Inputs* outInputs) {
155    std::unique_ptr<SkSL::Program> program =
156            gpu->shaderCompiler()->convertProgram(kind,
157                                                  SkSL::String(shaderString),
158                                                  settings);
159
160    if (!program) {
161        SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
162        SkASSERT(false);
163    }
164
165    *outInputs = program->fInputs;
166    SkSL::String code;
167    if (!gpu->shaderCompiler()->toMetal(*program, &code)) {
168        SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
169        SkASSERT(false);
170        return nil;
171    }
172    NSString* mtlCode = [[NSString alloc] initWithCString: code.c_str()
173                                                 encoding: NSASCIIStringEncoding];
174#if PRINT_MSL
175    print_msl([mtlCode cStringUsingEncoding: NSASCIIStringEncoding]);
176#endif
177
178    MTLCompileOptions* defaultOptions = [[MTLCompileOptions alloc] init];
179    NSError* error = nil;
180    id<MTLLibrary> compiledLibrary = [gpu->device() newLibraryWithSource: mtlCode
181                                                                 options: defaultOptions
182                                                                   error: &error];
183    if (error) {
184        SkDebugf("Error compiling MSL shader: %s\n",
185                 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
186        return nil;
187    }
188    return compiledLibrary;
189}
190
191id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface, bool doResolve) {
192    id<MTLTexture> mtlTexture = nil;
193
194    GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
195    GrMtlTexture* texture;
196    if (renderTarget) {
197        if (doResolve) {
198            // TODO: do resolve and set mtlTexture to resolved texture. As of now, we shouldn't
199            // have any multisampled render targets.
200            SkASSERT(false);
201        } else {
202            mtlTexture = renderTarget->mtlRenderTexture();
203        }
204    } else {
205        texture = static_cast<GrMtlTexture*>(surface->asTexture());
206        if (texture) {
207            mtlTexture = texture->mtlTexture();
208        }
209    }
210    return mtlTexture;
211}
212
213
214//////////////////////////////////////////////////////////////////////////////
215// CPP Utils
216
217GrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo& info) {
218    id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture,
219                                                GrWrapOwnership::kBorrow_GrWrapOwnership);
220    return static_cast<GrMTLPixelFormat>(mtlTexture.pixelFormat);
221}
222