blob: 90b91ef4989933dd826ef474551533a4730fcde0 [file] [log] [blame]
Timothy Liang7ac582e2018-08-06 09:47:23 -04001/*
Timothy Liang44636e92018-08-08 10:50:21 -04002 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
Timothy Liang7ac582e2018-08-06 09:47:23 -04007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContext.h"
11#include "src/gpu/GrContextPriv.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -040012
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/mtl/GrMtlGpu.h"
14#include "src/gpu/mtl/GrMtlPipelineState.h"
15#include "src/gpu/mtl/GrMtlUtil.h"
Timothy Liang7ac582e2018-08-06 09:47:23 -040016
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/GrRenderTargetPriv.h"
Jim Van Verth2e4287f2019-03-05 12:16:11 -050018
Timothy Liang7ac582e2018-08-06 09:47:23 -040019#import <simd/simd.h>
20
Jim Van Verthcf23f582019-05-22 09:46:57 -040021#if !__has_feature(objc_arc)
22#error This file must be compiled with Arc. Use -fobjc-arc flag
23#endif
24
Timothy Liang7ac582e2018-08-06 09:47:23 -040025GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
Jim Van Verth1223e7f2019-02-28 17:38:35 -050026 GrMtlGpu* gpu,
Robert Phillipsd0fe8752019-01-31 14:13:59 -050027 GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
Timothy Liang7ac582e2018-08-06 09:47:23 -040028 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050029 const GrTextureProxy* const primProcProxies[],
Timothy Liang7ac582e2018-08-06 09:47:23 -040030 const GrPipeline& pipeline,
Jim Van Verth1223e7f2019-02-28 17:38:35 -050031 Desc* desc) {
32 GrMtlPipelineStateBuilder builder(gpu, renderTarget, origin, pipeline, primProc,
33 primProcProxies, desc);
Timothy Liang7ac582e2018-08-06 09:47:23 -040034
35 if (!builder.emitAndInstallProcs()) {
36 return nullptr;
37 }
Jim Van Verth2e4287f2019-03-05 12:16:11 -050038 return builder.finalize(renderTarget, primProc, pipeline, desc);
Timothy Liang7ac582e2018-08-06 09:47:23 -040039}
40
Jim Van Verth1223e7f2019-02-28 17:38:35 -050041GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
42 GrRenderTarget* renderTarget,
43 GrSurfaceOrigin origin,
44 const GrPipeline& pipeline,
Robert Phillipsd0fe8752019-01-31 14:13:59 -050045 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050046 const GrTextureProxy* const primProcProxies[],
Jim Van Verth1223e7f2019-02-28 17:38:35 -050047 GrProgramDesc* desc)
Robert Phillipsd0fe8752019-01-31 14:13:59 -050048 : INHERITED(renderTarget, origin, primProc, primProcProxies, pipeline, desc)
Timothy Liang057c3902018-08-08 10:48:45 -040049 , fGpu(gpu)
50 , fUniformHandler(this)
51 , fVaryingHandler(this) {
Timothy Liang7ac582e2018-08-06 09:47:23 -040052}
53
54const GrCaps* GrMtlPipelineStateBuilder::caps() const {
55 return fGpu->caps();
56}
57
58void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
59 outputColor.addLayoutQualifier("location = 0, index = 0");
60}
61
62void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
63 outputColor.addLayoutQualifier("location = 0, index = 1");
64}
65
66id<MTLLibrary> GrMtlPipelineStateBuilder::createMtlShaderLibrary(
67 const GrGLSLShaderBuilder& builder,
68 SkSL::Program::Kind kind,
69 const SkSL::Program::Settings& settings,
70 GrProgramDesc* desc) {
Timothy Liang7ac582e2018-08-06 09:47:23 -040071 SkSL::Program::Inputs inputs;
Brian Osman6c431d52019-04-15 16:31:54 -040072 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, builder.fCompilerString.c_str(),
Timothy Liang7ac582e2018-08-06 09:47:23 -040073 kind, settings, &inputs);
74 if (shaderLibrary == nil) {
75 return nil;
76 }
Greg Daniele6ab9982018-08-22 13:56:32 +000077 if (inputs.fRTHeight) {
78 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
Timothy Liang7ac582e2018-08-06 09:47:23 -040079 }
80 if (inputs.fFlipY) {
Robert Phillipsd0fe8752019-01-31 14:13:59 -050081 desc->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(this->origin()));
Timothy Liang7ac582e2018-08-06 09:47:23 -040082 }
83 return shaderLibrary;
84}
85
86static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
87 // All half types will actually be float types. We are currently not using half types with
88 // metal to avoid an issue with narrow type coercions (float->half) http://skbug.com/8221
89 switch (type) {
90 case kFloat_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -040091 return MTLVertexFormatFloat;
92 case kFloat2_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -040093 return MTLVertexFormatFloat2;
94 case kFloat3_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -040095 return MTLVertexFormatFloat3;
96 case kFloat4_GrVertexAttribType:
Timothy Liang7ac582e2018-08-06 09:47:23 -040097 return MTLVertexFormatFloat4;
Brian Osmand4c29702018-09-14 16:16:55 -040098 case kHalf_GrVertexAttribType:
99 return MTLVertexFormatHalf;
100 case kHalf2_GrVertexAttribType:
101 return MTLVertexFormatHalf2;
102 case kHalf3_GrVertexAttribType:
103 return MTLVertexFormatHalf3;
104 case kHalf4_GrVertexAttribType:
105 return MTLVertexFormatHalf4;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400106 case kInt2_GrVertexAttribType:
107 return MTLVertexFormatInt2;
108 case kInt3_GrVertexAttribType:
109 return MTLVertexFormatInt3;
110 case kInt4_GrVertexAttribType:
111 return MTLVertexFormatInt4;
112 case kByte_GrVertexAttribType:
113 return MTLVertexFormatChar;
114 case kByte2_GrVertexAttribType:
115 return MTLVertexFormatChar2;
116 case kByte3_GrVertexAttribType:
117 return MTLVertexFormatChar3;
118 case kByte4_GrVertexAttribType:
119 return MTLVertexFormatChar4;
120 case kUByte_GrVertexAttribType:
121 return MTLVertexFormatUChar;
122 case kUByte2_GrVertexAttribType:
123 return MTLVertexFormatUChar2;
124 case kUByte3_GrVertexAttribType:
125 return MTLVertexFormatUChar3;
126 case kUByte4_GrVertexAttribType:
127 return MTLVertexFormatUChar4;
128 case kUByte_norm_GrVertexAttribType:
129 return MTLVertexFormatUCharNormalized;
130 case kUByte4_norm_GrVertexAttribType:
131 return MTLVertexFormatUChar4Normalized;
132 case kShort2_GrVertexAttribType:
133 return MTLVertexFormatShort2;
Brian Osmana5c578f2018-09-19 14:19:02 -0400134 case kShort4_GrVertexAttribType:
135 return MTLVertexFormatShort4;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400136 case kUShort2_GrVertexAttribType:
137 return MTLVertexFormatUShort2;
138 case kUShort2_norm_GrVertexAttribType:
139 return MTLVertexFormatUShort2Normalized;
140 case kInt_GrVertexAttribType:
141 return MTLVertexFormatInt;
142 case kUint_GrVertexAttribType:
143 return MTLVertexFormatUInt;
Robert Phillipsf83c4682019-06-13 16:49:21 +0000144 // Experimental (for P016 and P010)
Robert Phillipsfe18de52019-06-06 17:21:50 -0400145 case kUShort_norm_GrVertexAttribType:
146 return MTLVertexFormatUShortNormalized;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400147 }
148 SK_ABORT("Unknown vertex attribute type");
149 return MTLVertexFormatInvalid;
150}
151
152static MTLVertexDescriptor* create_vertex_descriptor(const GrPrimitiveProcessor& primProc) {
153 uint32_t vertexBinding = 0, instanceBinding = 0;
154
Timothy Liang057c3902018-08-08 10:48:45 -0400155 int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400156 if (primProc.hasVertexAttributes()) {
157 vertexBinding = nextBinding++;
158 }
159
160 if (primProc.hasInstanceAttributes()) {
161 instanceBinding = nextBinding;
162 }
163
164 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
165 int attributeIndex = 0;
166
167 int vertexAttributeCount = primProc.numVertexAttributes();
168 size_t vertexAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500169 for (const auto& attribute : primProc.vertexAttributes()) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400170 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
Brian Osmand4c29702018-09-14 16:16:55 -0400171 mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400172 mtlAttribute.offset = vertexAttributeOffset;
173 mtlAttribute.bufferIndex = vertexBinding;
174
Timothy Liang7ac582e2018-08-06 09:47:23 -0400175 vertexAttributeOffset += attribute.sizeAlign4();
176 attributeIndex++;
177 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500178 SkASSERT(vertexAttributeOffset == primProc.vertexStride());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400179
180 if (vertexAttributeCount) {
181 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
182 vertexDescriptor.layouts[vertexBinding];
183 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
184 vertexBufferLayout.stepRate = 1;
185 vertexBufferLayout.stride = vertexAttributeOffset;
186 }
187
188 int instanceAttributeCount = primProc.numInstanceAttributes();
189 size_t instanceAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500190 for (const auto& attribute : primProc.instanceAttributes()) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400191 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
Brian Osmand4c29702018-09-14 16:16:55 -0400192 mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400193 mtlAttribute.offset = instanceAttributeOffset;
194 mtlAttribute.bufferIndex = instanceBinding;
195
Timothy Liang7ac582e2018-08-06 09:47:23 -0400196 instanceAttributeOffset += attribute.sizeAlign4();
197 attributeIndex++;
198 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500199 SkASSERT(instanceAttributeOffset == primProc.instanceStride());
Timothy Liang7ac582e2018-08-06 09:47:23 -0400200
201 if (instanceAttributeCount) {
202 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
203 vertexDescriptor.layouts[instanceBinding];
204 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
205 instanceBufferLayout.stepRate = 1;
206 instanceBufferLayout.stride = instanceAttributeOffset;
207 }
208 return vertexDescriptor;
209}
210
211static MTLBlendFactor blend_coeff_to_mtl_blend(GrBlendCoeff coeff) {
212 static const MTLBlendFactor gTable[] = {
213 MTLBlendFactorZero, // kZero_GrBlendCoeff
214 MTLBlendFactorOne, // kOne_GrBlendCoeff
215 MTLBlendFactorSourceColor, // kSC_GrBlendCoeff
216 MTLBlendFactorOneMinusSourceColor, // kISC_GrBlendCoeff
217 MTLBlendFactorDestinationColor, // kDC_GrBlendCoeff
218 MTLBlendFactorOneMinusDestinationColor, // kIDC_GrBlendCoeff
219 MTLBlendFactorSourceAlpha, // kSA_GrBlendCoeff
220 MTLBlendFactorOneMinusSourceAlpha, // kISA_GrBlendCoeff
221 MTLBlendFactorDestinationAlpha, // kDA_GrBlendCoeff
222 MTLBlendFactorOneMinusDestinationAlpha, // kIDA_GrBlendCoeff
223 MTLBlendFactorBlendColor, // kConstC_GrBlendCoeff
224 MTLBlendFactorOneMinusBlendColor, // kIConstC_GrBlendCoeff
225 MTLBlendFactorBlendAlpha, // kConstA_GrBlendCoeff
226 MTLBlendFactorOneMinusBlendAlpha, // kIConstA_GrBlendCoeff
227 MTLBlendFactorSource1Color, // kS2C_GrBlendCoeff
228 MTLBlendFactorOneMinusSource1Color, // kIS2C_GrBlendCoeff
229 MTLBlendFactorSource1Alpha, // kS2A_GrBlendCoeff
230 MTLBlendFactorOneMinusSource1Alpha, // kIS2A_GrBlendCoeff
Mike Klein36743362018-11-06 08:23:30 -0500231 MTLBlendFactorZero, // kIllegal_GrBlendCoeff
Timothy Liang7ac582e2018-08-06 09:47:23 -0400232 };
233 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrBlendCoeffCnt);
234 GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff);
235 GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff);
236 GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff);
237 GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff);
238 GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff);
239 GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff);
240 GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff);
241 GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff);
242 GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff);
243 GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff);
244 GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff);
245 GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff);
246 GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff);
247 GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff);
248 GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff);
249 GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff);
250 GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff);
251 GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff);
252
Timothy Liang7ac582e2018-08-06 09:47:23 -0400253 SkASSERT((unsigned)coeff < kGrBlendCoeffCnt);
254 return gTable[coeff];
255}
256
257static MTLBlendOperation blend_equation_to_mtl_blend_op(GrBlendEquation equation) {
258 static const MTLBlendOperation gTable[] = {
259 MTLBlendOperationAdd, // kAdd_GrBlendEquation
260 MTLBlendOperationSubtract, // kSubtract_GrBlendEquation
261 MTLBlendOperationReverseSubtract, // kReverseSubtract_GrBlendEquation
262 };
263 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation);
264 GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation);
265 GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation);
266 GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation);
267
Mike Klein36743362018-11-06 08:23:30 -0500268 SkASSERT((unsigned)equation < kGrBlendEquationCnt);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400269 return gTable[equation];
270}
271
272static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500273 GrPixelConfig config, const GrPipeline& pipeline) {
Timothy Liang7ac582e2018-08-06 09:47:23 -0400274 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
275
276 // pixel format
277 MTLPixelFormat format;
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500278 SkAssertResult(GrPixelConfigToMTLFormat(config, &format));
Timothy Liang7ac582e2018-08-06 09:47:23 -0400279 mtlColorAttachment.pixelFormat = format;
280
281 // blending
282 GrXferProcessor::BlendInfo blendInfo;
283 pipeline.getXferProcessor().getBlendInfo(&blendInfo);
284
285 GrBlendEquation equation = blendInfo.fEquation;
286 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
287 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
288 bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
289 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
290
291 mtlColorAttachment.blendingEnabled = !blendOff;
292 if (!blendOff) {
293 mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
294 mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
295 mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
296 mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
297 mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
298 mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
299 }
300
301 if (!blendInfo.fWriteColor) {
302 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
303 } else {
304 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
305 }
306 return mtlColorAttachment;
307}
308
Jim Van Verth3d482992019-02-07 10:48:05 -0500309uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
310 // Metal expects the buffer to be padded at the end according to the alignment
311 // of the largest element in the buffer.
312 uint32_t offsetDiff = offset & maxAlignment;
313 if (offsetDiff != 0) {
314 offsetDiff = maxAlignment - offsetDiff + 1;
315 }
316 return offset + offsetDiff;
317}
318
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500319GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
320 const GrPrimitiveProcessor& primProc,
Timothy Liang7ac582e2018-08-06 09:47:23 -0400321 const GrPipeline& pipeline,
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500322 Desc* desc) {
Jim Van Verthf16e0742019-04-02 14:33:03 -0400323 auto pipelineDescriptor = [MTLRenderPipelineDescriptor new];
Timothy Liang7ac582e2018-08-06 09:47:23 -0400324
325 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
326 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
327 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
328 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
329
330 this->finalizeShaders();
331
332 SkSL::Program::Settings settings;
333 settings.fCaps = this->caps()->shaderCaps();
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500334 settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
Robert Phillips9da87e02019-02-04 13:26:26 -0500335 settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400336 SkASSERT(!this->fragColorIsInOut());
337
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500338 // TODO: Store shaders in cache
Timothy Liang7ac582e2018-08-06 09:47:23 -0400339 id<MTLLibrary> vertexLibrary = nil;
340 id<MTLLibrary> fragmentLibrary = nil;
341 vertexLibrary = this->createMtlShaderLibrary(fVS,
342 SkSL::Program::kVertex_Kind,
343 settings,
344 desc);
345 fragmentLibrary = this->createMtlShaderLibrary(fFS,
346 SkSL::Program::kFragment_Kind,
347 settings,
348 desc);
349 SkASSERT(!this->primitiveProcessor().willUseGeoShader());
350
351 SkASSERT(vertexLibrary);
352 SkASSERT(fragmentLibrary);
353
354 id<MTLFunction> vertexFunction = [vertexLibrary newFunctionWithName: @"vertexMain"];
355 id<MTLFunction> fragmentFunction = [fragmentLibrary newFunctionWithName: @"fragmentMain"];
356
Jim Van Verth9756c362019-05-17 11:05:22 -0400357 if (vertexFunction == nil) {
358 SkDebugf("Couldn't find vertexMain() in library\n");
359 return nullptr;
360 }
361 if (fragmentFunction == nil) {
362 SkDebugf("Couldn't find fragmentMain() in library\n");
363 return nullptr;
364 }
365
Timothy Liang7ac582e2018-08-06 09:47:23 -0400366 pipelineDescriptor.vertexFunction = vertexFunction;
367 pipelineDescriptor.fragmentFunction = fragmentFunction;
368 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc);
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500369 pipelineDescriptor.colorAttachments[0] = create_color_attachment(this->config(), pipeline);
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500370 bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500371 GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
372 pipelineDescriptor.stencilAttachmentPixelFormat =
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500373 hasStencilAttachment ? mtlCaps->preferredStencilFormat().fInternalFormat
374 : MTLPixelFormatInvalid;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400375
376 SkASSERT(pipelineDescriptor.vertexFunction);
377 SkASSERT(pipelineDescriptor.fragmentFunction);
378 SkASSERT(pipelineDescriptor.vertexDescriptor);
379 SkASSERT(pipelineDescriptor.colorAttachments[0]);
380
381 NSError* error = nil;
382 id<MTLRenderPipelineState> pipelineState =
383 [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
384 error: &error];
385 if (error) {
386 SkDebugf("Error creating pipeline: %s\n",
387 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
Timothy Liang6ed63962018-08-10 09:49:44 -0400388 return nullptr;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400389 }
Jim Van Verth3d482992019-02-07 10:48:05 -0500390 uint32_t geomBufferSize = buffer_size(fUniformHandler.fCurrentGeometryUBOOffset,
391 fUniformHandler.fCurrentGeometryUBOMaxAlignment);
392 uint32_t fragBufferSize = buffer_size(fUniformHandler.fCurrentFragmentUBOOffset,
393 fUniformHandler.fCurrentFragmentUBOMaxAlignment);
Timothy Liang057c3902018-08-08 10:48:45 -0400394 return new GrMtlPipelineState(fGpu,
395 pipelineState,
396 pipelineDescriptor.colorAttachments[0].pixelFormat,
Timothy Liang6ed63962018-08-10 09:49:44 -0400397 fUniformHandles,
398 fUniformHandler.fUniforms,
Jim Van Verthdd15d692019-04-22 15:29:53 -0400399 geomBufferSize,
400 fragBufferSize,
Timothy Liang6ed63962018-08-10 09:49:44 -0400401 (uint32_t)fUniformHandler.numSamplers(),
402 std::move(fGeometryProcessor),
403 std::move(fXferProcessor),
404 std::move(fFragmentProcessors),
405 fFragmentProcessorCnt);
Timothy Liang7ac582e2018-08-06 09:47:23 -0400406}
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500407
408//////////////////////////////////////////////////////////////////////////////
409
410bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
411 GrRenderTarget* renderTarget,
412 const GrPrimitiveProcessor& primProc,
413 const GrPipeline& pipeline,
414 GrPrimitiveType primitiveType,
415 GrMtlGpu* gpu) {
Chris Daltond7291ba2019-03-07 14:17:03 -0700416 if (!INHERITED::Build(desc, renderTarget, primProc,
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500417 GrPrimitiveType::kLines == primitiveType, pipeline, gpu)) {
418 return false;
419 }
420
421 GrProcessorKeyBuilder b(&desc->key());
422
423 int keyLength = desc->key().count();
424 SkASSERT(0 == (keyLength % 4));
425 desc->fShaderKeyLength = SkToU32(keyLength);
426
427 b.add32(renderTarget->config());
428 b.add32(renderTarget->numColorSamples());
Jim Van Verth2e4287f2019-03-05 12:16:11 -0500429 bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
430 b.add32(hasStencilAttachment ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat
431 : MTLPixelFormatInvalid);
432 b.add32((uint32_t)pipeline.isStencilEnabled());
Jim Van Verth1223e7f2019-02-28 17:38:35 -0500433 // Stencil samples don't seem to be tracked in the MTLRenderPipeline
434
435 b.add32(pipeline.getBlendInfoKey());
436
437 b.add32((uint32_t)primitiveType);
438
439 return true;
440}