2 * Copyright 2018 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "src/gpu/ganesh/mtl/GrMtlPipelineStateBuilder.h"
10 #include "include/gpu/GrDirectContext.h"
11 #include "src/core/SkReadBuffer.h"
12 #include "src/core/SkTraceEvent.h"
13 #include "src/core/SkWriteBuffer.h"
14 #include "src/gpu/ganesh/GrAutoLocaleSetter.h"
15 #include "src/gpu/ganesh/GrDirectContextPriv.h"
16 #include "src/gpu/ganesh/GrPersistentCacheUtils.h"
17 #include "src/gpu/ganesh/GrRenderTarget.h"
18 #include "src/utils/SkShaderUtils.h"
20 #include "src/gpu/ganesh/mtl/GrMtlGpu.h"
21 #include "src/gpu/ganesh/mtl/GrMtlPipelineState.h"
22 #include "src/gpu/ganesh/mtl/GrMtlUtil.h"
26 #if !__has_feature(objc_arc)
27 #error This file must be compiled with Arc. Use -fobjc-arc flag
32 GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
33 GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo,
34 const GrMtlPrecompiledLibraries* precompiledLibs) {
35 GrAutoLocaleSetter als("C");
36 GrMtlPipelineStateBuilder builder(gpu, desc, programInfo);
38 if (!builder.emitAndInstallProcs()) {
41 return builder.finalize(desc, programInfo, precompiledLibs);
44 GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
45 const GrProgramDesc& desc,
46 const GrProgramInfo& programInfo)
47 : INHERITED(desc, programInfo)
49 , fUniformHandler(this)
50 , fVaryingHandler(this) {
53 const GrCaps* GrMtlPipelineStateBuilder::caps() const {
57 SkSL::Compiler* GrMtlPipelineStateBuilder::shaderCompiler() const {
58 return fGpu->shaderCompiler();
61 void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
62 outputColor.addLayoutQualifier("location = 0, index = 0");
65 void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
66 outputColor.addLayoutQualifier("location = 0, index = 1");
69 static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
70 static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
72 void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[],
73 const SkSL::Program::Inputs inputs[],
74 SkSL::Program::Settings* settings,
75 sk_sp<SkData> pipelineData,
77 sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(),
78 this->desc().keyLength());
79 SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
80 // cache metadata to allow for a complete precompile in either case
81 GrPersistentCacheUtils::ShaderMetadata meta;
82 meta.fSettings = settings;
83 meta.fPlatformData = std::move(pipelineData);
84 SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag;
85 sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(tag, shaders, inputs,
86 kGrShaderTypeCount, &meta);
87 fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description);
90 id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
91 const std::string& shader, SkSL::Program::Inputs inputs,
92 GrContextOptions::ShaderErrorHandler* errorHandler) {
93 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
94 if (shaderLibrary != nil && inputs.fUseFlipRTUniform) {
95 this->addRTFlipUniform(SKSL_RTFLIP_NAME);
100 static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
102 case kFloat_GrVertexAttribType:
103 return MTLVertexFormatFloat;
104 case kFloat2_GrVertexAttribType:
105 return MTLVertexFormatFloat2;
106 case kFloat3_GrVertexAttribType:
107 return MTLVertexFormatFloat3;
108 case kFloat4_GrVertexAttribType:
109 return MTLVertexFormatFloat4;
110 case kHalf_GrVertexAttribType:
111 if (@available(macOS 10.13, iOS 11.0, *)) {
112 return MTLVertexFormatHalf;
114 return MTLVertexFormatInvalid;
116 case kHalf2_GrVertexAttribType:
117 return MTLVertexFormatHalf2;
118 case kHalf4_GrVertexAttribType:
119 return MTLVertexFormatHalf4;
120 case kInt2_GrVertexAttribType:
121 return MTLVertexFormatInt2;
122 case kInt3_GrVertexAttribType:
123 return MTLVertexFormatInt3;
124 case kInt4_GrVertexAttribType:
125 return MTLVertexFormatInt4;
126 case kByte_GrVertexAttribType:
127 if (@available(macOS 10.13, iOS 11.0, *)) {
128 return MTLVertexFormatChar;
130 return MTLVertexFormatInvalid;
132 case kByte2_GrVertexAttribType:
133 return MTLVertexFormatChar2;
134 case kByte4_GrVertexAttribType:
135 return MTLVertexFormatChar4;
136 case kUByte_GrVertexAttribType:
137 if (@available(macOS 10.13, iOS 11.0, *)) {
138 return MTLVertexFormatUChar;
140 return MTLVertexFormatInvalid;
142 case kUByte2_GrVertexAttribType:
143 return MTLVertexFormatUChar2;
144 case kUByte4_GrVertexAttribType:
145 return MTLVertexFormatUChar4;
146 case kUByte_norm_GrVertexAttribType:
147 if (@available(macOS 10.13, iOS 11.0, *)) {
148 return MTLVertexFormatUCharNormalized;
150 return MTLVertexFormatInvalid;
152 case kUByte4_norm_GrVertexAttribType:
153 return MTLVertexFormatUChar4Normalized;
154 case kShort2_GrVertexAttribType:
155 return MTLVertexFormatShort2;
156 case kShort4_GrVertexAttribType:
157 return MTLVertexFormatShort4;
158 case kUShort2_GrVertexAttribType:
159 return MTLVertexFormatUShort2;
160 case kUShort2_norm_GrVertexAttribType:
161 return MTLVertexFormatUShort2Normalized;
162 case kInt_GrVertexAttribType:
163 return MTLVertexFormatInt;
164 case kUInt_GrVertexAttribType:
165 return MTLVertexFormatUInt;
166 case kUShort_norm_GrVertexAttribType:
167 if (@available(macOS 10.13, iOS 11.0, *)) {
168 return MTLVertexFormatUShortNormalized;
170 return MTLVertexFormatInvalid;
172 case kUShort4_norm_GrVertexAttribType:
173 return MTLVertexFormatUShort4Normalized;
175 SK_ABORT("Unknown vertex attribute type");
178 static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
179 SkBinaryWriteBuffer* writer) {
180 uint32_t vertexBinding = 0, instanceBinding = 0;
182 int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
183 if (geomProc.hasVertexAttributes()) {
184 vertexBinding = nextBinding++;
187 if (geomProc.hasInstanceAttributes()) {
188 instanceBinding = nextBinding;
191 writer->writeUInt(vertexBinding);
192 writer->writeUInt(instanceBinding);
195 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
196 int attributeIndex = 0;
198 int vertexAttributeCount = geomProc.numVertexAttributes();
200 writer->writeInt(vertexAttributeCount);
202 for (auto attribute : geomProc.vertexAttributes()) {
203 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
204 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
205 SkASSERT(MTLVertexFormatInvalid != format);
206 mtlAttribute.format = format;
207 mtlAttribute.offset = *attribute.offset();
208 mtlAttribute.bufferIndex = vertexBinding;
210 writer->writeInt(format);
211 writer->writeUInt(*attribute.offset());
212 writer->writeUInt(vertexBinding);
218 if (vertexAttributeCount) {
219 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
220 vertexDescriptor.layouts[vertexBinding];
221 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
222 vertexBufferLayout.stepRate = 1;
223 vertexBufferLayout.stride = geomProc.vertexStride();
225 writer->writeUInt(geomProc.vertexStride());
229 int instanceAttributeCount = geomProc.numInstanceAttributes();
231 writer->writeInt(instanceAttributeCount);
233 for (auto attribute : geomProc.instanceAttributes()) {
234 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
235 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
236 SkASSERT(MTLVertexFormatInvalid != format);
237 mtlAttribute.format = format;
238 mtlAttribute.offset = *attribute.offset();
239 mtlAttribute.bufferIndex = instanceBinding;
241 writer->writeInt(format);
242 writer->writeUInt(*attribute.offset());
243 writer->writeUInt(instanceBinding);
249 if (instanceAttributeCount) {
250 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
251 vertexDescriptor.layouts[instanceBinding];
252 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
253 instanceBufferLayout.stepRate = 1;
254 instanceBufferLayout.stride = geomProc.instanceStride();
256 writer->writeUInt(geomProc.instanceStride());
259 return vertexDescriptor;
262 static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff) {
264 case skgpu::BlendCoeff::kZero:
265 return MTLBlendFactorZero;
266 case skgpu::BlendCoeff::kOne:
267 return MTLBlendFactorOne;
268 case skgpu::BlendCoeff::kSC:
269 return MTLBlendFactorSourceColor;
270 case skgpu::BlendCoeff::kISC:
271 return MTLBlendFactorOneMinusSourceColor;
272 case skgpu::BlendCoeff::kDC:
273 return MTLBlendFactorDestinationColor;
274 case skgpu::BlendCoeff::kIDC:
275 return MTLBlendFactorOneMinusDestinationColor;
276 case skgpu::BlendCoeff::kSA:
277 return MTLBlendFactorSourceAlpha;
278 case skgpu::BlendCoeff::kISA:
279 return MTLBlendFactorOneMinusSourceAlpha;
280 case skgpu::BlendCoeff::kDA:
281 return MTLBlendFactorDestinationAlpha;
282 case skgpu::BlendCoeff::kIDA:
283 return MTLBlendFactorOneMinusDestinationAlpha;
284 case skgpu::BlendCoeff::kConstC:
285 return MTLBlendFactorBlendColor;
286 case skgpu::BlendCoeff::kIConstC:
287 return MTLBlendFactorOneMinusBlendColor;
288 case skgpu::BlendCoeff::kS2C:
289 if (@available(macOS 10.12, iOS 11.0, *)) {
290 return MTLBlendFactorSource1Color;
292 return MTLBlendFactorZero;
294 case skgpu::BlendCoeff::kIS2C:
295 if (@available(macOS 10.12, iOS 11.0, *)) {
296 return MTLBlendFactorOneMinusSource1Color;
298 return MTLBlendFactorZero;
300 case skgpu::BlendCoeff::kS2A:
301 if (@available(macOS 10.12, iOS 11.0, *)) {
302 return MTLBlendFactorSource1Alpha;
304 return MTLBlendFactorZero;
306 case skgpu::BlendCoeff::kIS2A:
307 if (@available(macOS 10.12, iOS 11.0, *)) {
308 return MTLBlendFactorOneMinusSource1Alpha;
310 return MTLBlendFactorZero;
312 case skgpu::BlendCoeff::kIllegal:
313 return MTLBlendFactorZero;
316 SK_ABORT("Unknown blend coefficient");
319 static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation) {
320 static const MTLBlendOperation gTable[] = {
321 MTLBlendOperationAdd, // skgpu::BlendEquation::kAdd
322 MTLBlendOperationSubtract, // skgpu::BlendEquation::kSubtract
323 MTLBlendOperationReverseSubtract, // skgpu::BlendEquation::kReverseSubtract
325 static_assert(SK_ARRAY_COUNT(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
326 static_assert(0 == (int)skgpu::BlendEquation::kAdd);
327 static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
328 static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
330 SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
331 return gTable[(int)equation];
334 static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
335 MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
336 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
339 mtlColorAttachment.pixelFormat = format;
341 writer->writeInt(format);
345 const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
347 skgpu::BlendEquation equation = blendInfo.fEquation;
348 skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
349 skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
350 bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
352 mtlColorAttachment.blendingEnabled = blendOn;
354 writer->writeBool(blendOn);
357 mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
358 mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
359 mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
360 mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
361 mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
362 mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
364 writer->writeInt(mtlColorAttachment.sourceRGBBlendFactor);
365 writer->writeInt(mtlColorAttachment.destinationRGBBlendFactor);
366 writer->writeInt(mtlColorAttachment.rgbBlendOperation);
367 writer->writeInt(mtlColorAttachment.sourceAlphaBlendFactor);
368 writer->writeInt(mtlColorAttachment.destinationAlphaBlendFactor);
369 writer->writeInt(mtlColorAttachment.alphaBlendOperation);
373 if (blendInfo.fWriteColor) {
374 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
376 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
379 writer->writeBool(blendInfo.fWriteColor);
381 return mtlColorAttachment;
384 static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
385 // Metal expects the buffer to be padded at the end according to the alignment
386 // of the largest element in the buffer.
387 uint32_t offsetDiff = offset & maxAlignment;
388 if (offsetDiff != 0) {
389 offsetDiff = maxAlignment - offsetDiff + 1;
391 return offset + offsetDiff;
394 static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
395 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
397 #ifdef SK_ENABLE_MTL_DEBUG_INFO
400 SkString description;
401 reader->readString(&description);
402 pipelineDescriptor.label = @(description.c_str());
406 // set up vertex descriptor
408 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
409 uint32_t vertexBinding = reader->readUInt();
410 uint32_t instanceBinding = reader->readUInt();
412 int attributeIndex = 0;
415 int vertexAttributeCount = reader->readInt();
416 for (int i = 0; i < vertexAttributeCount; ++i) {
417 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
418 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
419 mtlAttribute.offset = reader->readUInt();
420 mtlAttribute.bufferIndex = reader->readUInt();
423 if (vertexAttributeCount) {
424 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
425 vertexDescriptor.layouts[vertexBinding];
426 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
427 vertexBufferLayout.stepRate = 1;
428 vertexBufferLayout.stride = reader->readUInt();
431 // instance attributes
432 int instanceAttributeCount = reader->readInt();
433 for (int i = 0; i < instanceAttributeCount; ++i) {
434 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
435 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
436 mtlAttribute.offset = reader->readUInt();
437 mtlAttribute.bufferIndex = reader->readUInt();
440 if (instanceAttributeCount) {
441 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
442 vertexDescriptor.layouts[instanceBinding];
443 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
444 instanceBufferLayout.stepRate = 1;
445 instanceBufferLayout.stride = reader->readUInt();
447 pipelineDescriptor.vertexDescriptor = vertexDescriptor;
450 // set up color attachments
452 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
454 mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt();
455 mtlColorAttachment.blendingEnabled = reader->readBool();
456 if (mtlColorAttachment.blendingEnabled) {
457 mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt();
458 mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt();
459 mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt();
460 mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
461 mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
462 mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt();
464 if (reader->readBool()) {
465 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
467 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
470 pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
473 pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();
475 return pipelineDescriptor;
478 GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
479 const GrProgramDesc& desc, const GrProgramInfo& programInfo,
480 const GrMtlPrecompiledLibraries* precompiledLibs) {
481 TRACE_EVENT0("skia.shaders", TRACE_FUNC);
483 // Set up for cache if needed
484 std::unique_ptr<SkBinaryWriteBuffer> writer;
486 sk_sp<SkData> cached;
487 auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
488 if (persistentCache && !precompiledLibs) {
489 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.keyLength());
490 cached = persistentCache->load(*key);
492 if (persistentCache && !cached) {
493 writer.reset(new SkBinaryWriteBuffer());
496 // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above.
497 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
498 #ifdef SK_ENABLE_MTL_DEBUG_INFO
499 SkString description = GrProgramDesc::Describe(programInfo, *fGpu->caps());
500 int split = description.find("\n");
501 description.resize(split);
502 pipelineDescriptor.label = @(description.c_str());
504 writer->writeString(description.c_str());
508 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
511 MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
512 if (pixelFormat == MTLPixelFormatInvalid) {
516 pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
517 programInfo.pipeline(),
519 pipelineDescriptor.sampleCount = programInfo.numSamples();
520 GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
521 pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
523 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
525 SkASSERT(pipelineDescriptor.vertexDescriptor);
526 SkASSERT(pipelineDescriptor.colorAttachments[0]);
528 if (precompiledLibs) {
529 SkASSERT(precompiledLibs->fVertexLibrary);
530 SkASSERT(precompiledLibs->fFragmentLibrary);
531 pipelineDescriptor.vertexFunction =
532 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
533 pipelineDescriptor.fragmentFunction =
534 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
535 SkASSERT(pipelineDescriptor.vertexFunction);
536 SkASSERT(pipelineDescriptor.fragmentFunction);
537 if (precompiledLibs->fRTFlip) {
538 this->addRTFlipUniform(SKSL_RTFLIP_NAME);
541 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
543 this->finalizeShaders();
545 SkSL::Program::Settings settings;
546 settings.fSharpenTextures = true;
547 SkASSERT(!this->fragColorIsInOut());
550 SkFourByteTag shaderType = 0;
551 if (persistentCache && cached) {
552 reader.setMemory(cached->data(), cached->size());
553 shaderType = GrPersistentCacheUtils::GetType(&reader);
556 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
557 std::string msl[kGrShaderTypeCount];
558 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
560 // Unpack any stored shaders from the persistent cache
562 switch (shaderType) {
564 GrPersistentCacheUtils::UnpackCachedShaders(&reader, msl, inputs,
570 std::string cached_sksl[kGrShaderTypeCount];
571 if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs,
572 kGrShaderTypeCount)) {
573 bool success = GrSkSLToMSL(fGpu,
574 cached_sksl[kVertex_GrShaderType],
575 SkSL::ProgramKind::kVertex,
577 &msl[kVertex_GrShaderType],
578 &inputs[kVertex_GrShaderType],
580 success = success && GrSkSLToMSL(fGpu,
581 cached_sksl[kFragment_GrShaderType],
582 SkSL::ProgramKind::kFragment,
584 &msl[kFragment_GrShaderType],
585 &inputs[kFragment_GrShaderType],
600 // Create any MSL shaders from pipeline data if necessary and cache
601 if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) {
603 if (msl[kVertex_GrShaderType].empty()) {
604 success = GrSkSLToMSL(fGpu,
606 SkSL::ProgramKind::kVertex,
608 &msl[kVertex_GrShaderType],
609 &inputs[kVertex_GrShaderType],
612 if (success && msl[kFragment_GrShaderType].empty()) {
613 success = GrSkSLToMSL(fGpu,
615 SkSL::ProgramKind::kFragment,
617 &msl[kFragment_GrShaderType],
618 &inputs[kFragment_GrShaderType],
625 if (persistentCache && !cached) {
626 sk_sp<SkData> pipelineData = writer->snapshotAsData();
627 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
628 GrContextOptions::ShaderCacheStrategy::kSkSL) {
629 std::string sksl[kGrShaderTypeCount];
630 sksl[kVertex_GrShaderType] = SkShaderUtils::PrettyPrint(fVS.fCompilerString);
631 sksl[kFragment_GrShaderType] = SkShaderUtils::PrettyPrint(fFS.fCompilerString);
632 this->storeShadersInCache(sksl, inputs, &settings,
633 std::move(pipelineData), true);
635 /*** dump pipeline data here */
636 this->storeShadersInCache(msl, inputs, nullptr,
637 std::move(pipelineData), false);
642 // Compile MSL to libraries
643 shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
644 msl[kVertex_GrShaderType],
645 inputs[kVertex_GrShaderType],
647 shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
648 msl[kFragment_GrShaderType],
649 inputs[kFragment_GrShaderType],
651 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
655 pipelineDescriptor.vertexFunction =
656 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
657 pipelineDescriptor.fragmentFunction =
658 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
661 if (pipelineDescriptor.vertexFunction == nil) {
662 SkDebugf("Couldn't find vertexMain() in library\n");
665 if (pipelineDescriptor.fragmentFunction == nil) {
666 SkDebugf("Couldn't find fragmentMain() in library\n");
669 SkASSERT(pipelineDescriptor.vertexFunction);
670 SkASSERT(pipelineDescriptor.fragmentFunction);
672 NSError* error = nil;
673 #if GR_METAL_SDK_VERSION >= 230
674 if (@available(macOS 11.0, iOS 14.0, *)) {
675 id<MTLBinaryArchive> archive = fGpu->binaryArchive();
677 NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
678 pipelineDescriptor.binaryArchives = archiveArray;
681 TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
682 result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
685 if (!result && error) {
686 SkDebugf("Error storing pipeline: %s\n",
687 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
693 id<MTLRenderPipelineState> pipelineState;
695 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
696 #if defined(SK_BUILD_FOR_MAC)
697 pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
698 fGpu->device(), pipelineDescriptor, &error);
701 [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
706 SkDebugf("Error creating pipeline: %s\n",
707 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
710 if (!pipelineState) {
714 sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState);
716 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
717 fUniformHandler.fCurrentUBOMaxAlignment);
718 return new GrMtlPipelineState(fGpu,
719 std::move(renderPipeline),
720 pipelineDescriptor.colorAttachments[0].pixelFormat,
722 fUniformHandler.fUniforms,
724 (uint32_t)fUniformHandler.numSamplers(),
727 std::move(fFPImpls));
730 //////////////////////////////////////////////////////////////////////////////
732 bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData,
733 GrMtlPrecompiledLibraries* precompiledLibs) {
734 SkASSERT(precompiledLibs);
736 SkReadBuffer reader(cachedData.data(), cachedData.size());
737 SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);
739 auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();
741 SkSL::Program::Settings settings;
742 settings.fSharpenTextures = true;
743 GrPersistentCacheUtils::ShaderMetadata meta;
744 meta.fSettings = &settings;
746 std::string shaders[kGrShaderTypeCount];
747 SkSL::Program::Inputs inputs[kGrShaderTypeCount];
748 if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount,
755 auto pipelineDescriptor = read_pipeline_data(&reader);
756 if (!reader.isValid()) {
760 switch (shaderType) {
762 precompiledLibs->fVertexLibrary =
763 GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
764 precompiledLibs->fFragmentLibrary =
765 GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
770 std::string msl[kGrShaderTypeCount];
771 if (!GrSkSLToMSL(gpu,
772 shaders[kVertex_GrShaderType],
773 SkSL::ProgramKind::kVertex,
775 &msl[kVertex_GrShaderType],
776 &inputs[kVertex_GrShaderType],
780 if (!GrSkSLToMSL(gpu,
781 shaders[kFragment_GrShaderType],
782 SkSL::ProgramKind::kFragment,
784 &msl[kFragment_GrShaderType],
785 &inputs[kFragment_GrShaderType],
789 precompiledLibs->fVertexLibrary =
790 GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
791 precompiledLibs->fFragmentLibrary =
792 GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
801 pipelineDescriptor.vertexFunction =
802 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
803 pipelineDescriptor.fragmentFunction =
804 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
806 #if GR_METAL_SDK_VERSION >= 230
807 if (@available(macOS 11.0, iOS 14.0, *)) {
808 id<MTLBinaryArchive> archive = gpu->binaryArchive();
810 NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
811 pipelineDescriptor.binaryArchives = archiveArray;
813 NSError* error = nil;
815 TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
816 result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
819 if (!result && error) {
820 SkDebugf("Error storing pipeline: %s\n",
821 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
827 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
828 MTLNewRenderPipelineStateCompletionHandler completionHandler =
829 ^(id<MTLRenderPipelineState> state, NSError* error) {
831 SkDebugf("Error creating pipeline: %s\n",
832 [[error localizedDescription]
833 cStringUsingEncoding: NSASCIIStringEncoding]);
837 // kick off asynchronous pipeline build and depend on Apple's cache to manage it
838 [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
839 completionHandler: completionHandler];
842 precompiledLibs->fRTFlip = inputs[kFragment_GrShaderType].fUseFlipRTUniform;