blob: 300d346b3fe68806de1b5451c609f810ce05dd54 [file] [log] [blame]
Timothy Liang7ac582e2018-08-06 09:47:23 -04001/*
Timothy Liang44636e92018-08-08 10:50:21 -04002 * Copyright 2018 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 */
Timothy Liang7ac582e2018-08-06 09:47:23 -04007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContext.h"
Jim Van Verth9b2c06f2019-12-09 11:12:50 -050011#include "src/core/SkReader32.h"
Jim Van Verth5a8f3e42019-10-24 10:23:26 -040012#include "src/gpu/GrAutoLocaleSetter.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrContextPriv.h"
Jim Van Verth9b2c06f2019-12-09 11:12:50 -050014#include "src/gpu/GrPersistentCacheUtils.h"
15#include "src/gpu/GrRenderTargetPriv.h"
16#include "src/gpu/GrShaderUtils.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -040017
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/mtl/GrMtlGpu.h"
19#include "src/gpu/mtl/GrMtlPipelineState.h"
20#include "src/gpu/mtl/GrMtlUtil.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -040021
22#import <simd/simd.h>
23
Jim Van Verthcf23f582019-05-22 09:46:57 -040024#if !__has_feature(objc_arc)
25#error This file must be compiled with Arc. Use -fobjc-arc flag
26#endif
27
Robert Phillips4777e3a2020-02-05 10:37:40 -050028GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
29 GrMtlGpu* gpu,
30 GrRenderTarget* renderTarget,
31 const GrProgramDesc& desc,
32 const GrProgramInfo& programInfo) {
Jim Van Verth5a8f3e42019-10-24 10:23:26 -040033 GrAutoLocaleSetter als("C");
Robert Phillips4777e3a2020-02-05 10:37:40 -050034 GrMtlPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);
Timothy Liang7ac582e2018-08-06 09:47:23 -040035
36 if (!builder.emitAndInstallProcs()) {
37 return nullptr;
38 }
Robert Phillips4777e3a2020-02-05 10:37:40 -050039 return builder.finalize(renderTarget, desc, programInfo);
Timothy Liang7ac582e2018-08-06 09:47:23 -040040}
41
Jim Van Verth1223e7f2019-02-28 17:38:35 -050042GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
43 GrRenderTarget* renderTarget,
Robert Phillips4777e3a2020-02-05 10:37:40 -050044 const GrProgramDesc& desc,
45 const GrProgramInfo& programInfo)
46 : INHERITED(renderTarget, desc, programInfo)
Timothy Liang057c3902018-08-08 10:48:45 -040047 , fGpu(gpu)
48 , fUniformHandler(this)
49 , fVaryingHandler(this) {
Timothy Liang7ac582e2018-08-06 09:47:23 -040050}
51
52const GrCaps* GrMtlPipelineStateBuilder::caps() const {
53 return fGpu->caps();
54}
55
56void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
57 outputColor.addLayoutQualifier("location = 0, index = 0");
58}
59
60void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
61 outputColor.addLayoutQualifier("location = 0, index = 1");
62}
63
Jim Van Verth9b2c06f2019-12-09 11:12:50 -050064static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
65static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
66
67
68void GrMtlPipelineStateBuilder::loadShadersFromCache(SkReader32* cached,
Jim Van Verth6ee695c2019-12-11 14:37:27 -050069 __strong id<MTLLibrary> outLibraries[]) {
Jim Van Verth9b2c06f2019-12-09 11:12:50 -050070 SkSL::String shaders[kGrShaderTypeCount];
71 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
72
73 GrPersistentCacheUtils::UnpackCachedShaders(cached, shaders, inputs, kGrShaderTypeCount);
74
75 outLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
76 shaders[kVertex_GrShaderType],
77 inputs[kVertex_GrShaderType]);
78 outLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
79 shaders[kFragment_GrShaderType],
80 inputs[kFragment_GrShaderType]);
81
82 // Geometry shaders are not supported
83 SkASSERT(shaders[kGeometry_GrShaderType].empty());
84
85 SkASSERT(outLibraries[kVertex_GrShaderType]);
86 SkASSERT(outLibraries[kFragment_GrShaderType]);
87}
88
89void GrMtlPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
90 const SkSL::Program::Inputs inputs[],
91 bool isSkSL) {
Jim Van Verth6ee695c2019-12-11 14:37:27 -050092 // Here we shear off the Mtl-specific portion of the Desc in order to create the
93 // persistent key. This is because Mtl only caches the MSL code, not the fully compiled
94 // program, and that only depends on the base GrProgramDesc data.
Robert Phillips4777e3a2020-02-05 10:37:40 -050095 sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(),
96 this->desc().initialKeyLength());
Jim Van Verth9b2c06f2019-12-09 11:12:50 -050097 sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(isSkSL ? kSKSL_Tag : kMSL_Tag,
98 shaders,
99 inputs, kGrShaderTypeCount);
100 fGpu->getContext()->priv().getPersistentCache()->store(*key, *data);
101}
102
103id<MTLLibrary> GrMtlPipelineStateBuilder::generateMtlShaderLibrary(
104 const SkSL::String& shader,
Timothy Liang7ac582e2018-08-06 09:47:23 -0400105 SkSL::Program::Kind kind,
106 const SkSL::Program::Settings& settings,
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500107 SkSL::String* msl,
108 SkSL::Program::Inputs* inputs) {
109 id<MTLLibrary> shaderLibrary = GrGenerateMtlShaderLibrary(fGpu, shader,
110 kind, settings, msl, inputs);
111 if (shaderLibrary != nil && inputs->fRTHeight) {
112 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400113 }
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500114 return shaderLibrary;
115}
116
117id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(const SkSL::String& shader,
118 SkSL::Program::Inputs inputs) {
119 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader);
120 if (shaderLibrary != nil && inputs.fRTHeight) {
Greg Daniele6ab9982018-08-22 13:56:32 +0000121 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400122 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400123 return shaderLibrary;
124}
125
126static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400127 switch (type) {
128 case kFloat_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -0400129 return MTLVertexFormatFloat;
130 case kFloat2_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -0400131 return MTLVertexFormatFloat2;
132 case kFloat3_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -0400133 return MTLVertexFormatFloat3;
134 case kFloat4_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -0400135 return MTLVertexFormatFloat4;
Brian Osmand4c29702018-09-14 16:16:55 -0400136 case kHalf_GrVertexAttribType:
Jim Van Verth598903f2019-10-07 15:52:47 -0400137 if (@available(macOS 10.13, iOS 11.0, *)) {
138 return MTLVertexFormatHalf;
139 } else {
140 return MTLVertexFormatInvalid;
141 }
Brian Osmand4c29702018-09-14 16:16:55 -0400142 case kHalf2_GrVertexAttribType:
143 return MTLVertexFormatHalf2;
144 case kHalf3_GrVertexAttribType:
145 return MTLVertexFormatHalf3;
146 case kHalf4_GrVertexAttribType:
147 return MTLVertexFormatHalf4;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400148 case kInt2_GrVertexAttribType:
149 return MTLVertexFormatInt2;
150 case kInt3_GrVertexAttribType:
151 return MTLVertexFormatInt3;
152 case kInt4_GrVertexAttribType:
153 return MTLVertexFormatInt4;
154 case kByte_GrVertexAttribType:
Jim Van Verth598903f2019-10-07 15:52:47 -0400155 if (@available(macOS 10.13, iOS 11.0, *)) {
156 return MTLVertexFormatChar;
157 } else {
158 return MTLVertexFormatInvalid;
159 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400160 case kByte2_GrVertexAttribType:
161 return MTLVertexFormatChar2;
162 case kByte3_GrVertexAttribType:
163 return MTLVertexFormatChar3;
164 case kByte4_GrVertexAttribType:
165 return MTLVertexFormatChar4;
166 case kUByte_GrVertexAttribType:
Jim Van Verth598903f2019-10-07 15:52:47 -0400167 if (@available(macOS 10.13, iOS 11.0, *)) {
168 return MTLVertexFormatUChar;
169 } else {
170 return MTLVertexFormatInvalid;
171 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400172 case kUByte2_GrVertexAttribType:
173 return MTLVertexFormatUChar2;
174 case kUByte3_GrVertexAttribType:
175 return MTLVertexFormatUChar3;
176 case kUByte4_GrVertexAttribType:
177 return MTLVertexFormatUChar4;
178 case kUByte_norm_GrVertexAttribType:
Jim Van Verth598903f2019-10-07 15:52:47 -0400179 if (@available(macOS 10.13, iOS 11.0, *)) {
180 return MTLVertexFormatUCharNormalized;
181 } else {
182 return MTLVertexFormatInvalid;
183 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400184 case kUByte4_norm_GrVertexAttribType:
185 return MTLVertexFormatUChar4Normalized;
186 case kShort2_GrVertexAttribType:
187 return MTLVertexFormatShort2;
Brian Osmana5c578f2018-09-19 14:19:02 -0400188 case kShort4_GrVertexAttribType:
189 return MTLVertexFormatShort4;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400190 case kUShort2_GrVertexAttribType:
191 return MTLVertexFormatUShort2;
192 case kUShort2_norm_GrVertexAttribType:
193 return MTLVertexFormatUShort2Normalized;
194 case kInt_GrVertexAttribType:
195 return MTLVertexFormatInt;
196 case kUint_GrVertexAttribType:
197 return MTLVertexFormatUInt;
Robert Phillipsfe18de52019-06-06 17:21:50 -0400198 case kUShort_norm_GrVertexAttribType:
Jim Van Verth598903f2019-10-07 15:52:47 -0400199 if (@available(macOS 10.13, iOS 11.0, *)) {
200 return MTLVertexFormatUShortNormalized;
201 } else {
202 return MTLVertexFormatInvalid;
203 }
Robert Phillips66a46032019-06-18 08:00:42 -0400204 case kUShort4_norm_GrVertexAttribType:
205 return MTLVertexFormatUShort4Normalized;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400206 }
207 SK_ABORT("Unknown vertex attribute type");
Timothy Liang7ac582e2018-08-06 09:47:23 -0400208}
209
210static MTLVertexDescriptor* create_vertex_descriptor(const GrPrimitiveProcessor& primProc) {
211 uint32_t vertexBinding = 0, instanceBinding = 0;
212
Timothy Liang057c3902018-08-08 10:48:45 -0400213 int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400214 if (primProc.hasVertexAttributes()) {
215 vertexBinding = nextBinding++;
216 }
217
218 if (primProc.hasInstanceAttributes()) {
219 instanceBinding = nextBinding;
220 }
221
222 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
223 int attributeIndex = 0;
224
225 int vertexAttributeCount = primProc.numVertexAttributes();
226 size_t vertexAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500227 for (const auto& attribute : primProc.vertexAttributes()) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400228 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
Brian Osmand4c29702018-09-14 16:16:55 -0400229 mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
Jim Van Verth598903f2019-10-07 15:52:47 -0400230 SkASSERT(MTLVertexFormatInvalid != mtlAttribute.format);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400231 mtlAttribute.offset = vertexAttributeOffset;
232 mtlAttribute.bufferIndex = vertexBinding;
233
Timothy Liang7ac582e2018-08-06 09:47:23 -0400234 vertexAttributeOffset += attribute.sizeAlign4();
235 attributeIndex++;
236 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500237 SkASSERT(vertexAttributeOffset == primProc.vertexStride());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400238
239 if (vertexAttributeCount) {
240 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
241 vertexDescriptor.layouts[vertexBinding];
242 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
243 vertexBufferLayout.stepRate = 1;
244 vertexBufferLayout.stride = vertexAttributeOffset;
245 }
246
247 int instanceAttributeCount = primProc.numInstanceAttributes();
248 size_t instanceAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500249 for (const auto& attribute : primProc.instanceAttributes()) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400250 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
Brian Osmand4c29702018-09-14 16:16:55 -0400251 mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400252 mtlAttribute.offset = instanceAttributeOffset;
253 mtlAttribute.bufferIndex = instanceBinding;
254
Timothy Liang7ac582e2018-08-06 09:47:23 -0400255 instanceAttributeOffset += attribute.sizeAlign4();
256 attributeIndex++;
257 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500258 SkASSERT(instanceAttributeOffset == primProc.instanceStride());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400259
260 if (instanceAttributeCount) {
261 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
262 vertexDescriptor.layouts[instanceBinding];
263 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
264 instanceBufferLayout.stepRate = 1;
265 instanceBufferLayout.stride = instanceAttributeOffset;
266 }
267 return vertexDescriptor;
268}
269
270static MTLBlendFactor blend_coeff_to_mtl_blend(GrBlendCoeff coeff) {
Jim Van Verth598903f2019-10-07 15:52:47 -0400271 switch (coeff) {
272 case kZero_GrBlendCoeff:
273 return MTLBlendFactorZero;
274 case kOne_GrBlendCoeff:
275 return MTLBlendFactorOne;
276 case kSC_GrBlendCoeff:
277 return MTLBlendFactorSourceColor;
278 case kISC_GrBlendCoeff:
279 return MTLBlendFactorOneMinusSourceColor;
280 case kDC_GrBlendCoeff:
281 return MTLBlendFactorDestinationColor;
282 case kIDC_GrBlendCoeff:
283 return MTLBlendFactorOneMinusDestinationColor;
284 case kSA_GrBlendCoeff:
285 return MTLBlendFactorSourceAlpha;
286 case kISA_GrBlendCoeff:
287 return MTLBlendFactorOneMinusSourceAlpha;
288 case kDA_GrBlendCoeff:
289 return MTLBlendFactorDestinationAlpha;
290 case kIDA_GrBlendCoeff:
291 return MTLBlendFactorOneMinusDestinationAlpha;
292 case kConstC_GrBlendCoeff:
293 return MTLBlendFactorBlendColor;
294 case kIConstC_GrBlendCoeff:
295 return MTLBlendFactorOneMinusBlendColor;
296 case kConstA_GrBlendCoeff:
297 return MTLBlendFactorBlendAlpha;
298 case kIConstA_GrBlendCoeff:
299 return MTLBlendFactorOneMinusBlendAlpha;
300 case kS2C_GrBlendCoeff:
301 if (@available(macOS 10.12, iOS 11.0, *)) {
302 return MTLBlendFactorSource1Color;
303 } else {
304 return MTLBlendFactorZero;
305 }
306 case kIS2C_GrBlendCoeff:
307 if (@available(macOS 10.12, iOS 11.0, *)) {
308 return MTLBlendFactorOneMinusSource1Color;
309 } else {
310 return MTLBlendFactorZero;
311 }
312 case kS2A_GrBlendCoeff:
313 if (@available(macOS 10.12, iOS 11.0, *)) {
314 return MTLBlendFactorSource1Alpha;
315 } else {
316 return MTLBlendFactorZero;
317 }
318 case kIS2A_GrBlendCoeff:
319 if (@available(macOS 10.12, iOS 11.0, *)) {
320 return MTLBlendFactorOneMinusSource1Alpha;
321 } else {
322 return MTLBlendFactorZero;
323 }
324 case kIllegal_GrBlendCoeff:
325 return MTLBlendFactorZero;
326 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400327
Jim Van Verth598903f2019-10-07 15:52:47 -0400328 SK_ABORT("Unknown blend coefficient");
Timothy Liang7ac582e2018-08-06 09:47:23 -0400329}
330
331static MTLBlendOperation blend_equation_to_mtl_blend_op(GrBlendEquation equation) {
332 static const MTLBlendOperation gTable[] = {
333 MTLBlendOperationAdd, // kAdd_GrBlendEquation
334 MTLBlendOperationSubtract, // kSubtract_GrBlendEquation
335 MTLBlendOperationReverseSubtract, // kReverseSubtract_GrBlendEquation
336 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500337 static_assert(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation);
338 static_assert(0 == kAdd_GrBlendEquation);
339 static_assert(1 == kSubtract_GrBlendEquation);
340 static_assert(2 == kReverseSubtract_GrBlendEquation);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400341
Mike Klein36743362018-11-06 08:23:30 -0500342 SkASSERT((unsigned)equation < kGrBlendEquationCnt);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400343 return gTable[equation];
344}
345
346static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
Robert Phillips933484f2019-11-26 09:38:55 -0500347 MTLPixelFormat format, const GrPipeline& pipeline) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400348 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
349
350 // pixel format
Timothy Liang7ac582e2018-08-06 09:47:23 -0400351 mtlColorAttachment.pixelFormat = format;
352
353 // blending
Chris Daltonbbb3f642019-07-24 12:25:08 -0400354 const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
Timothy Liang7ac582e2018-08-06 09:47:23 -0400355
356 GrBlendEquation equation = blendInfo.fEquation;
357 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
358 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
359 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
360 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
361
362 mtlColorAttachment.blendingEnabled = !blendOff;
363 if (!blendOff) {
364 mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
365 mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
366 mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
367 mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
368 mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
369 mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
370 }
371
372 if (!blendInfo.fWriteColor) {
373 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
374 } else {
375 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
376 }
377 return mtlColorAttachment;
378}
379
Jim Van Verth3d482992019-02-07 10:48:05 -0500380uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
381 // Metal expects the buffer to be padded at the end according to the alignment
382 // of the largest element in the buffer.
383 uint32_t offsetDiff = offset & maxAlignment;
384 if (offsetDiff != 0) {
385 offsetDiff = maxAlignment - offsetDiff + 1;
386 }
387 return offset + offsetDiff;
388}
389
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500390GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
Robert Phillips4777e3a2020-02-05 10:37:40 -0500391 const GrProgramDesc& desc,
392 const GrProgramInfo& programInfo) {
Jim Van Verth4afe94c2019-11-05 15:10:08 -0500393 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500394 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
Timothy Liang7ac582e2018-08-06 09:47:23 -0400395
396 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
397 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
398 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
399 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
400
401 this->finalizeShaders();
402
403 SkSL::Program::Settings settings;
404 settings.fCaps = this->caps()->shaderCaps();
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500405 settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
Robert Phillips9da87e02019-02-04 13:26:26 -0500406 settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400407 SkASSERT(!this->fragColorIsInOut());
408
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500409 sk_sp<SkData> cached;
410 SkReader32 reader;
411 SkFourByteTag shaderType = 0;
412 auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
413 if (persistentCache) {
Jim Van Verth6ee695c2019-12-11 14:37:27 -0500414 // Here we shear off the Mtl-specific portion of the Desc in order to create the
415 // persistent key. This is because Mtl only caches the MSL code, not the fully compiled
416 // program, and that only depends on the base GrProgramDesc data.
Robert Phillips4777e3a2020-02-05 10:37:40 -0500417 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.initialKeyLength());
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500418 cached = persistentCache->load(*key);
419 if (cached) {
420 reader.setMemory(cached->data(), cached->size());
421 shaderType = reader.readU32();
422 }
Jim Van Vertha885b892019-06-24 15:09:57 -0400423 }
Timothy Liang7ac582e2018-08-06 09:47:23 -0400424
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500425 SkSL::String shaders[kGrShaderTypeCount];
426 if (kMSL_Tag == shaderType) {
427 this->loadShadersFromCache(&reader, shaderLibraries);
428 } else {
429 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
430
431 SkSL::String* sksl[kGrShaderTypeCount] = {
432 &fVS.fCompilerString,
433 nullptr, // geometry shaders not supported
434 &fFS.fCompilerString,
435 };
436 SkSL::String cached_sksl[kGrShaderTypeCount];
437 if (kSKSL_Tag == shaderType) {
438 GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs,
439 kGrShaderTypeCount);
440 for (int i = 0; i < kGrShaderTypeCount; ++i) {
441 sksl[i] = &cached_sksl[i];
442 }
443 }
444
445 shaderLibraries[kVertex_GrShaderType] = this->generateMtlShaderLibrary(
446 *sksl[kVertex_GrShaderType],
447 SkSL::Program::kVertex_Kind,
448 settings,
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500449 &shaders[kVertex_GrShaderType],
450 &inputs[kVertex_GrShaderType]);
451 shaderLibraries[kFragment_GrShaderType] = this->generateMtlShaderLibrary(
452 *sksl[kFragment_GrShaderType],
453 SkSL::Program::kFragment_Kind,
454 settings,
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500455 &shaders[kFragment_GrShaderType],
456 &inputs[kFragment_GrShaderType]);
457
458 // Geometry shaders are not supported
459 SkASSERT(!this->primitiveProcessor().willUseGeoShader());
460
461 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
462 return nullptr;
463 }
464
465 if (persistentCache && !cached) {
466 bool isSkSL = false;
467 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
468 GrContextOptions::ShaderCacheStrategy::kSkSL) {
469 for (int i = 0; i < kGrShaderTypeCount; ++i) {
Jim Van Verth73d46152019-12-19 10:55:02 -0500470 if (sksl[i]) {
471 shaders[i] = GrShaderUtils::PrettyPrint(*sksl[i]);
472 }
Jim Van Verth9b2c06f2019-12-09 11:12:50 -0500473 }
474 isSkSL = true;
475 }
476 this->storeShadersInCache(shaders, inputs, isSkSL);
477 }
478 }
479
480 id<MTLFunction> vertexFunction =
481 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
482 id<MTLFunction> fragmentFunction =
483 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
Timothy Liang7ac582e2018-08-06 09:47:23 -0400484
Jim Van Verth9756c362019-05-17 11:05:22 -0400485 if (vertexFunction == nil) {
486 SkDebugf("Couldn't find vertexMain() in library\n");
487 return nullptr;
488 }
489 if (fragmentFunction == nil) {
490 SkDebugf("Couldn't find fragmentMain() in library\n");
491 return nullptr;
492 }
493
Timothy Liang7ac582e2018-08-06 09:47:23 -0400494 pipelineDescriptor.vertexFunction = vertexFunction;
495 pipelineDescriptor.fragmentFunction = fragmentFunction;
Robert Phillips901aff02019-10-08 12:32:56 -0400496 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.primProc());
Robert Phillips933484f2019-11-26 09:38:55 -0500497
498 MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(renderTarget->backendFormat());
499 if (pixelFormat == MTLPixelFormatInvalid) {
500 return nullptr;
501 }
502
503 pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
Robert Phillips901aff02019-10-08 12:32:56 -0400504 programInfo.pipeline());
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700505 pipelineDescriptor.sampleCount = programInfo.numRasterSamples();
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500506 bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500507 GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
508 pipelineDescriptor.stencilAttachmentPixelFormat =
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500509 hasStencilAttachment ? mtlCaps->preferredStencilFormat().fInternalFormat
510 : MTLPixelFormatInvalid;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400511
512 SkASSERT(pipelineDescriptor.vertexFunction);
513 SkASSERT(pipelineDescriptor.fragmentFunction);
514 SkASSERT(pipelineDescriptor.vertexDescriptor);
515 SkASSERT(pipelineDescriptor.colorAttachments[0]);
516
517 NSError* error = nil;
Jim Van Verthb71f0232020-01-30 16:56:04 -0500518#if defined(SK_BUILD_FOR_MAC)
519 id<MTLRenderPipelineState> pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
520 fGpu->device(), pipelineDescriptor, &error);
521#else
Timothy Liang7ac582e2018-08-06 09:47:23 -0400522 id<MTLRenderPipelineState> pipelineState =
523 [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
524 error: &error];
Jim Van Verthb71f0232020-01-30 16:56:04 -0500525#endif
Timothy Liang7ac582e2018-08-06 09:47:23 -0400526 if (error) {
527 SkDebugf("Error creating pipeline: %s\n",
528 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
Timothy Liang6ed63962018-08-10 09:49:44 -0400529 return nullptr;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400530 }
Jim Van Verthb71f0232020-01-30 16:56:04 -0500531 if (!pipelineState) {
532 return nullptr;
533 }
Jim Van Vertha885b892019-06-24 15:09:57 -0400534
Ethan Nicholase5dc1eb2019-08-13 17:02:25 -0400535 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
536 fUniformHandler.fCurrentUBOMaxAlignment);
Timothy Liang057c3902018-08-08 10:48:45 -0400537 return new GrMtlPipelineState(fGpu,
538 pipelineState,
539 pipelineDescriptor.colorAttachments[0].pixelFormat,
Timothy Liang6ed63962018-08-10 09:49:44 -0400540 fUniformHandles,
541 fUniformHandler.fUniforms,
Ethan Nicholase5dc1eb2019-08-13 17:02:25 -0400542 bufferSize,
Timothy Liang6ed63962018-08-10 09:49:44 -0400543 (uint32_t)fUniformHandler.numSamplers(),
544 std::move(fGeometryProcessor),
545 std::move(fXferProcessor),
546 std::move(fFragmentProcessors),
547 fFragmentProcessorCnt);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400548}
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500549
550//////////////////////////////////////////////////////////////////////////////
551