xref: /aosp_15_r20/external/skia/src/gpu/graphite/mtl/MtlGraphicsPipeline.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphicsPipeline.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/TextureInfo.h"
11*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/Attribute.h"
12*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/ContextUtils.h"
13*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/GraphicsPipelineDesc.h"
14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/Log.h"
15*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/RenderPassDesc.h"
16*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/RendererProvider.h"
17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/ShaderInfo.h"
18*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteTypesPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteUtilsPriv.h"
20*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlResourceProvider.h"
21*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlSharedContext.h"
22*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h"
23*c8dee2aaSAndroid Build Coastguard Worker#include "src/sksl/SkSLCompiler.h"
24*c8dee2aaSAndroid Build Coastguard Worker#include "src/sksl/SkSLProgramSettings.h"
25*c8dee2aaSAndroid Build Coastguard Worker#include "src/sksl/ir/SkSLProgram.h"
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Workernamespace skgpu::graphite {
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Workernamespace {
30*c8dee2aaSAndroid Build Coastguard Worker
31*c8dee2aaSAndroid Build Coastguard Workerinline MTLVertexFormat attribute_type_to_mtlformat(VertexAttribType type) {
32*c8dee2aaSAndroid Build Coastguard Worker    switch (type) {
33*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kFloat:
34*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatFloat;
35*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kFloat2:
36*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatFloat2;
37*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kFloat3:
38*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatFloat3;
39*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kFloat4:
40*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatFloat4;
41*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kHalf:
42*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
43*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatHalf;
44*c8dee2aaSAndroid Build Coastguard Worker            } else {
45*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatInvalid;
46*c8dee2aaSAndroid Build Coastguard Worker            }
47*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kHalf2:
48*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatHalf2;
49*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kHalf4:
50*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatHalf4;
51*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kInt2:
52*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatInt2;
53*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kInt3:
54*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatInt3;
55*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kInt4:
56*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatInt4;
57*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUInt2:
58*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUInt2;
59*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kByte:
60*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
61*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatChar;
62*c8dee2aaSAndroid Build Coastguard Worker            } else {
63*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatInvalid;
64*c8dee2aaSAndroid Build Coastguard Worker            }
65*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kByte2:
66*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatChar2;
67*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kByte4:
68*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatChar4;
69*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUByte:
70*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
71*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatUChar;
72*c8dee2aaSAndroid Build Coastguard Worker            } else {
73*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatInvalid;
74*c8dee2aaSAndroid Build Coastguard Worker            }
75*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUByte2:
76*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUChar2;
77*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUByte4:
78*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUChar4;
79*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUByte_norm:
80*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
81*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatUCharNormalized;
82*c8dee2aaSAndroid Build Coastguard Worker            } else {
83*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatInvalid;
84*c8dee2aaSAndroid Build Coastguard Worker            }
85*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUByte4_norm:
86*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUChar4Normalized;
87*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kShort2:
88*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatShort2;
89*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kShort4:
90*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatShort4;
91*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUShort2:
92*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUShort2;
93*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUShort2_norm:
94*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUShort2Normalized;
95*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kInt:
96*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatInt;
97*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUInt:
98*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUInt;
99*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUShort_norm:
100*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
101*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatUShortNormalized;
102*c8dee2aaSAndroid Build Coastguard Worker            } else {
103*c8dee2aaSAndroid Build Coastguard Worker                return MTLVertexFormatInvalid;
104*c8dee2aaSAndroid Build Coastguard Worker            }
105*c8dee2aaSAndroid Build Coastguard Worker        case VertexAttribType::kUShort4_norm:
106*c8dee2aaSAndroid Build Coastguard Worker            return MTLVertexFormatUShort4Normalized;
107*c8dee2aaSAndroid Build Coastguard Worker    }
108*c8dee2aaSAndroid Build Coastguard Worker    SK_ABORT("Unknown vertex attribute type");
109*c8dee2aaSAndroid Build Coastguard Worker}
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard WorkerMTLVertexDescriptor* create_vertex_descriptor(SkSpan<const Attribute> vertexAttrs,
112*c8dee2aaSAndroid Build Coastguard Worker                                              SkSpan<const Attribute> instanceAttrs) {
113*c8dee2aaSAndroid Build Coastguard Worker    auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
114*c8dee2aaSAndroid Build Coastguard Worker    int attributeIndex = 0;
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker    size_t vertexAttributeOffset = 0;
117*c8dee2aaSAndroid Build Coastguard Worker    for (const auto& attribute : vertexAttrs) {
118*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
119*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
120*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(MTLVertexFormatInvalid != format);
121*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.format = format;
122*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.offset = vertexAttributeOffset;
123*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.bufferIndex = MtlGraphicsPipeline::kVertexBufferIndex;
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker        vertexAttributeOffset += attribute.sizeAlign4();
126*c8dee2aaSAndroid Build Coastguard Worker        attributeIndex++;
127*c8dee2aaSAndroid Build Coastguard Worker    }
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker    if (vertexAttributeOffset) {
130*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
131*c8dee2aaSAndroid Build Coastguard Worker                vertexDescriptor.layouts[MtlGraphicsPipeline::kVertexBufferIndex];
132*c8dee2aaSAndroid Build Coastguard Worker        vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
133*c8dee2aaSAndroid Build Coastguard Worker        vertexBufferLayout.stepRate = 1;
134*c8dee2aaSAndroid Build Coastguard Worker        vertexBufferLayout.stride = vertexAttributeOffset;
135*c8dee2aaSAndroid Build Coastguard Worker    }
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker    size_t instanceAttributeOffset = 0;
138*c8dee2aaSAndroid Build Coastguard Worker    for (const auto& attribute : instanceAttrs) {
139*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
140*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
141*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(MTLVertexFormatInvalid != format);
142*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.format = format;
143*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.offset = instanceAttributeOffset;
144*c8dee2aaSAndroid Build Coastguard Worker        mtlAttribute.bufferIndex = MtlGraphicsPipeline::kInstanceBufferIndex;
145*c8dee2aaSAndroid Build Coastguard Worker
146*c8dee2aaSAndroid Build Coastguard Worker        instanceAttributeOffset += attribute.sizeAlign4();
147*c8dee2aaSAndroid Build Coastguard Worker        attributeIndex++;
148*c8dee2aaSAndroid Build Coastguard Worker    }
149*c8dee2aaSAndroid Build Coastguard Worker
150*c8dee2aaSAndroid Build Coastguard Worker    if (instanceAttributeOffset) {
151*c8dee2aaSAndroid Build Coastguard Worker        MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
152*c8dee2aaSAndroid Build Coastguard Worker                vertexDescriptor.layouts[MtlGraphicsPipeline::kInstanceBufferIndex];
153*c8dee2aaSAndroid Build Coastguard Worker        instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
154*c8dee2aaSAndroid Build Coastguard Worker        instanceBufferLayout.stepRate = 1;
155*c8dee2aaSAndroid Build Coastguard Worker        instanceBufferLayout.stride = instanceAttributeOffset;
156*c8dee2aaSAndroid Build Coastguard Worker    }
157*c8dee2aaSAndroid Build Coastguard Worker    return vertexDescriptor;
158*c8dee2aaSAndroid Build Coastguard Worker}
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker// TODO: share this w/ Ganesh Metal backend?
161*c8dee2aaSAndroid Build Coastguard Workerstatic MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff) {
162*c8dee2aaSAndroid Build Coastguard Worker    switch (coeff) {
163*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kZero:
164*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorZero;
165*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kOne:
166*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOne;
167*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kSC:
168*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorSourceColor;
169*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kISC:
170*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOneMinusSourceColor;
171*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kDC:
172*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorDestinationColor;
173*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIDC:
174*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOneMinusDestinationColor;
175*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kSA:
176*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorSourceAlpha;
177*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kISA:
178*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOneMinusSourceAlpha;
179*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kDA:
180*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorDestinationAlpha;
181*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIDA:
182*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOneMinusDestinationAlpha;
183*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kConstC:
184*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorBlendColor;
185*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIConstC:
186*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorOneMinusBlendColor;
187*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kS2C:
188*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
189*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorSource1Color;
190*c8dee2aaSAndroid Build Coastguard Worker            } else {
191*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorZero;
192*c8dee2aaSAndroid Build Coastguard Worker            }
193*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIS2C:
194*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
195*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorOneMinusSource1Color;
196*c8dee2aaSAndroid Build Coastguard Worker            } else {
197*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorZero;
198*c8dee2aaSAndroid Build Coastguard Worker            }
199*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kS2A:
200*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
201*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorSource1Alpha;
202*c8dee2aaSAndroid Build Coastguard Worker            } else {
203*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorZero;
204*c8dee2aaSAndroid Build Coastguard Worker            }
205*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIS2A:
206*c8dee2aaSAndroid Build Coastguard Worker            if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
207*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorOneMinusSource1Alpha;
208*c8dee2aaSAndroid Build Coastguard Worker            } else {
209*c8dee2aaSAndroid Build Coastguard Worker                return MTLBlendFactorZero;
210*c8dee2aaSAndroid Build Coastguard Worker            }
211*c8dee2aaSAndroid Build Coastguard Worker        case skgpu::BlendCoeff::kIllegal:
212*c8dee2aaSAndroid Build Coastguard Worker            return MTLBlendFactorZero;
213*c8dee2aaSAndroid Build Coastguard Worker    }
214*c8dee2aaSAndroid Build Coastguard Worker
215*c8dee2aaSAndroid Build Coastguard Worker    SK_ABORT("Unknown blend coefficient");
216*c8dee2aaSAndroid Build Coastguard Worker}
217*c8dee2aaSAndroid Build Coastguard Worker
218*c8dee2aaSAndroid Build Coastguard Worker// TODO: share this w/ Ganesh Metal backend?
219*c8dee2aaSAndroid Build Coastguard Workerstatic MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation) {
220*c8dee2aaSAndroid Build Coastguard Worker    static const MTLBlendOperation gTable[] = {
221*c8dee2aaSAndroid Build Coastguard Worker            MTLBlendOperationAdd,              // skgpu::BlendEquation::kAdd
222*c8dee2aaSAndroid Build Coastguard Worker            MTLBlendOperationSubtract,         // skgpu::BlendEquation::kSubtract
223*c8dee2aaSAndroid Build Coastguard Worker            MTLBlendOperationReverseSubtract,  // skgpu::BlendEquation::kReverseSubtract
224*c8dee2aaSAndroid Build Coastguard Worker    };
225*c8dee2aaSAndroid Build Coastguard Worker    static_assert(std::size(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
226*c8dee2aaSAndroid Build Coastguard Worker    static_assert(0 == (int)skgpu::BlendEquation::kAdd);
227*c8dee2aaSAndroid Build Coastguard Worker    static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
228*c8dee2aaSAndroid Build Coastguard Worker    static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
229*c8dee2aaSAndroid Build Coastguard Worker
230*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
231*c8dee2aaSAndroid Build Coastguard Worker    return gTable[(int)equation];
232*c8dee2aaSAndroid Build Coastguard Worker}
233*c8dee2aaSAndroid Build Coastguard Worker
234*c8dee2aaSAndroid Build Coastguard Workerstatic MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
235*c8dee2aaSAndroid Build Coastguard Worker        MTLPixelFormat format,
236*c8dee2aaSAndroid Build Coastguard Worker        const BlendInfo& blendInfo) {
237*c8dee2aaSAndroid Build Coastguard Worker
238*c8dee2aaSAndroid Build Coastguard Worker    skgpu::BlendEquation equation = blendInfo.fEquation;
239*c8dee2aaSAndroid Build Coastguard Worker    skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
240*c8dee2aaSAndroid Build Coastguard Worker    skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
241*c8dee2aaSAndroid Build Coastguard Worker    bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
242*c8dee2aaSAndroid Build Coastguard Worker
243*c8dee2aaSAndroid Build Coastguard Worker    // TODO: I *think* this gets cleaned up by the pipelineDescriptor?
244*c8dee2aaSAndroid Build Coastguard Worker    auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
245*c8dee2aaSAndroid Build Coastguard Worker
246*c8dee2aaSAndroid Build Coastguard Worker    mtlColorAttachment.pixelFormat = format;
247*c8dee2aaSAndroid Build Coastguard Worker
248*c8dee2aaSAndroid Build Coastguard Worker    mtlColorAttachment.blendingEnabled = blendOn;
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker    if (blendOn) {
251*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
252*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
253*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
254*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
255*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
256*c8dee2aaSAndroid Build Coastguard Worker        mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
257*c8dee2aaSAndroid Build Coastguard Worker    }
258*c8dee2aaSAndroid Build Coastguard Worker
259*c8dee2aaSAndroid Build Coastguard Worker    mtlColorAttachment.writeMask = blendInfo.fWritesColor ? MTLColorWriteMaskAll
260*c8dee2aaSAndroid Build Coastguard Worker                                                          : MTLColorWriteMaskNone;
261*c8dee2aaSAndroid Build Coastguard Worker
262*c8dee2aaSAndroid Build Coastguard Worker    return mtlColorAttachment;
263*c8dee2aaSAndroid Build Coastguard Worker}
264*c8dee2aaSAndroid Build Coastguard Worker
265*c8dee2aaSAndroid Build Coastguard Worker} // anonymous namespace
266*c8dee2aaSAndroid Build Coastguard Worker
267*c8dee2aaSAndroid Build Coastguard Workersk_sp<MtlGraphicsPipeline> MtlGraphicsPipeline::Make(
268*c8dee2aaSAndroid Build Coastguard Worker        const MtlSharedContext* sharedContext,
269*c8dee2aaSAndroid Build Coastguard Worker        MtlResourceProvider* resourceProvider,
270*c8dee2aaSAndroid Build Coastguard Worker        const RuntimeEffectDictionary* runtimeDict,
271*c8dee2aaSAndroid Build Coastguard Worker        const GraphicsPipelineDesc& pipelineDesc,
272*c8dee2aaSAndroid Build Coastguard Worker        const RenderPassDesc& renderPassDesc,
273*c8dee2aaSAndroid Build Coastguard Worker        SkEnumBitMask<PipelineCreationFlags> pipelineCreationFlags) {
274*c8dee2aaSAndroid Build Coastguard Worker    std::string vsMSL, fsMSL;
275*c8dee2aaSAndroid Build Coastguard Worker    SkSL::Program::Interface vsInterface, fsInterface;
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker    SkSL::ProgramSettings settings;
278*c8dee2aaSAndroid Build Coastguard Worker    settings.fSharpenTextures = true;
279*c8dee2aaSAndroid Build Coastguard Worker    settings.fForceNoRTFlip = true;
280*c8dee2aaSAndroid Build Coastguard Worker
281*c8dee2aaSAndroid Build Coastguard Worker    SkSL::Compiler skslCompiler;
282*c8dee2aaSAndroid Build Coastguard Worker    ShaderErrorHandler* errorHandler = sharedContext->caps()->shaderErrorHandler();
283*c8dee2aaSAndroid Build Coastguard Worker
284*c8dee2aaSAndroid Build Coastguard Worker    const RenderStep* step =
285*c8dee2aaSAndroid Build Coastguard Worker            sharedContext->rendererProvider()->lookup(pipelineDesc.renderStepID());
286*c8dee2aaSAndroid Build Coastguard Worker    const bool useStorageBuffers = sharedContext->caps()->storageBufferSupport();
287*c8dee2aaSAndroid Build Coastguard Worker
288*c8dee2aaSAndroid Build Coastguard Worker    UniquePaintParamsID paintID = pipelineDesc.paintParamsID();
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker    std::unique_ptr<ShaderInfo> shaderInfo = ShaderInfo::Make(sharedContext->caps(),
291*c8dee2aaSAndroid Build Coastguard Worker                                                              sharedContext->shaderCodeDictionary(),
292*c8dee2aaSAndroid Build Coastguard Worker                                                              runtimeDict,
293*c8dee2aaSAndroid Build Coastguard Worker                                                              step,
294*c8dee2aaSAndroid Build Coastguard Worker                                                              paintID,
295*c8dee2aaSAndroid Build Coastguard Worker                                                              useStorageBuffers,
296*c8dee2aaSAndroid Build Coastguard Worker                                                              renderPassDesc.fWriteSwizzle);
297*c8dee2aaSAndroid Build Coastguard Worker
298*c8dee2aaSAndroid Build Coastguard Worker    const std::string& fsSkSL = shaderInfo->fragmentSkSL();
299*c8dee2aaSAndroid Build Coastguard Worker    const BlendInfo& blendInfo = shaderInfo->blendInfo();
300*c8dee2aaSAndroid Build Coastguard Worker    if (!SkSLToMSL(sharedContext->caps()->shaderCaps(),
301*c8dee2aaSAndroid Build Coastguard Worker                   fsSkSL,
302*c8dee2aaSAndroid Build Coastguard Worker                   SkSL::ProgramKind::kGraphiteFragment,
303*c8dee2aaSAndroid Build Coastguard Worker                   settings,
304*c8dee2aaSAndroid Build Coastguard Worker                   &fsMSL,
305*c8dee2aaSAndroid Build Coastguard Worker                   &fsInterface,
306*c8dee2aaSAndroid Build Coastguard Worker                   errorHandler)) {
307*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
308*c8dee2aaSAndroid Build Coastguard Worker    }
309*c8dee2aaSAndroid Build Coastguard Worker
310*c8dee2aaSAndroid Build Coastguard Worker    const std::string& vsSkSL = shaderInfo->vertexSkSL();
311*c8dee2aaSAndroid Build Coastguard Worker    if (!SkSLToMSL(sharedContext->caps()->shaderCaps(),
312*c8dee2aaSAndroid Build Coastguard Worker                   vsSkSL,
313*c8dee2aaSAndroid Build Coastguard Worker                   SkSL::ProgramKind::kGraphiteVertex,
314*c8dee2aaSAndroid Build Coastguard Worker                   settings,
315*c8dee2aaSAndroid Build Coastguard Worker                   &vsMSL,
316*c8dee2aaSAndroid Build Coastguard Worker                   &vsInterface,
317*c8dee2aaSAndroid Build Coastguard Worker                   errorHandler)) {
318*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
319*c8dee2aaSAndroid Build Coastguard Worker    }
320*c8dee2aaSAndroid Build Coastguard Worker
321*c8dee2aaSAndroid Build Coastguard Worker    auto vsLibrary =
322*c8dee2aaSAndroid Build Coastguard Worker            MtlCompileShaderLibrary(sharedContext, shaderInfo->vsLabel(), vsMSL, errorHandler);
323*c8dee2aaSAndroid Build Coastguard Worker    auto fsLibrary =
324*c8dee2aaSAndroid Build Coastguard Worker            MtlCompileShaderLibrary(sharedContext, shaderInfo->fsLabel(), fsMSL, errorHandler);
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<id<MTLDepthStencilState>> dss =
327*c8dee2aaSAndroid Build Coastguard Worker            resourceProvider->findOrCreateCompatibleDepthStencilState(step->depthStencilSettings());
328*c8dee2aaSAndroid Build Coastguard Worker
329*c8dee2aaSAndroid Build Coastguard Worker    PipelineInfo pipelineInfo{*shaderInfo, pipelineCreationFlags};
330*c8dee2aaSAndroid Build Coastguard Worker#if defined(GPU_TEST_UTILS)
331*c8dee2aaSAndroid Build Coastguard Worker    pipelineInfo.fNativeVertexShader = std::move(vsMSL);
332*c8dee2aaSAndroid Build Coastguard Worker    pipelineInfo.fNativeFragmentShader = std::move(fsMSL);
333*c8dee2aaSAndroid Build Coastguard Worker#endif
334*c8dee2aaSAndroid Build Coastguard Worker
335*c8dee2aaSAndroid Build Coastguard Worker    std::string pipelineLabel =
336*c8dee2aaSAndroid Build Coastguard Worker            GetPipelineLabel(sharedContext->shaderCodeDictionary(), renderPassDesc, step, paintID);
337*c8dee2aaSAndroid Build Coastguard Worker    return Make(sharedContext,
338*c8dee2aaSAndroid Build Coastguard Worker                pipelineLabel,
339*c8dee2aaSAndroid Build Coastguard Worker                pipelineInfo,
340*c8dee2aaSAndroid Build Coastguard Worker                {vsLibrary.get(), "vertexMain"},
341*c8dee2aaSAndroid Build Coastguard Worker                step->vertexAttributes(),
342*c8dee2aaSAndroid Build Coastguard Worker                step->instanceAttributes(),
343*c8dee2aaSAndroid Build Coastguard Worker                {fsLibrary.get(), "fragmentMain"},
344*c8dee2aaSAndroid Build Coastguard Worker                std::move(dss),
345*c8dee2aaSAndroid Build Coastguard Worker                step->depthStencilSettings().fStencilReferenceValue,
346*c8dee2aaSAndroid Build Coastguard Worker                blendInfo,
347*c8dee2aaSAndroid Build Coastguard Worker                renderPassDesc);
348*c8dee2aaSAndroid Build Coastguard Worker}
349*c8dee2aaSAndroid Build Coastguard Worker
350*c8dee2aaSAndroid Build Coastguard Workersk_sp<MtlGraphicsPipeline> MtlGraphicsPipeline::MakeLoadMSAAPipeline(
351*c8dee2aaSAndroid Build Coastguard Worker        const MtlSharedContext* sharedContext,
352*c8dee2aaSAndroid Build Coastguard Worker        MtlResourceProvider* resourceProvider,
353*c8dee2aaSAndroid Build Coastguard Worker        const RenderPassDesc& renderPassDesc) {
354*c8dee2aaSAndroid Build Coastguard Worker    static const char* kLoadMSAAShaderText = R"(
355*c8dee2aaSAndroid Build Coastguard Worker            #include <metal_stdlib>
356*c8dee2aaSAndroid Build Coastguard Worker            #include <simd/simd.h>
357*c8dee2aaSAndroid Build Coastguard Worker            using namespace metal;
358*c8dee2aaSAndroid Build Coastguard Worker
359*c8dee2aaSAndroid Build Coastguard Worker            typedef struct {
360*c8dee2aaSAndroid Build Coastguard Worker                float4 position [[position]];
361*c8dee2aaSAndroid Build Coastguard Worker            } VertexOutput;
362*c8dee2aaSAndroid Build Coastguard Worker
363*c8dee2aaSAndroid Build Coastguard Worker            vertex VertexOutput vertexMain(uint vertexID [[vertex_id]]) {
364*c8dee2aaSAndroid Build Coastguard Worker                VertexOutput out;
365*c8dee2aaSAndroid Build Coastguard Worker                float2 position = float2(float(vertexID >> 1), float(vertexID & 1));
366*c8dee2aaSAndroid Build Coastguard Worker                out.position = float4(2.0 * position - 1.0, 0.0, 1.0);
367*c8dee2aaSAndroid Build Coastguard Worker                return out;
368*c8dee2aaSAndroid Build Coastguard Worker            }
369*c8dee2aaSAndroid Build Coastguard Worker
370*c8dee2aaSAndroid Build Coastguard Worker            fragment float4 fragmentMain(VertexOutput in [[stage_in]],
371*c8dee2aaSAndroid Build Coastguard Worker                                            texture2d<half> colorMap [[texture(0)]]) {
372*c8dee2aaSAndroid Build Coastguard Worker                uint2 coords = uint2(in.position.x, in.position.y);
373*c8dee2aaSAndroid Build Coastguard Worker                half4 colorSample   = colorMap.read(coords);
374*c8dee2aaSAndroid Build Coastguard Worker                return float4(colorSample);
375*c8dee2aaSAndroid Build Coastguard Worker            }
376*c8dee2aaSAndroid Build Coastguard Worker    )";
377*c8dee2aaSAndroid Build Coastguard Worker
378*c8dee2aaSAndroid Build Coastguard Worker    auto mtlLibrary = MtlCompileShaderLibrary(sharedContext,
379*c8dee2aaSAndroid Build Coastguard Worker                                              "LoadMSAAFromResolve",
380*c8dee2aaSAndroid Build Coastguard Worker                                              kLoadMSAAShaderText,
381*c8dee2aaSAndroid Build Coastguard Worker                                              sharedContext->caps()->shaderErrorHandler());
382*c8dee2aaSAndroid Build Coastguard Worker    BlendInfo noBlend{}; // default is equivalent to kSrc blending
383*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<id<MTLDepthStencilState>> ignoreDS =
384*c8dee2aaSAndroid Build Coastguard Worker            resourceProvider->findOrCreateCompatibleDepthStencilState({});
385*c8dee2aaSAndroid Build Coastguard Worker
386*c8dee2aaSAndroid Build Coastguard Worker    std::string pipelineLabel = "LoadMSAAFromResolve + ";
387*c8dee2aaSAndroid Build Coastguard Worker    pipelineLabel += renderPassDesc.toString().c_str();
388*c8dee2aaSAndroid Build Coastguard Worker
389*c8dee2aaSAndroid Build Coastguard Worker    PipelineInfo pipelineInfo;
390*c8dee2aaSAndroid Build Coastguard Worker    pipelineInfo.fNumFragTexturesAndSamplers = 1;
391*c8dee2aaSAndroid Build Coastguard Worker    // This is an internal shader, leave off filling out the test-utils shader code
392*c8dee2aaSAndroid Build Coastguard Worker    return Make(sharedContext,
393*c8dee2aaSAndroid Build Coastguard Worker                pipelineLabel,
394*c8dee2aaSAndroid Build Coastguard Worker                pipelineInfo,
395*c8dee2aaSAndroid Build Coastguard Worker                {mtlLibrary.get(), "vertexMain"},
396*c8dee2aaSAndroid Build Coastguard Worker                /*vertexAttrs=*/{},
397*c8dee2aaSAndroid Build Coastguard Worker                /*instanceAttrs=*/{},
398*c8dee2aaSAndroid Build Coastguard Worker                {mtlLibrary.get(), "fragmentMain"},
399*c8dee2aaSAndroid Build Coastguard Worker                std::move(ignoreDS),
400*c8dee2aaSAndroid Build Coastguard Worker                /*stencilRefValue=*/0,
401*c8dee2aaSAndroid Build Coastguard Worker                noBlend,
402*c8dee2aaSAndroid Build Coastguard Worker                renderPassDesc);
403*c8dee2aaSAndroid Build Coastguard Worker}
404*c8dee2aaSAndroid Build Coastguard Worker
405*c8dee2aaSAndroid Build Coastguard Workersk_sp<MtlGraphicsPipeline> MtlGraphicsPipeline::Make(const MtlSharedContext* sharedContext,
406*c8dee2aaSAndroid Build Coastguard Worker                                                     const std::string& label,
407*c8dee2aaSAndroid Build Coastguard Worker                                                     const PipelineInfo& pipelineInfo,
408*c8dee2aaSAndroid Build Coastguard Worker                                                     MSLFunction vertexMain,
409*c8dee2aaSAndroid Build Coastguard Worker                                                     SkSpan<const Attribute> vertexAttrs,
410*c8dee2aaSAndroid Build Coastguard Worker                                                     SkSpan<const Attribute> instanceAttrs,
411*c8dee2aaSAndroid Build Coastguard Worker                                                     MSLFunction fragmentMain,
412*c8dee2aaSAndroid Build Coastguard Worker                                                     sk_cfp<id<MTLDepthStencilState>> dss,
413*c8dee2aaSAndroid Build Coastguard Worker                                                     uint32_t stencilRefValue,
414*c8dee2aaSAndroid Build Coastguard Worker                                                     const BlendInfo& blendInfo,
415*c8dee2aaSAndroid Build Coastguard Worker                                                     const RenderPassDesc& renderPassDesc) {
416*c8dee2aaSAndroid Build Coastguard Worker    id<MTLLibrary> vsLibrary = std::get<0>(vertexMain);
417*c8dee2aaSAndroid Build Coastguard Worker    id<MTLLibrary> fsLibrary = std::get<0>(fragmentMain);
418*c8dee2aaSAndroid Build Coastguard Worker    if (!vsLibrary || !fsLibrary) {
419*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
420*c8dee2aaSAndroid Build Coastguard Worker    }
421*c8dee2aaSAndroid Build Coastguard Worker
422*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<MTLRenderPipelineDescriptor*> psoDescriptor([[MTLRenderPipelineDescriptor alloc] init]);
423*c8dee2aaSAndroid Build Coastguard Worker
424*c8dee2aaSAndroid Build Coastguard Worker    NSString* labelName =  [NSString stringWithUTF8String: label.c_str()];
425*c8dee2aaSAndroid Build Coastguard Worker    NSString* vsFuncName = [NSString stringWithUTF8String: std::get<1>(vertexMain).c_str()];
426*c8dee2aaSAndroid Build Coastguard Worker    NSString* fsFuncName = [NSString stringWithUTF8String: std::get<1>(fragmentMain).c_str()];
427*c8dee2aaSAndroid Build Coastguard Worker
428*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).label = labelName;
429*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).vertexFunction = [vsLibrary newFunctionWithName: vsFuncName];
430*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).fragmentFunction = [fsLibrary newFunctionWithName: fsFuncName];
431*c8dee2aaSAndroid Build Coastguard Worker
432*c8dee2aaSAndroid Build Coastguard Worker    // TODO: I *think* this gets cleaned up by the pipelineDescriptor?
433*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).vertexDescriptor = create_vertex_descriptor(vertexAttrs, instanceAttrs);
434*c8dee2aaSAndroid Build Coastguard Worker
435*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat pixelFormat =
436*c8dee2aaSAndroid Build Coastguard Worker            TextureInfos::GetMTLPixelFormat(renderPassDesc.fColorAttachment.fTextureInfo);
437*c8dee2aaSAndroid Build Coastguard Worker    auto mtlColorAttachment = create_color_attachment(pixelFormat, blendInfo);
438*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).colorAttachments[0] = mtlColorAttachment;
439*c8dee2aaSAndroid Build Coastguard Worker
440*c8dee2aaSAndroid Build Coastguard Worker    (*psoDescriptor).rasterSampleCount =
441*c8dee2aaSAndroid Build Coastguard Worker            renderPassDesc.fColorAttachment.fTextureInfo.numSamples();
442*c8dee2aaSAndroid Build Coastguard Worker
443*c8dee2aaSAndroid Build Coastguard Worker    MTLPixelFormat depthStencilFormat =
444*c8dee2aaSAndroid Build Coastguard Worker            TextureInfos::GetMTLPixelFormat(renderPassDesc.fDepthStencilAttachment.fTextureInfo);
445*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsStencil(depthStencilFormat)) {
446*c8dee2aaSAndroid Build Coastguard Worker        (*psoDescriptor).stencilAttachmentPixelFormat = depthStencilFormat;
447*c8dee2aaSAndroid Build Coastguard Worker    } else {
448*c8dee2aaSAndroid Build Coastguard Worker        (*psoDescriptor).stencilAttachmentPixelFormat = MTLPixelFormatInvalid;
449*c8dee2aaSAndroid Build Coastguard Worker    }
450*c8dee2aaSAndroid Build Coastguard Worker    if (MtlFormatIsDepth(depthStencilFormat)) {
451*c8dee2aaSAndroid Build Coastguard Worker        (*psoDescriptor).depthAttachmentPixelFormat = depthStencilFormat;
452*c8dee2aaSAndroid Build Coastguard Worker    } else {
453*c8dee2aaSAndroid Build Coastguard Worker        (*psoDescriptor).depthAttachmentPixelFormat = MTLPixelFormatInvalid;
454*c8dee2aaSAndroid Build Coastguard Worker    }
455*c8dee2aaSAndroid Build Coastguard Worker
456*c8dee2aaSAndroid Build Coastguard Worker    NSError* error;
457*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<id<MTLRenderPipelineState>> pso(
458*c8dee2aaSAndroid Build Coastguard Worker            [sharedContext->device() newRenderPipelineStateWithDescriptor:psoDescriptor.get()
459*c8dee2aaSAndroid Build Coastguard Worker                                                                    error:&error]);
460*c8dee2aaSAndroid Build Coastguard Worker    if (!pso) {
461*c8dee2aaSAndroid Build Coastguard Worker        SKGPU_LOG_E("Render pipeline creation failure:\n%s", error.debugDescription.UTF8String);
462*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
463*c8dee2aaSAndroid Build Coastguard Worker    }
464*c8dee2aaSAndroid Build Coastguard Worker
465*c8dee2aaSAndroid Build Coastguard Worker    return sk_sp<MtlGraphicsPipeline>(new MtlGraphicsPipeline(sharedContext,
466*c8dee2aaSAndroid Build Coastguard Worker                                                              pipelineInfo,
467*c8dee2aaSAndroid Build Coastguard Worker                                                              std::move(pso),
468*c8dee2aaSAndroid Build Coastguard Worker                                                              std::move(dss),
469*c8dee2aaSAndroid Build Coastguard Worker                                                              stencilRefValue));
470*c8dee2aaSAndroid Build Coastguard Worker}
471*c8dee2aaSAndroid Build Coastguard Worker
472*c8dee2aaSAndroid Build Coastguard WorkerMtlGraphicsPipeline::MtlGraphicsPipeline(const skgpu::graphite::SharedContext* sharedContext,
473*c8dee2aaSAndroid Build Coastguard Worker                                         const PipelineInfo& pipelineInfo,
474*c8dee2aaSAndroid Build Coastguard Worker                                         sk_cfp<id<MTLRenderPipelineState>> pso,
475*c8dee2aaSAndroid Build Coastguard Worker                                         sk_cfp<id<MTLDepthStencilState>> dss,
476*c8dee2aaSAndroid Build Coastguard Worker                                         uint32_t refValue)
477*c8dee2aaSAndroid Build Coastguard Worker        : GraphicsPipeline(sharedContext, pipelineInfo)
478*c8dee2aaSAndroid Build Coastguard Worker        , fPipelineState(std::move(pso))
479*c8dee2aaSAndroid Build Coastguard Worker        , fDepthStencilState(std::move(dss))
480*c8dee2aaSAndroid Build Coastguard Worker        , fStencilReferenceValue(refValue) {}
481*c8dee2aaSAndroid Build Coastguard Worker
482*c8dee2aaSAndroid Build Coastguard Workervoid MtlGraphicsPipeline::freeGpuData() {
483*c8dee2aaSAndroid Build Coastguard Worker    fPipelineState.reset();
484*c8dee2aaSAndroid Build Coastguard Worker}
485*c8dee2aaSAndroid Build Coastguard Worker
486*c8dee2aaSAndroid Build Coastguard Worker} // namespace skgpu::graphite
487