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