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