blob: 824bbf5da34ecc870992c60f8e5f0b91f88b7a50 [file] [log] [blame]
Greg Daniel0576a452017-07-31 16:32:36 -04001/*
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
Greg Danielef59d872017-11-17 16:47:21 -050010#include "GrTypesPriv.h"
Timothy Liange30739a2018-07-31 10:51:17 -040011#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
Greg Danielef59d872017-11-17 16:47:21 -050020
Greg Daniel0576a452017-07-31 16:32:36 -040021bool 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;
Brian Salomon5fba7ad2018-03-22 10:01:16 -040033 case kRGB_888_GrPixelConfig:
34 // TODO: MTLPixelFormatRGB8Unorm
35 return false;
Jim Van Verth69e57852018-12-05 13:38:59 -050036 case kRG_88_GrPixelConfig:
37 // TODO: MTLPixelFormatRG8Unorm
38 return false;
Greg Daniel0576a452017-07-31 16:32:36 -040039 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;
Brian Osman10fc6fd2018-03-02 11:01:10 -050048 case kRGBA_1010102_GrPixelConfig:
49 *format = MTLPixelFormatRGB10A2Unorm;
50 return true;
Greg Daniel0576a452017-07-31 16:32:36 -040051 case kRGB_565_GrPixelConfig:
52#ifdef SK_BUILD_FOR_IOS
Brian Osman10fc6fd2018-03-02 11:01:10 -050053 *format = MTLPixelFormatB5G6R5Unorm;
Greg Daniel0576a452017-07-31 16:32:36 -040054 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
Greg Danielef59d872017-11-17 16:47:21 -050065 case kAlpha_8_GrPixelConfig: // fall through
66 case kAlpha_8_as_Red_GrPixelConfig:
Greg Daniel0576a452017-07-31 16:32:36 -040067 *format = MTLPixelFormatR8Unorm;
68 return true;
Greg Danielef59d872017-11-17 16:47:21 -050069 case kAlpha_8_as_Alpha_GrPixelConfig:
70 return false;
Greg Daniel7af060a2017-12-05 16:27:11 -050071 case kGray_8_GrPixelConfig: // fall through
72 case kGray_8_as_Red_GrPixelConfig:
Greg Daniel0576a452017-07-31 16:32:36 -040073 *format = MTLPixelFormatR8Unorm;
74 return true;
Greg Daniel7af060a2017-12-05 16:27:11 -050075 case kGray_8_as_Lum_GrPixelConfig:
76 return false;
Greg Daniel0576a452017-07-31 16:32:36 -040077 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;
Greg Danielef59d872017-11-17 16:47:21 -050086 case kAlpha_half_GrPixelConfig: // fall through
87 case kAlpha_half_as_Red_GrPixelConfig:
Greg Daniel0576a452017-07-31 16:32:36 -040088 *format = MTLPixelFormatR16Float;
89 return true;
Jim Van Verth1676cb92019-01-15 13:24:45 -050090 case kRGB_ETC1_GrPixelConfig:
91#ifdef SK_BUILD_FOR_IOS
92 *format = MTLPixelFormatETC2_RGB8;
93 return true;
94#else
95 return false;
96#endif
Greg Daniel0576a452017-07-31 16:32:36 -040097 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040098 SK_ABORT("Unexpected config");
Greg Daniel0576a452017-07-31 16:32:36 -040099 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;
Brian Osman10fc6fd2018-03-02 11:01:10 -0500112 case MTLPixelFormatRGB10A2Unorm:
113 return kRGBA_1010102_GrPixelConfig;
Greg Daniel0576a452017-07-31 16:32:36 -0400114#ifdef SK_BUILD_FOR_IOS
115 case MTLPixelFormatB5G6R5Unorm:
116 return kRGB_565_GrPixelConfig;
117 case MTLPixelFormatABGR4Unorm:
118 return kRGBA_4444_GrPixelConfig;
119#endif
Jim Van Verth69e57852018-12-05 13:38:59 -0500120 case MTLPixelFormatRG8Unorm:
121 return kRG_88_GrPixelConfig;
Greg Daniel0576a452017-07-31 16:32:36 -0400122 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;
Jim Van Verth1676cb92019-01-15 13:24:45 -0500133#ifdef SK_BUILD_FOR_IOS
134 case MTLPixelFormatETC2_RGB8:
135 return kRGB_ETC1_GrPixelConfig;
136#endif
Greg Daniel0576a452017-07-31 16:32:36 -0400137 default:
138 return kUnknown_GrPixelConfig;
139 }
140}
Timothy Liang4e85e802018-06-28 16:37:18 -0400141
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
Timothy Liange886e802018-07-02 16:03:28 -0400150const void* GrGetPtrFromId(id idObject) {
151 return (__bridge const void*)idObject;
152}
153
Timothy Liang760dbc42018-07-17 13:28:20 -0400154const void* GrReleaseId(id idObject) {
155 return (__bridge_retained const void*)idObject;
156}
157
Timothy Liangff19c8f2018-07-11 13:27:21 -0400158MTLTextureDescriptor* 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}
Timothy Liange30739a2018-07-31 10:51:17 -0400171
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}
Brian Salomonf391d0f2018-12-14 09:18:50 -0500246
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}