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