• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
9
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/GrAutoLocaleSetter.h"
15#include "src/gpu/GrDirectContextPriv.h"
16#include "src/gpu/GrPersistentCacheUtils.h"
17#include "src/gpu/GrRenderTarget.h"
18#include "src/utils/SkShaderUtils.h"
19
20#include "src/gpu/mtl/GrMtlGpu.h"
21#include "src/gpu/mtl/GrMtlPipelineState.h"
22#include "src/gpu/mtl/GrMtlUtil.h"
23
24#import <simd/simd.h>
25
26#if !__has_feature(objc_arc)
27#error This file must be compiled with Arc. Use -fobjc-arc flag
28#endif
29
30GR_NORETAIN_BEGIN
31
32GrMtlPipelineState* 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);
37
38    if (!builder.emitAndInstallProcs()) {
39        return nullptr;
40    }
41    return builder.finalize(desc, programInfo, precompiledLibs);
42}
43
44GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
45                                                     const GrProgramDesc& desc,
46                                                     const GrProgramInfo& programInfo)
47        : INHERITED(desc, programInfo)
48        , fGpu(gpu)
49        , fUniformHandler(this)
50        , fVaryingHandler(this) {
51}
52
53const GrCaps* GrMtlPipelineStateBuilder::caps() const {
54    return fGpu->caps();
55}
56
57SkSL::Compiler* GrMtlPipelineStateBuilder::shaderCompiler() const {
58    return fGpu->shaderCompiler();
59}
60
61void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
62    outputColor.addLayoutQualifier("location = 0, index = 0");
63}
64
65void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
66    outputColor.addLayoutQualifier("location = 0, index = 1");
67}
68
69static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
70static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
71
72void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[],
73                                                    const SkSL::Program::Inputs inputs[],
74                                                    SkSL::Program::Settings* settings,
75                                                    sk_sp<SkData> pipelineData,
76                                                    bool isSkSL) {
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);
88}
89
90id<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);
96    }
97    return shaderLibrary;
98}
99
100static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
101    switch (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;
113            } else {
114                return MTLVertexFormatInvalid;
115            }
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;
129            } else {
130                return MTLVertexFormatInvalid;
131            }
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;
139            } else {
140                return MTLVertexFormatInvalid;
141            }
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;
149            } else {
150                return MTLVertexFormatInvalid;
151            }
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;
169            } else {
170                return MTLVertexFormatInvalid;
171            }
172        case kUShort4_norm_GrVertexAttribType:
173            return MTLVertexFormatUShort4Normalized;
174    }
175    SK_ABORT("Unknown vertex attribute type");
176}
177
178static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
179                                                     SkBinaryWriteBuffer* writer) {
180    uint32_t vertexBinding = 0, instanceBinding = 0;
181
182    int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
183    if (geomProc.hasVertexAttributes()) {
184        vertexBinding = nextBinding++;
185    }
186
187    if (geomProc.hasInstanceAttributes()) {
188        instanceBinding = nextBinding;
189    }
190    if (writer) {
191        writer->writeUInt(vertexBinding);
192        writer->writeUInt(instanceBinding);
193    }
194
195    auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
196    int attributeIndex = 0;
197
198    int vertexAttributeCount = geomProc.numVertexAttributes();
199    if (writer) {
200        writer->writeInt(vertexAttributeCount);
201    }
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;
209        if (writer) {
210            writer->writeInt(format);
211            writer->writeUInt(*attribute.offset());
212            writer->writeUInt(vertexBinding);
213        }
214
215        attributeIndex++;
216    }
217
218    if (vertexAttributeCount) {
219        MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
220                vertexDescriptor.layouts[vertexBinding];
221        vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
222        vertexBufferLayout.stepRate = 1;
223        vertexBufferLayout.stride = geomProc.vertexStride();
224        if (writer) {
225            writer->writeUInt(geomProc.vertexStride());
226        }
227    }
228
229    int instanceAttributeCount = geomProc.numInstanceAttributes();
230    if (writer) {
231        writer->writeInt(instanceAttributeCount);
232    }
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;
240        if (writer) {
241            writer->writeInt(format);
242            writer->writeUInt(*attribute.offset());
243            writer->writeUInt(instanceBinding);
244        }
245
246        attributeIndex++;
247    }
248
249    if (instanceAttributeCount) {
250        MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
251                vertexDescriptor.layouts[instanceBinding];
252        instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
253        instanceBufferLayout.stepRate = 1;
254        instanceBufferLayout.stride = geomProc.instanceStride();
255        if (writer) {
256            writer->writeUInt(geomProc.instanceStride());
257        }
258    }
259    return vertexDescriptor;
260}
261
262static MTLBlendFactor blend_coeff_to_mtl_blend(GrBlendCoeff coeff) {
263    switch (coeff) {
264        case kZero_GrBlendCoeff:
265            return MTLBlendFactorZero;
266        case kOne_GrBlendCoeff:
267            return MTLBlendFactorOne;
268        case kSC_GrBlendCoeff:
269            return MTLBlendFactorSourceColor;
270        case kISC_GrBlendCoeff:
271            return MTLBlendFactorOneMinusSourceColor;
272        case kDC_GrBlendCoeff:
273            return MTLBlendFactorDestinationColor;
274        case kIDC_GrBlendCoeff:
275            return MTLBlendFactorOneMinusDestinationColor;
276        case kSA_GrBlendCoeff:
277            return MTLBlendFactorSourceAlpha;
278        case kISA_GrBlendCoeff:
279            return MTLBlendFactorOneMinusSourceAlpha;
280        case kDA_GrBlendCoeff:
281            return MTLBlendFactorDestinationAlpha;
282        case kIDA_GrBlendCoeff:
283            return MTLBlendFactorOneMinusDestinationAlpha;
284        case kConstC_GrBlendCoeff:
285            return MTLBlendFactorBlendColor;
286        case kIConstC_GrBlendCoeff:
287            return MTLBlendFactorOneMinusBlendColor;
288        case kS2C_GrBlendCoeff:
289            if (@available(macOS 10.12, iOS 11.0, *)) {
290                return MTLBlendFactorSource1Color;
291            } else {
292                return MTLBlendFactorZero;
293            }
294        case kIS2C_GrBlendCoeff:
295            if (@available(macOS 10.12, iOS 11.0, *)) {
296                return MTLBlendFactorOneMinusSource1Color;
297            } else {
298                return MTLBlendFactorZero;
299            }
300        case kS2A_GrBlendCoeff:
301            if (@available(macOS 10.12, iOS 11.0, *)) {
302                return MTLBlendFactorSource1Alpha;
303            } else {
304                return MTLBlendFactorZero;
305            }
306        case kIS2A_GrBlendCoeff:
307            if (@available(macOS 10.12, iOS 11.0, *)) {
308                return MTLBlendFactorOneMinusSource1Alpha;
309            } else {
310                return MTLBlendFactorZero;
311            }
312        case kIllegal_GrBlendCoeff:
313            return MTLBlendFactorZero;
314    }
315
316    SK_ABORT("Unknown blend coefficient");
317}
318
319static MTLBlendOperation blend_equation_to_mtl_blend_op(GrBlendEquation equation) {
320    static const MTLBlendOperation gTable[] = {
321        MTLBlendOperationAdd,              // kAdd_GrBlendEquation
322        MTLBlendOperationSubtract,         // kSubtract_GrBlendEquation
323        MTLBlendOperationReverseSubtract,  // kReverseSubtract_GrBlendEquation
324    };
325    static_assert(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation);
326    static_assert(0 == kAdd_GrBlendEquation);
327    static_assert(1 == kSubtract_GrBlendEquation);
328    static_assert(2 == kReverseSubtract_GrBlendEquation);
329
330    SkASSERT((unsigned)equation < kGrBlendEquationCnt);
331    return gTable[equation];
332}
333
334static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
335        MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
336    auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
337
338    // pixel format
339    mtlColorAttachment.pixelFormat = format;
340    if (writer) {
341        writer->writeInt(format);
342    }
343
344    // blending
345    const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
346
347    GrBlendEquation equation = blendInfo.fEquation;
348    GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
349    GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
350    bool blendOn = !GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
351
352    mtlColorAttachment.blendingEnabled = blendOn;
353    if (writer) {
354        writer->writeBool(blendOn);
355    }
356    if (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);
363        if (writer) {
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);
370        }
371    }
372
373    if (blendInfo.fWriteColor) {
374        mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
375    } else {
376        mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
377    }
378    if (writer) {
379        writer->writeBool(blendInfo.fWriteColor);
380    }
381    return mtlColorAttachment;
382}
383
384static 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;
390    }
391    return offset + offsetDiff;
392}
393
394static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
395    auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
396
397#ifdef SK_ENABLE_MTL_DEBUG_INFO
398    // set label
399    {
400        SkString description;
401        reader->readString(&description);
402        pipelineDescriptor.label = @(description.c_str());
403    }
404#endif
405
406    // set up vertex descriptor
407    {
408        auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
409        uint32_t vertexBinding = reader->readUInt();
410        uint32_t instanceBinding = reader->readUInt();
411
412        int attributeIndex = 0;
413
414        // vertex attributes
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();
421            ++attributeIndex;
422        }
423        if (vertexAttributeCount) {
424            MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
425                    vertexDescriptor.layouts[vertexBinding];
426            vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
427            vertexBufferLayout.stepRate = 1;
428            vertexBufferLayout.stride = reader->readUInt();
429        }
430
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();
438            ++attributeIndex;
439        }
440        if (instanceAttributeCount) {
441            MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
442                    vertexDescriptor.layouts[instanceBinding];
443            instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
444            instanceBufferLayout.stepRate = 1;
445            instanceBufferLayout.stride = reader->readUInt();
446        }
447        pipelineDescriptor.vertexDescriptor = vertexDescriptor;
448    }
449
450    // set up color attachments
451    {
452        auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
453
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();
463        }
464        if (reader->readBool()) {
465            mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
466        } else {
467            mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
468        }
469
470        pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
471    }
472
473    pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();
474
475    return pipelineDescriptor;
476}
477
478GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
479        const GrProgramDesc& desc, const GrProgramInfo& programInfo,
480        const GrMtlPrecompiledLibraries* precompiledLibs) {
481    TRACE_EVENT0("skia.shaders", TRACE_FUNC);
482
483    // Set up for cache if needed
484    std::unique_ptr<SkBinaryWriteBuffer> writer;
485
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);
491    }
492    if (persistentCache && !cached) {
493        writer.reset(new SkBinaryWriteBuffer());
494    }
495
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());
503    if (writer) {
504        writer->writeString(description.c_str());
505    }
506#endif
507
508    pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
509                                                                   writer.get());
510
511    MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
512    if (pixelFormat == MTLPixelFormatInvalid) {
513        return nullptr;
514    }
515
516    pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
517                                                                     programInfo.pipeline(),
518                                                                     writer.get());
519    pipelineDescriptor.sampleCount = programInfo.numSamples();
520    GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
521    pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
522    if (writer) {
523        writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
524    }
525    SkASSERT(pipelineDescriptor.vertexDescriptor);
526    SkASSERT(pipelineDescriptor.colorAttachments[0]);
527
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);
539        }
540    } else {
541        id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
542
543        this->finalizeShaders();
544
545        SkSL::Program::Settings settings;
546        settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures;
547        SkASSERT(!this->fragColorIsInOut());
548
549        SkReadBuffer reader;
550        SkFourByteTag shaderType = 0;
551        if (persistentCache && cached) {
552            reader.setMemory(cached->data(), cached->size());
553            shaderType = GrPersistentCacheUtils::GetType(&reader);
554        }
555
556        auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
557        std::string msl[kGrShaderTypeCount];
558        SkSL::Program::Inputs inputs[kGrShaderTypeCount];
559
560        // Unpack any stored shaders from the persistent cache
561        if (cached) {
562            switch (shaderType) {
563                case kMSL_Tag: {
564                    GrPersistentCacheUtils::UnpackCachedShaders(&reader, msl, inputs,
565                                                                kGrShaderTypeCount);
566                    break;
567                }
568
569                case kSKSL_Tag: {
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,
576                                                   settings,
577                                                   &msl[kVertex_GrShaderType],
578                                                   &inputs[kVertex_GrShaderType],
579                                                   errorHandler);
580                        success = success && GrSkSLToMSL(fGpu,
581                                                         cached_sksl[kFragment_GrShaderType],
582                                                         SkSL::ProgramKind::kFragment,
583                                                         settings,
584                                                         &msl[kFragment_GrShaderType],
585                                                         &inputs[kFragment_GrShaderType],
586                                                         errorHandler);
587                        if (!success) {
588                            return nullptr;
589                        }
590                    }
591                    break;
592                }
593
594                default: {
595                    break;
596                }
597            }
598        }
599
600        // Create any MSL shaders from pipeline data if necessary and cache
601        if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) {
602            bool success = true;
603            if (msl[kVertex_GrShaderType].empty()) {
604                success = GrSkSLToMSL(fGpu,
605                                      fVS.fCompilerString,
606                                      SkSL::ProgramKind::kVertex,
607                                      settings,
608                                      &msl[kVertex_GrShaderType],
609                                      &inputs[kVertex_GrShaderType],
610                                      errorHandler);
611            }
612            if (success && msl[kFragment_GrShaderType].empty()) {
613                success = GrSkSLToMSL(fGpu,
614                                      fFS.fCompilerString,
615                                      SkSL::ProgramKind::kFragment,
616                                      settings,
617                                      &msl[kFragment_GrShaderType],
618                                      &inputs[kFragment_GrShaderType],
619                                      errorHandler);
620            }
621            if (!success) {
622                return nullptr;
623            }
624
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);
634                } else {
635                    /*** dump pipeline data here */
636                    this->storeShadersInCache(msl, inputs, nullptr,
637                                              std::move(pipelineData), false);
638                }
639            }
640        }
641
642        // Compile MSL to libraries
643        shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
644                                                        msl[kVertex_GrShaderType],
645                                                        inputs[kVertex_GrShaderType],
646                                                        errorHandler);
647        shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
648                                                        msl[kFragment_GrShaderType],
649                                                        inputs[kFragment_GrShaderType],
650                                                        errorHandler);
651        if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
652            return nullptr;
653        }
654
655        pipelineDescriptor.vertexFunction =
656                [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
657        pipelineDescriptor.fragmentFunction =
658                [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
659    }
660
661    if (pipelineDescriptor.vertexFunction == nil) {
662        SkDebugf("Couldn't find vertexMain() in library\n");
663        return nullptr;
664    }
665    if (pipelineDescriptor.fragmentFunction == nil) {
666        SkDebugf("Couldn't find fragmentMain() in library\n");
667        return nullptr;
668    }
669    SkASSERT(pipelineDescriptor.vertexFunction);
670    SkASSERT(pipelineDescriptor.fragmentFunction);
671
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();
676        if (archive) {
677            NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
678            pipelineDescriptor.binaryArchives = archiveArray;
679            BOOL result;
680            {
681                TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
682                result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
683                                                                            error: &error];
684            }
685            if (!result && error) {
686                SkDebugf("Error storing pipeline: %s\n",
687                        [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
688            }
689        }
690    }
691#endif
692
693    id<MTLRenderPipelineState> pipelineState;
694    {
695        TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
696#if defined(SK_BUILD_FOR_MAC)
697        pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
698                                                     fGpu->device(), pipelineDescriptor, &error);
699#else
700        pipelineState =
701            [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
702                                                           error: &error];
703#endif
704    }
705    if (error) {
706        SkDebugf("Error creating pipeline: %s\n",
707                 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
708        return nullptr;
709    }
710    if (!pipelineState) {
711        return nullptr;
712    }
713
714    sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState);
715
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,
721                                  fUniformHandles,
722                                  fUniformHandler.fUniforms,
723                                  bufferSize,
724                                  (uint32_t)fUniformHandler.numSamplers(),
725                                  std::move(fGPImpl),
726                                  std::move(fXPImpl),
727                                  std::move(fFPImpls));
728}
729
730//////////////////////////////////////////////////////////////////////////////
731
732bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData,
733                                                  GrMtlPrecompiledLibraries* precompiledLibs) {
734    SkASSERT(precompiledLibs);
735
736    SkReadBuffer reader(cachedData.data(), cachedData.size());
737    SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);
738
739    auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();
740
741    SkSL::Program::Settings settings;
742    settings.fSharpenTextures = gpu->getContext()->priv().options().fSharpenMipmappedTextures;
743    GrPersistentCacheUtils::ShaderMetadata meta;
744    meta.fSettings = &settings;
745
746    std::string shaders[kGrShaderTypeCount];
747    SkSL::Program::Inputs inputs[kGrShaderTypeCount];
748    if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount,
749                                                     &meta)) {
750        return false;
751    }
752
753    // skip the size
754    reader.readUInt();
755    auto pipelineDescriptor = read_pipeline_data(&reader);
756    if (!reader.isValid()) {
757        return false;
758    }
759
760    switch (shaderType) {
761        case kMSL_Tag: {
762            precompiledLibs->fVertexLibrary =
763                    GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
764            precompiledLibs->fFragmentLibrary =
765                    GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
766            break;
767        }
768
769        case kSKSL_Tag: {
770            std::string msl[kGrShaderTypeCount];
771            if (!GrSkSLToMSL(gpu,
772                           shaders[kVertex_GrShaderType],
773                           SkSL::ProgramKind::kVertex,
774                           settings,
775                           &msl[kVertex_GrShaderType],
776                           &inputs[kVertex_GrShaderType],
777                           errorHandler)) {
778                return false;
779            }
780            if (!GrSkSLToMSL(gpu,
781                           shaders[kFragment_GrShaderType],
782                           SkSL::ProgramKind::kFragment,
783                           settings,
784                           &msl[kFragment_GrShaderType],
785                           &inputs[kFragment_GrShaderType],
786                           errorHandler)) {
787                return false;
788            }
789            precompiledLibs->fVertexLibrary =
790                    GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
791            precompiledLibs->fFragmentLibrary =
792                    GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
793            break;
794        }
795
796        default: {
797            return false;
798        }
799    }
800
801    pipelineDescriptor.vertexFunction =
802            [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
803    pipelineDescriptor.fragmentFunction =
804            [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
805
806#if GR_METAL_SDK_VERSION >= 230
807    if (@available(macOS 11.0, iOS 14.0, *)) {
808        id<MTLBinaryArchive> archive = gpu->binaryArchive();
809        if (archive) {
810            NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
811            pipelineDescriptor.binaryArchives = archiveArray;
812            BOOL result;
813            NSError* error = nil;
814            {
815                TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
816                result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
817                                                                            error: &error];
818            }
819            if (!result && error) {
820                SkDebugf("Error storing pipeline: %s\n",
821                        [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
822            }
823        }
824    }
825#endif
826    {
827        TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
828        MTLNewRenderPipelineStateCompletionHandler completionHandler =
829                 ^(id<MTLRenderPipelineState> state, NSError* error) {
830                     if (error) {
831                         SkDebugf("Error creating pipeline: %s\n",
832                                  [[error localizedDescription]
833                                           cStringUsingEncoding: NSASCIIStringEncoding]);
834                     }
835                 };
836
837        // kick off asynchronous pipeline build and depend on Apple's cache to manage it
838        [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
839                                          completionHandler: completionHandler];
840    }
841
842    precompiledLibs->fRTFlip = inputs[kFragment_GrShaderType].fUseFlipRTUniform;
843    return true;
844}
845
846GR_NORETAIN_END
847