Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrMtlPipelineStateBuilder.mm
Go to the documentation of this file.
1/*
2 * 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 */
7
9
22
27
28#import <simd/simd.h>
29
30#if !__has_feature(objc_arc)
31#error This file must be compiled with Arc. Use -fobjc-arc flag
32#endif
33
34GR_NORETAIN_BEGIN
35
37 GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo,
38 const GrMtlPrecompiledLibraries* precompiledLibs) {
39 GrAutoLocaleSetter als("C");
40 GrMtlPipelineStateBuilder builder(gpu, desc, programInfo);
41
42 if (!builder.emitAndInstallProcs()) {
43 return nullptr;
44 }
45 return builder.finalize(desc, programInfo, precompiledLibs);
46}
47
48GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
49 const GrProgramDesc& desc,
50 const GrProgramInfo& programInfo)
51 : INHERITED(desc, programInfo)
52 , fGpu(gpu)
53 , fUniformHandler(this)
54 , fVaryingHandler(this) {
55}
56
58 return fGpu->caps();
59}
60
62 outputColor.addLayoutQualifier("location = 0, index = 1");
63}
64
65static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
66static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
67
68void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[],
69 const SkSL::Program::Interface interfaces[],
70 SkSL::ProgramSettings* settings,
71 sk_sp<SkData> pipelineData,
72 bool isSkSL) {
74 this->desc().keyLength());
75 SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
76 // cache metadata to allow for a complete precompile in either case
78 meta.fSettings = settings;
79 meta.fPlatformData = std::move(pipelineData);
80 SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag;
81 sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(tag, shaders, interfaces,
82 kGrShaderTypeCount, &meta);
83 fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description);
84}
85
86id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
87 const std::string& shader,
90 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
91 if (shaderLibrary != nil &&
94 }
95 return shaderLibrary;
96}
97
98static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
99 switch (type) {
101 return MTLVertexFormatFloat;
103 return MTLVertexFormatFloat2;
105 return MTLVertexFormatFloat3;
107 return MTLVertexFormatFloat4;
109 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
110 return MTLVertexFormatHalf;
111 } else {
112 return MTLVertexFormatInvalid;
113 }
115 return MTLVertexFormatHalf2;
117 return MTLVertexFormatHalf4;
119 return MTLVertexFormatInt2;
121 return MTLVertexFormatInt3;
123 return MTLVertexFormatInt4;
125 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
126 return MTLVertexFormatChar;
127 } else {
128 return MTLVertexFormatInvalid;
129 }
131 return MTLVertexFormatChar2;
133 return MTLVertexFormatChar4;
135 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
136 return MTLVertexFormatUChar;
137 } else {
138 return MTLVertexFormatInvalid;
139 }
141 return MTLVertexFormatUChar2;
143 return MTLVertexFormatUChar4;
145 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
146 return MTLVertexFormatUCharNormalized;
147 } else {
148 return MTLVertexFormatInvalid;
149 }
151 return MTLVertexFormatUChar4Normalized;
153 return MTLVertexFormatShort2;
155 return MTLVertexFormatShort4;
157 return MTLVertexFormatUShort2;
159 return MTLVertexFormatUShort2Normalized;
161 return MTLVertexFormatInt;
163 return MTLVertexFormatUInt;
165 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
166 return MTLVertexFormatUShortNormalized;
167 } else {
168 return MTLVertexFormatInvalid;
169 }
171 return MTLVertexFormatUShort4Normalized;
172 }
173 SK_ABORT("Unknown vertex attribute type");
174}
175
176static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
177 SkBinaryWriteBuffer* writer) {
178 uint32_t vertexBinding = 0, instanceBinding = 0;
179
180 int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
181 if (geomProc.hasVertexAttributes()) {
182 vertexBinding = nextBinding++;
183 }
184
185 if (geomProc.hasInstanceAttributes()) {
186 instanceBinding = nextBinding;
187 }
188 if (writer) {
189 writer->writeUInt(vertexBinding);
190 writer->writeUInt(instanceBinding);
191 }
192
193 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
194 int attributeIndex = 0;
195
196 int vertexAttributeCount = geomProc.numVertexAttributes();
197 if (writer) {
198 writer->writeInt(vertexAttributeCount);
199 }
200 for (auto attribute : geomProc.vertexAttributes()) {
201 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
202 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
203 SkASSERT(MTLVertexFormatInvalid != format);
204 mtlAttribute.format = format;
205 mtlAttribute.offset = *attribute.offset();
206 mtlAttribute.bufferIndex = vertexBinding;
207 if (writer) {
208 writer->writeInt(format);
209 writer->writeUInt(*attribute.offset());
210 writer->writeUInt(vertexBinding);
211 }
212
213 attributeIndex++;
214 }
215
216 if (vertexAttributeCount) {
217 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
218 vertexDescriptor.layouts[vertexBinding];
219 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
220 vertexBufferLayout.stepRate = 1;
221 vertexBufferLayout.stride = geomProc.vertexStride();
222 if (writer) {
223 writer->writeUInt(geomProc.vertexStride());
224 }
225 }
226
227 int instanceAttributeCount = geomProc.numInstanceAttributes();
228 if (writer) {
229 writer->writeInt(instanceAttributeCount);
230 }
231 for (auto attribute : geomProc.instanceAttributes()) {
232 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
233 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
234 SkASSERT(MTLVertexFormatInvalid != format);
235 mtlAttribute.format = format;
236 mtlAttribute.offset = *attribute.offset();
237 mtlAttribute.bufferIndex = instanceBinding;
238 if (writer) {
239 writer->writeInt(format);
240 writer->writeUInt(*attribute.offset());
241 writer->writeUInt(instanceBinding);
242 }
243
244 attributeIndex++;
245 }
246
247 if (instanceAttributeCount) {
248 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
249 vertexDescriptor.layouts[instanceBinding];
250 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
251 instanceBufferLayout.stepRate = 1;
252 instanceBufferLayout.stride = geomProc.instanceStride();
253 if (writer) {
254 writer->writeUInt(geomProc.instanceStride());
255 }
256 }
257 return vertexDescriptor;
258}
259
260static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff) {
261 switch (coeff) {
263 return MTLBlendFactorZero;
265 return MTLBlendFactorOne;
267 return MTLBlendFactorSourceColor;
269 return MTLBlendFactorOneMinusSourceColor;
271 return MTLBlendFactorDestinationColor;
273 return MTLBlendFactorOneMinusDestinationColor;
275 return MTLBlendFactorSourceAlpha;
277 return MTLBlendFactorOneMinusSourceAlpha;
279 return MTLBlendFactorDestinationAlpha;
281 return MTLBlendFactorOneMinusDestinationAlpha;
283 return MTLBlendFactorBlendColor;
285 return MTLBlendFactorOneMinusBlendColor;
287 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
288 return MTLBlendFactorSource1Color;
289 } else {
290 return MTLBlendFactorZero;
291 }
293 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
294 return MTLBlendFactorOneMinusSource1Color;
295 } else {
296 return MTLBlendFactorZero;
297 }
299 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
300 return MTLBlendFactorSource1Alpha;
301 } else {
302 return MTLBlendFactorZero;
303 }
305 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
306 return MTLBlendFactorOneMinusSource1Alpha;
307 } else {
308 return MTLBlendFactorZero;
309 }
311 return MTLBlendFactorZero;
312 }
313
314 SK_ABORT("Unknown blend coefficient");
315}
316
317static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation) {
318 static const MTLBlendOperation gTable[] = {
319 MTLBlendOperationAdd, // skgpu::BlendEquation::kAdd
320 MTLBlendOperationSubtract, // skgpu::BlendEquation::kSubtract
321 MTLBlendOperationReverseSubtract, // skgpu::BlendEquation::kReverseSubtract
322 };
323 static_assert(std::size(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
324 static_assert(0 == (int)skgpu::BlendEquation::kAdd);
325 static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
326 static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
327
328 SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
329 return gTable[(int)equation];
330}
331
332static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
333 MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
334 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
335
336 // pixel format
337 mtlColorAttachment.pixelFormat = format;
338 if (writer) {
339 writer->writeInt(format);
340 }
341
342 // blending
343 const skgpu::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
344
345 skgpu::BlendEquation equation = blendInfo.fEquation;
346 skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
347 skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
348 bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
349
350 mtlColorAttachment.blendingEnabled = blendOn;
351 if (writer) {
352 writer->writeBool(blendOn);
353 }
354 if (blendOn) {
355 mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
356 mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
357 mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
358 mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
359 mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
360 mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
361 if (writer) {
362 writer->writeInt(mtlColorAttachment.sourceRGBBlendFactor);
363 writer->writeInt(mtlColorAttachment.destinationRGBBlendFactor);
364 writer->writeInt(mtlColorAttachment.rgbBlendOperation);
365 writer->writeInt(mtlColorAttachment.sourceAlphaBlendFactor);
366 writer->writeInt(mtlColorAttachment.destinationAlphaBlendFactor);
367 writer->writeInt(mtlColorAttachment.alphaBlendOperation);
368 }
369 }
370
371 if (blendInfo.fWritesColor) {
372 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
373 } else {
374 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
375 }
376 if (writer) {
377 writer->writeBool(blendInfo.fWritesColor);
378 }
379 return mtlColorAttachment;
380}
381
382static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
383 // Metal expects the buffer to be padded at the end according to the alignment
384 // of the largest element in the buffer.
385 uint32_t offsetDiff = offset & maxAlignment;
386 if (offsetDiff != 0) {
387 offsetDiff = maxAlignment - offsetDiff + 1;
388 }
389 return offset + offsetDiff;
390}
391
392static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
393 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
394
395#ifdef SK_ENABLE_MTL_DEBUG_INFO
396 // set label
397 {
398 SkString description;
399 reader->readString(&description);
400 pipelineDescriptor.label = @(description.c_str());
401 }
402#endif
403
404 // set up vertex descriptor
405 {
406 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
407 uint32_t vertexBinding = reader->readUInt();
408 uint32_t instanceBinding = reader->readUInt();
409
410 int attributeIndex = 0;
411
412 // vertex attributes
413 int vertexAttributeCount = reader->readInt();
414 for (int i = 0; i < vertexAttributeCount; ++i) {
415 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
416 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
417 mtlAttribute.offset = reader->readUInt();
418 mtlAttribute.bufferIndex = reader->readUInt();
419 ++attributeIndex;
420 }
421 if (vertexAttributeCount) {
422 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
423 vertexDescriptor.layouts[vertexBinding];
424 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
425 vertexBufferLayout.stepRate = 1;
426 vertexBufferLayout.stride = reader->readUInt();
427 }
428
429 // instance attributes
430 int instanceAttributeCount = reader->readInt();
431 for (int i = 0; i < instanceAttributeCount; ++i) {
432 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
433 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
434 mtlAttribute.offset = reader->readUInt();
435 mtlAttribute.bufferIndex = reader->readUInt();
436 ++attributeIndex;
437 }
438 if (instanceAttributeCount) {
439 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
440 vertexDescriptor.layouts[instanceBinding];
441 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
442 instanceBufferLayout.stepRate = 1;
443 instanceBufferLayout.stride = reader->readUInt();
444 }
445 pipelineDescriptor.vertexDescriptor = vertexDescriptor;
446 }
447
448 // set up color attachments
449 {
450 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
451
452 mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt();
453 mtlColorAttachment.blendingEnabled = reader->readBool();
454 if (mtlColorAttachment.blendingEnabled) {
455 mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt();
456 mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt();
457 mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt();
458 mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
459 mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
460 mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt();
461 }
462 if (reader->readBool()) {
463 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
464 } else {
465 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
466 }
467
468 pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
469 }
470
471 pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();
472
473 return pipelineDescriptor;
474}
475
476GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
477 const GrProgramDesc& desc, const GrProgramInfo& programInfo,
478 const GrMtlPrecompiledLibraries* precompiledLibs) {
479 TRACE_EVENT0("skia.shaders", TRACE_FUNC);
480
481 // Set up for cache if needed
482 std::unique_ptr<SkBinaryWriteBuffer> writer;
483
484 sk_sp<SkData> cached;
485 auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
486 if (persistentCache && !precompiledLibs) {
488 cached = persistentCache->load(*key);
489 }
490 if (persistentCache && !cached) {
491 writer = std::make_unique<SkBinaryWriteBuffer>(SkSerialProcs{});
492 }
493
494 // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above.
495 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
496#ifdef SK_ENABLE_MTL_DEBUG_INFO
497 SkString description = GrProgramDesc::Describe(programInfo, *fGpu->caps());
498 int split = description.find("\n");
499 description.resize(split);
500 pipelineDescriptor.label = @(description.c_str());
501 if (writer) {
502 writer->writeString(description.c_str());
503 }
504#endif
505
506 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
507 writer.get());
508
509 MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
510 if (pixelFormat == MTLPixelFormatInvalid) {
511 return nullptr;
512 }
513
514 pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
515 programInfo.pipeline(),
516 writer.get());
517 pipelineDescriptor.rasterSampleCount = programInfo.numSamples();
518
519 const GrMtlCaps* mtlCaps = (const GrMtlCaps*)this->caps();
520 pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
521 if (writer) {
522 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
523 }
524 SkASSERT(pipelineDescriptor.vertexDescriptor);
525 SkASSERT(pipelineDescriptor.colorAttachments[0]);
526
527 if (precompiledLibs) {
528 SkASSERT(precompiledLibs->fVertexLibrary);
529 SkASSERT(precompiledLibs->fFragmentLibrary);
530 pipelineDescriptor.vertexFunction =
531 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
532 pipelineDescriptor.fragmentFunction =
533 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
534 SkASSERT(pipelineDescriptor.vertexFunction);
535 SkASSERT(pipelineDescriptor.fragmentFunction);
536 if (precompiledLibs->fRTFlip) {
538 }
539 } else {
540 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
541
542 this->finalizeShaders();
543
545 settings.fSharpenTextures = true;
546 SkASSERT(!this->fragColorIsInOut());
547
548 SkReadBuffer reader;
549 SkFourByteTag shaderType = 0;
550 if (persistentCache && cached) {
551 reader.setMemory(cached->data(), cached->size());
552 shaderType = GrPersistentCacheUtils::GetType(&reader);
553 }
554
555 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
556 std::string msl[kGrShaderTypeCount];
558
559 // Unpack any stored shaders from the persistent cache
560 if (cached) {
561 switch (shaderType) {
562 case kMSL_Tag: {
564 &reader, msl, interfaces, kGrShaderTypeCount);
565 break;
566 }
567
568 case kSKSL_Tag: {
569 std::string cached_sksl[kGrShaderTypeCount];
571 &reader, cached_sksl, interfaces, kGrShaderTypeCount)) {
572 bool success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
573 cached_sksl[kVertex_GrShaderType],
575 settings,
577 &interfaces[kVertex_GrShaderType],
578 errorHandler);
579 success = success && skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
580 cached_sksl[kFragment_GrShaderType],
582 settings,
584 &interfaces[kFragment_GrShaderType],
585 errorHandler);
586 if (!success) {
587 return nullptr;
588 }
589 }
590 break;
591 }
592
593 default: {
594 break;
595 }
596 }
597 }
598
599 // Create any MSL shaders from pipeline data if necessary and cache
601 bool success = true;
602 if (msl[kVertex_GrShaderType].empty()) {
603 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
606 settings,
608 &interfaces[kVertex_GrShaderType],
609 errorHandler);
610 }
611 if (success && msl[kFragment_GrShaderType].empty()) {
612 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
615 settings,
617 &interfaces[kFragment_GrShaderType],
618 errorHandler);
619 }
620 if (!success) {
621 return nullptr;
622 }
623
624 if (persistentCache && !cached) {
625 sk_sp<SkData> pipelineData = writer->snapshotAsData();
626 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
628 std::string sksl[kGrShaderTypeCount];
631 this->storeShadersInCache(sksl, interfaces, &settings,
632 std::move(pipelineData), true);
633 } else {
634 /*** dump pipeline data here */
635 this->storeShadersInCache(msl, interfaces, nullptr,
636 std::move(pipelineData), false);
637 }
638 }
639 }
640
641 // Compile MSL to libraries
642 shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
644 interfaces[kVertex_GrShaderType],
645 errorHandler);
646 shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
648 interfaces[kFragment_GrShaderType],
649 errorHandler);
650 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
651 return nullptr;
652 }
653
654 pipelineDescriptor.vertexFunction =
655 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
656 pipelineDescriptor.fragmentFunction =
657 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
658 }
659
660 if (pipelineDescriptor.vertexFunction == nil) {
661 SkDebugf("Couldn't find vertexMain() in library\n");
662 return nullptr;
663 }
664 if (pipelineDescriptor.fragmentFunction == nil) {
665 SkDebugf("Couldn't find fragmentMain() in library\n");
666 return nullptr;
667 }
668 SkASSERT(pipelineDescriptor.vertexFunction);
669 SkASSERT(pipelineDescriptor.fragmentFunction);
670
671 NSError* error = nil;
672 id<MTLRenderPipelineState> pipelineState;
673 {
674 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
675 if (@available(macOS 10.15, *)) {
676 pipelineState = [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
677 error: &error];
678 } else {
680 fGpu->device(), pipelineDescriptor, &error);
681 }
682 }
683 if (error) {
684 SkDebugf("Error creating pipeline: %s\n",
685 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
686 return nullptr;
687 }
688 if (!pipelineState) {
689 return nullptr;
690 }
691
692 sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState);
693
694 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
695 fUniformHandler.fCurrentUBOMaxAlignment);
696 return new GrMtlPipelineState(fGpu,
697 std::move(renderPipeline),
698 pipelineDescriptor.colorAttachments[0].pixelFormat,
700 fUniformHandler.fUniforms,
701 bufferSize,
702 (uint32_t)fUniformHandler.numSamplers(),
703 std::move(fGPImpl),
704 std::move(fXPImpl),
705 std::move(fFPImpls));
706}
707
708//////////////////////////////////////////////////////////////////////////////
709
711 GrMtlPrecompiledLibraries* precompiledLibs) {
712 SkASSERT(precompiledLibs);
713
714 SkReadBuffer reader(cachedData.data(), cachedData.size());
716
717 auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();
718
719 SkSL::ProgramSettings settings;
720 settings.fSharpenTextures = true;
722 meta.fSettings = &settings;
723
724 std::string shaders[kGrShaderTypeCount];
727 &reader, shaders, interfaces, kGrShaderTypeCount, &meta)) {
728 return false;
729 }
730
731 // skip the size
732 reader.readUInt();
733 auto pipelineDescriptor = read_pipeline_data(&reader);
734 if (!reader.isValid()) {
735 return false;
736 }
737
738 switch (shaderType) {
739 case kMSL_Tag: {
740 precompiledLibs->fVertexLibrary =
741 GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
742 precompiledLibs->fFragmentLibrary =
743 GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
744 break;
745 }
746
747 case kSKSL_Tag: {
748 std::string msl[kGrShaderTypeCount];
749 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(),
750 shaders[kVertex_GrShaderType],
752 settings,
754 &interfaces[kVertex_GrShaderType],
755 errorHandler)) {
756 return false;
757 }
758 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(),
759 shaders[kFragment_GrShaderType],
761 settings,
763 &interfaces[kFragment_GrShaderType],
764 errorHandler)) {
765 return false;
766 }
767 precompiledLibs->fVertexLibrary =
768 GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
769 precompiledLibs->fFragmentLibrary =
770 GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
771 break;
772 }
773
774 default: {
775 return false;
776 }
777 }
778
779 pipelineDescriptor.vertexFunction =
780 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
781 pipelineDescriptor.fragmentFunction =
782 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
783
784 {
785 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
786 MTLNewRenderPipelineStateCompletionHandler completionHandler =
787 ^(id<MTLRenderPipelineState> state, NSError* error) {
788 if (error) {
789 SkDebugf("Error creating pipeline: %s\n",
790 [[error localizedDescription]
791 cStringUsingEncoding: NSASCIIStringEncoding]);
792 }
793 };
794
795 // kick off asynchronous pipeline build and depend on Apple's cache to manage it
796 [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
797 completionHandler: completionHandler];
798 }
799
800 precompiledLibs->fRTFlip = (interfaces[kFragment_GrShaderType].fRTFlipUniform !=
802 return true;
803}
804
805GR_NORETAIN_END
static constexpr SkFourByteTag kSKSL_Tag
static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation)
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static MTLRenderPipelineColorAttachmentDescriptor * create_color_attachment(MTLPixelFormat format, const GrPipeline &pipeline, SkBinaryWriteBuffer *writer)
static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff)
static MTLRenderPipelineDescriptor * read_pipeline_data(SkReadBuffer *reader)
static MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type)
static MTLVertexDescriptor * create_vertex_descriptor(const GrGeometryProcessor &geomProc, SkBinaryWriteBuffer *writer)
static constexpr SkFourByteTag kMSL_Tag
static constexpr SkFourByteTag kSKSL_Tag
id< MTLRenderPipelineState > GrMtlNewRenderPipelineStateWithDescriptor(id< MTLDevice >, MTLRenderPipelineDescriptor *, NSError **)
Definition GrMtlUtil.mm:166
static MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat &format)
Definition GrMtlUtil.h:106
id< MTLLibrary > GrCompileMtlShaderLibrary(const GrMtlGpu *gpu, const std::string &msl, GrContextOptions::ShaderErrorHandler *errorHandler)
Definition GrMtlUtil.mm:52
@ kFragment_GrShaderType
@ kVertex_GrShaderType
GrVertexAttribType
@ kUShort_norm_GrVertexAttribType
@ kFloat2_GrVertexAttribType
@ kUShort2_GrVertexAttribType
@ kUInt_GrVertexAttribType
@ kUByte4_norm_GrVertexAttribType
@ kUByte_GrVertexAttribType
@ kShort2_GrVertexAttribType
@ kUShort4_norm_GrVertexAttribType
@ kInt_GrVertexAttribType
@ kByte_GrVertexAttribType
@ kByte4_GrVertexAttribType
@ kFloat3_GrVertexAttribType
@ kFloat_GrVertexAttribType
@ kByte2_GrVertexAttribType
@ kFloat4_GrVertexAttribType
@ kShort4_GrVertexAttribType
@ kUShort2_norm_GrVertexAttribType
@ kInt3_GrVertexAttribType
@ kHalf2_GrVertexAttribType
@ kHalf4_GrVertexAttribType
@ kUByte4_GrVertexAttribType
@ kUByte2_GrVertexAttribType
@ kInt4_GrVertexAttribType
@ kUByte_norm_GrVertexAttribType
@ kInt2_GrVertexAttribType
@ kHalf_GrVertexAttribType
static const int kGrShaderTypeCount
#define SK_ABORT(message,...)
Definition SkAssert.h:70
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define INHERITED(method,...)
#define SKSL_RTFLIP_NAME
Definition SkSLProgram.h:19
#define TRACE_FUNC
uint32_t SkFourByteTag
Definition SkTypes.h:166
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition SkTypes.h:167
Type::kYUV Type::kRGBA() int(0.7 *637)
const GrContextOptions & options() const
GrContextOptions::ShaderErrorHandler * getShaderErrorHandler() const
const GrShaderCaps * shaderCaps() const
Definition GrCaps.h:63
virtual void store(const SkData &, const SkData &)
GrContextOptions::PersistentCache * getPersistentCache()
GrDirectContextPriv priv()
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
GrGLSLVertexBuilder fVS
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
GrGLSLBuiltinUniformHandles fUniformHandles
const GrProgramInfo & fProgramInfo
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
bool hasInstanceAttributes() const
const AttributeSet & vertexAttributes() const
const AttributeSet & instanceAttributes() const
size_t instanceStride() const
const GrCaps * caps() const
Definition GrGpu.h:73
GrDirectContext * getContext()
Definition GrGpu.h:67
MTLPixelFormat getStencilPixelFormat(const GrProgramDesc &desc) const
id< MTLDevice > device() const
Definition GrMtlGpu.h:49
static GrMtlPipelineState * CreatePipelineState(GrMtlGpu *, const GrProgramDesc &, const GrProgramInfo &, const GrMtlPrecompiledLibraries *precompiledLibs=nullptr)
void finalizeFragmentSecondaryColor(GrShaderVar &outputColor) override
const GrCaps * caps() const override
static bool PrecompileShaders(GrMtlGpu *, const SkData &, GrMtlPrecompiledLibraries *precompiledLibs)
static sk_sp< GrMtlRenderPipeline > Make(id< MTLRenderPipelineState > pso)
const GrXferProcessor & getXferProcessor() const
Definition GrPipeline.h:116
uint32_t keyLength() const
const uint32_t * asKey() const
static SkString Describe(const GrProgramInfo &, const GrCaps &)
int numSamples() const
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
const GrBackendFormat & backendFormat() const
void addLayoutQualifier(const char *layoutQualifier)
skgpu::BlendInfo getBlendInfo() const
void writeBool(bool value) override
void writeUInt(uint32_t value) override
void writeInt(int32_t value) override
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition SkData.h:116
const void * data() const
Definition SkData.h:37
size_t size() const
Definition SkData.h:30
void setMemory(const void *, size_t)
uint32_t readUInt()
bool isValid() const
int32_t readInt()
void readString(SkString *string)
int find(const char substring[]) const
Definition SkString.h:158
void resize(size_t len)
Definition SkString.cpp:374
const char * c_str() const
Definition SkString.h:133
EMSCRIPTEN_KEEPALIVE void empty()
AtkStateType state
const uint8_t uint32_t uint32_t GError ** error
uint32_t uint32_t * format
sk_sp< SkData > PackCachedShaders(SkFourByteTag shaderType, const std::string shaders[], const SkSL::Program::Interface interfaces[], int numInterfaces, const ShaderMetadata *meta)
bool UnpackCachedShaders(SkReadBuffer *reader, std::string shaders[], SkSL::Program::Interface interfaces[], int numInterfaces, ShaderMetadata *meta)
SkFourByteTag GetType(SkReadBuffer *reader)
std::string PrettyPrint(const std::string &string)
bool SkSLToMSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *msl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:145
static const int kBlendEquationCnt
Definition Blend.h:55
BlendEquation
Definition Blend.h:26
BlendCoeff
Definition Blend.h:60
init(device_serial, adb_binary)
Definition _adb_path.py:12
Point offset
ShaderCacheStrategy fShaderCacheStrategy
skgpu::BlendCoeff fDstBlend
Definition Blend.h:96
bool fWritesColor
Definition Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition Blend.h:95
#define TRACE_EVENT0(category_group, name)