• 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 kRG_88_GrPixelConfig:
37            // TODO: MTLPixelFormatRG8Unorm
38            return false;
39        case kBGRA_8888_GrPixelConfig:
40            *format = MTLPixelFormatBGRA8Unorm;
41            return true;
42        case kSRGBA_8888_GrPixelConfig:
43            *format = MTLPixelFormatRGBA8Unorm_sRGB;
44            return true;
45        case kSBGRA_8888_GrPixelConfig:
46            *format = MTLPixelFormatBGRA8Unorm_sRGB;
47            return true;
48        case kRGBA_1010102_GrPixelConfig:
49            *format = MTLPixelFormatRGB10A2Unorm;
50            return true;
51        case kRGB_565_GrPixelConfig:
52#ifdef SK_BUILD_FOR_IOS
53            *format = MTLPixelFormatB5G6R5Unorm;
54            return true;
55#else
56            return false;
57#endif
58        case kRGBA_4444_GrPixelConfig:
59#ifdef SK_BUILD_FOR_IOS
60            *format = MTLPixelFormatABGR4Unorm;
61            return true;
62#else
63            return false;
64#endif
65        case kAlpha_8_GrPixelConfig: // fall through
66        case kAlpha_8_as_Red_GrPixelConfig:
67            *format = MTLPixelFormatR8Unorm;
68            return true;
69        case kAlpha_8_as_Alpha_GrPixelConfig:
70            return false;
71        case kGray_8_GrPixelConfig: // fall through
72        case kGray_8_as_Red_GrPixelConfig:
73            *format = MTLPixelFormatR8Unorm;
74            return true;
75        case kGray_8_as_Lum_GrPixelConfig:
76            return false;
77        case kRGBA_float_GrPixelConfig:
78            *format = MTLPixelFormatRGBA32Float;
79            return true;
80        case kRG_float_GrPixelConfig:
81            *format = MTLPixelFormatRG32Float;
82            return true;
83        case kRGBA_half_GrPixelConfig:
84            *format = MTLPixelFormatRGBA16Float;
85            return true;
86        case kAlpha_half_GrPixelConfig: // fall through
87        case kAlpha_half_as_Red_GrPixelConfig:
88            *format = MTLPixelFormatR16Float;
89            return true;
90        case kRGB_ETC1_GrPixelConfig:
91#ifdef SK_BUILD_FOR_IOS
92            *format = MTLPixelFormatETC2_RGB8;
93            return true;
94#else
95            return false;
96#endif
97    }
98    SK_ABORT("Unexpected config");
99    return false;
100}
101
102GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format) {
103    switch (format) {
104        case MTLPixelFormatRGBA8Unorm:
105            return kRGBA_8888_GrPixelConfig;
106        case MTLPixelFormatBGRA8Unorm:
107            return kBGRA_8888_GrPixelConfig;
108        case MTLPixelFormatRGBA8Unorm_sRGB:
109            return kSRGBA_8888_GrPixelConfig;
110        case MTLPixelFormatBGRA8Unorm_sRGB:
111            return kSBGRA_8888_GrPixelConfig;
112        case MTLPixelFormatRGB10A2Unorm:
113            return kRGBA_1010102_GrPixelConfig;
114#ifdef SK_BUILD_FOR_IOS
115        case MTLPixelFormatB5G6R5Unorm:
116            return kRGB_565_GrPixelConfig;
117        case MTLPixelFormatABGR4Unorm:
118            return kRGBA_4444_GrPixelConfig;
119#endif
120        case MTLPixelFormatRG8Unorm:
121            return kRG_88_GrPixelConfig;
122        case MTLPixelFormatR8Unorm:
123            // We currently set this to be Alpha_8 and have no way to go to Gray_8
124            return kAlpha_8_GrPixelConfig;
125        case MTLPixelFormatRGBA32Float:
126            return kRGBA_float_GrPixelConfig;
127        case MTLPixelFormatRG32Float:
128            return kRG_float_GrPixelConfig;
129        case MTLPixelFormatRGBA16Float:
130            return kRGBA_half_GrPixelConfig;
131        case MTLPixelFormatR16Float:
132            return kAlpha_half_GrPixelConfig;
133#ifdef SK_BUILD_FOR_IOS
134        case MTLPixelFormatETC2_RGB8:
135            return kRGB_ETC1_GrPixelConfig;
136#endif
137        default:
138            return kUnknown_GrPixelConfig;
139    }
140}
141
142id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership wrapOwnership) {
143    if (GrWrapOwnership::kAdopt_GrWrapOwnership == wrapOwnership) {
144        return (__bridge_transfer id<MTLTexture>)mtlTexture;
145    } else {
146        return (__bridge id<MTLTexture>)mtlTexture;
147    }
148}
149
150const void* GrGetPtrFromId(id idObject) {
151    return (__bridge const void*)idObject;
152}
153
154const void* GrReleaseId(id idObject) {
155    return (__bridge_retained const void*)idObject;
156}
157
158MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
159    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
160    texDesc.textureType = mtlTexture.textureType;
161    texDesc.pixelFormat = mtlTexture.pixelFormat;
162    texDesc.width = mtlTexture.width;
163    texDesc.height = mtlTexture.height;
164    texDesc.depth = mtlTexture.depth;
165    texDesc.mipmapLevelCount = mtlTexture.mipmapLevelCount;
166    texDesc.arrayLength = mtlTexture.arrayLength;
167    texDesc.sampleCount = mtlTexture.sampleCount;
168    texDesc.usage = mtlTexture.usage;
169    return texDesc;
170}
171
172#if PRINT_MSL
173void print_msl(const char* source) {
174    SkTArray<SkString> lines;
175    SkStrSplit(source, "\n", kStrict_SkStrSplitMode, &lines);
176    for (int i = 0; i < lines.count(); i++) {
177        SkString& line = lines[i];
178        line.prependf("%4i\t", i + 1);
179        SkDebugf("%s\n", line.c_str());
180    }
181}
182#endif
183
184id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
185                                         const char* shaderString,
186                                         SkSL::Program::Kind kind,
187                                         const SkSL::Program::Settings& settings,
188                                         SkSL::Program::Inputs* outInputs) {
189    std::unique_ptr<SkSL::Program> program =
190            gpu->shaderCompiler()->convertProgram(kind,
191                                                  SkSL::String(shaderString),
192                                                  settings);
193
194    if (!program) {
195        SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
196        SkASSERT(false);
197    }
198
199    *outInputs = program->fInputs;
200    SkSL::String code;
201    if (!gpu->shaderCompiler()->toMetal(*program, &code)) {
202        SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
203        SkASSERT(false);
204        return nil;
205    }
206    NSString* mtlCode = [[NSString alloc] initWithCString: code.c_str()
207                                                 encoding: NSASCIIStringEncoding];
208#if PRINT_MSL
209    print_msl([mtlCode cStringUsingEncoding: NSASCIIStringEncoding]);
210#endif
211
212    MTLCompileOptions* defaultOptions = [[MTLCompileOptions alloc] init];
213    NSError* error = nil;
214    id<MTLLibrary> compiledLibrary = [gpu->device() newLibraryWithSource: mtlCode
215                                                                 options: defaultOptions
216                                                                   error: &error];
217    if (error) {
218        SkDebugf("Error compiling MSL shader: %s\n",
219                 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
220        return nil;
221    }
222    return compiledLibrary;
223}
224
225id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface, bool doResolve) {
226    id<MTLTexture> mtlTexture = nil;
227
228    GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
229    GrMtlTexture* texture;
230    if (renderTarget) {
231        if (doResolve) {
232            // TODO: do resolve and set mtlTexture to resolved texture. As of now, we shouldn't
233            // have any multisampled render targets.
234            SkASSERT(false);
235        } else {
236            mtlTexture = renderTarget->mtlRenderTexture();
237        }
238    } else {
239        texture = static_cast<GrMtlTexture*>(surface->asTexture());
240        if (texture) {
241            mtlTexture = texture->mtlTexture();
242        }
243    }
244    return mtlTexture;
245}
246
247
248//////////////////////////////////////////////////////////////////////////////
249// CPP Utils
250
251GrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo& info) {
252    id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture,
253                                                GrWrapOwnership::kBorrow_GrWrapOwnership);
254    return static_cast<GrMTLPixelFormat>(mtlTexture.pixelFormat);
255}
256