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/ganesh/GrDirectContext.h" 11#include "src/core/SkReadBuffer.h" 12#include "src/core/SkTraceEvent.h" 13#include "src/core/SkWriteBuffer.h" 14#include "src/gpu/SkSLToBackend.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/SkSLProgramKind.h" 20#include "src/sksl/SkSLProgramSettings.h" 21#include "src/utils/SkShaderUtils.h" 22 23#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 24#include "src/gpu/ganesh/mtl/GrMtlPipelineState.h" 25#include "src/gpu/ganesh/mtl/GrMtlUtil.h" 26#include "src/gpu/mtl/MtlUtilsPriv.h" 27 28#import <simd/simd.h> 29 30#if !__has_feature(objc_arc) 31#error This file must be compiled with Arc. Use -fobjc-arc flag 32#endif 33 34GR_NORETAIN_BEGIN 35 36GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState( 37 GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo, 38 const GrMtlPrecompiledLibraries* precompiledLibs) { 39 GrAutoLocaleSetter als("C"); 40 GrMtlPipelineStateBuilder builder(gpu, desc, programInfo); 41 42 if (!builder.emitAndInstallProcs()) { 43 return nullptr; 44 } 45 return builder.finalize(desc, programInfo, precompiledLibs); 46} 47 48GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu, 49 const GrProgramDesc& desc, 50 const GrProgramInfo& programInfo) 51 : INHERITED(desc, programInfo) 52 , fGpu(gpu) 53 , fUniformHandler(this) 54 , fVaryingHandler(this) { 55} 56 57const GrCaps* GrMtlPipelineStateBuilder::caps() const { 58 return fGpu->caps(); 59} 60 61void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) { 62 outputColor.addLayoutQualifier("location = 0, index = 1"); 63} 64 65static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' '); 66static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L'); 67 68void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[], 69 const SkSL::Program::Interface interfaces[], 70 SkSL::ProgramSettings* settings, 71 sk_sp<SkData> pipelineData, 72 bool isSkSL) { 73 sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(), 74 this->desc().keyLength()); 75 SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps()); 76 // cache metadata to allow for a complete precompile in either case 77 GrPersistentCacheUtils::ShaderMetadata meta; 78 meta.fSettings = settings; 79 meta.fPlatformData = std::move(pipelineData); 80 SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag; 81 sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(tag, shaders, interfaces, 82 kGrShaderTypeCount, &meta); 83 fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description); 84} 85 86id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary( 87 const std::string& shader, 88 SkSL::Program::Interface interface, 89 GrContextOptions::ShaderErrorHandler* errorHandler) { 90 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler); 91 if (shaderLibrary != nil && 92 interface.fRTFlipUniform != SkSL::Program::Interface::kRTFlip_None) { 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, tvOS 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, tvOS 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, tvOS 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, tvOS 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, tvOS 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; // Start after the uniforms. 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, tvOS 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, tvOS 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, tvOS 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, tvOS 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 = std::make_unique<SkBinaryWriteBuffer>(SkSerialProcs{}); 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.rasterSampleCount = programInfo.numSamples(); 518 519 const GrMtlCaps* mtlCaps = (const GrMtlCaps*)this->caps(); 520 pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc); 521 if (writer) { 522 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat); 523 } 524 SkASSERT(pipelineDescriptor.vertexDescriptor); 525 SkASSERT(pipelineDescriptor.colorAttachments[0]); 526 527 if (precompiledLibs) { 528 SkASSERT(precompiledLibs->fVertexLibrary); 529 SkASSERT(precompiledLibs->fFragmentLibrary); 530 pipelineDescriptor.vertexFunction = 531 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"]; 532 pipelineDescriptor.fragmentFunction = 533 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"]; 534 SkASSERT(pipelineDescriptor.vertexFunction); 535 SkASSERT(pipelineDescriptor.fragmentFunction); 536 if (precompiledLibs->fRTFlip) { 537 this->addRTFlipUniform(SKSL_RTFLIP_NAME); 538 } 539 } else { 540 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount]; 541 542 this->finalizeShaders(); 543 544 SkSL::ProgramSettings settings; 545 settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures; 546 SkASSERT(!this->fragColorIsInOut()); 547 548 SkReadBuffer reader; 549 SkFourByteTag shaderType = 0; 550 if (persistentCache && cached) { 551 reader.setMemory(cached->data(), cached->size()); 552 shaderType = GrPersistentCacheUtils::GetType(&reader); 553 } 554 555 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler(); 556 std::string msl[kGrShaderTypeCount]; 557 SkSL::Program::Interface interfaces[kGrShaderTypeCount]; 558 559 // Unpack any stored shaders from the persistent cache 560 if (cached) { 561 switch (shaderType) { 562 case kMSL_Tag: { 563 GrPersistentCacheUtils::UnpackCachedShaders( 564 &reader, msl, interfaces, kGrShaderTypeCount); 565 break; 566 } 567 568 case kSKSL_Tag: { 569 std::string cached_sksl[kGrShaderTypeCount]; 570 if (GrPersistentCacheUtils::UnpackCachedShaders( 571 &reader, cached_sksl, interfaces, kGrShaderTypeCount)) { 572 bool success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(), 573 cached_sksl[kVertex_GrShaderType], 574 SkSL::ProgramKind::kVertex, 575 settings, 576 &msl[kVertex_GrShaderType], 577 &interfaces[kVertex_GrShaderType], 578 errorHandler); 579 success = success && skgpu::SkSLToMSL(mtlCaps->shaderCaps(), 580 cached_sksl[kFragment_GrShaderType], 581 SkSL::ProgramKind::kFragment, 582 settings, 583 &msl[kFragment_GrShaderType], 584 &interfaces[kFragment_GrShaderType], 585 errorHandler); 586 if (!success) { 587 return nullptr; 588 } 589 } 590 break; 591 } 592 593 default: { 594 break; 595 } 596 } 597 } 598 599 // Create any MSL shaders from pipeline data if necessary and cache 600 if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) { 601 bool success = true; 602 if (msl[kVertex_GrShaderType].empty()) { 603 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(), 604 fVS.fCompilerString, 605 SkSL::ProgramKind::kVertex, 606 settings, 607 &msl[kVertex_GrShaderType], 608 &interfaces[kVertex_GrShaderType], 609 errorHandler); 610 } 611 if (success && msl[kFragment_GrShaderType].empty()) { 612 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(), 613 fFS.fCompilerString, 614 SkSL::ProgramKind::kFragment, 615 settings, 616 &msl[kFragment_GrShaderType], 617 &interfaces[kFragment_GrShaderType], 618 errorHandler); 619 } 620 if (!success) { 621 return nullptr; 622 } 623 624 if (persistentCache && !cached) { 625 sk_sp<SkData> pipelineData = writer->snapshotAsData(); 626 if (fGpu->getContext()->priv().options().fShaderCacheStrategy == 627 GrContextOptions::ShaderCacheStrategy::kSkSL) { 628 std::string sksl[kGrShaderTypeCount]; 629 sksl[kVertex_GrShaderType] = SkShaderUtils::PrettyPrint(fVS.fCompilerString); 630 sksl[kFragment_GrShaderType] = SkShaderUtils::PrettyPrint(fFS.fCompilerString); 631 this->storeShadersInCache(sksl, interfaces, &settings, 632 std::move(pipelineData), true); 633 } else { 634 /*** dump pipeline data here */ 635 this->storeShadersInCache(msl, interfaces, nullptr, 636 std::move(pipelineData), false); 637 } 638 } 639 } 640 641 // Compile MSL to libraries 642 shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary( 643 msl[kVertex_GrShaderType], 644 interfaces[kVertex_GrShaderType], 645 errorHandler); 646 shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary( 647 msl[kFragment_GrShaderType], 648 interfaces[kFragment_GrShaderType], 649 errorHandler); 650 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) { 651 return nullptr; 652 } 653 654 pipelineDescriptor.vertexFunction = 655 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"]; 656 pipelineDescriptor.fragmentFunction = 657 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"]; 658 } 659 660 if (pipelineDescriptor.vertexFunction == nil) { 661 SkDebugf("Couldn't find vertexMain() in library\n"); 662 return nullptr; 663 } 664 if (pipelineDescriptor.fragmentFunction == nil) { 665 SkDebugf("Couldn't find fragmentMain() in library\n"); 666 return nullptr; 667 } 668 SkASSERT(pipelineDescriptor.vertexFunction); 669 SkASSERT(pipelineDescriptor.fragmentFunction); 670 671 NSError* error = nil; 672 id<MTLRenderPipelineState> pipelineState; 673 { 674 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor"); 675 if (@available(macOS 10.15, *)) { 676 pipelineState = [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor 677 error: &error]; 678 } else { 679 pipelineState = GrMtlNewRenderPipelineStateWithDescriptor( 680 fGpu->device(), pipelineDescriptor, &error); 681 } 682 } 683 if (error) { 684 SkDebugf("Error creating pipeline: %s\n", 685 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]); 686 return nullptr; 687 } 688 if (!pipelineState) { 689 return nullptr; 690 } 691 692 sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState); 693 694 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset, 695 fUniformHandler.fCurrentUBOMaxAlignment); 696 return new GrMtlPipelineState(fGpu, 697 std::move(renderPipeline), 698 pipelineDescriptor.colorAttachments[0].pixelFormat, 699 fUniformHandles, 700 fUniformHandler.fUniforms, 701 bufferSize, 702 (uint32_t)fUniformHandler.numSamplers(), 703 std::move(fGPImpl), 704 std::move(fXPImpl), 705 std::move(fFPImpls)); 706} 707 708////////////////////////////////////////////////////////////////////////////// 709 710bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData, 711 GrMtlPrecompiledLibraries* precompiledLibs) { 712 SkASSERT(precompiledLibs); 713 714 SkReadBuffer reader(cachedData.data(), cachedData.size()); 715 SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader); 716 717 auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler(); 718 719 SkSL::ProgramSettings settings; 720 settings.fSharpenTextures = gpu->getContext()->priv().options().fSharpenMipmappedTextures; 721 GrPersistentCacheUtils::ShaderMetadata meta; 722 meta.fSettings = &settings; 723 724 std::string shaders[kGrShaderTypeCount]; 725 SkSL::Program::Interface interfaces[kGrShaderTypeCount]; 726 if (!GrPersistentCacheUtils::UnpackCachedShaders( 727 &reader, shaders, interfaces, kGrShaderTypeCount, &meta)) { 728 return false; 729 } 730 731 // skip the size 732 reader.readUInt(); 733 auto pipelineDescriptor = read_pipeline_data(&reader); 734 if (!reader.isValid()) { 735 return false; 736 } 737 738 switch (shaderType) { 739 case kMSL_Tag: { 740 precompiledLibs->fVertexLibrary = 741 GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler); 742 precompiledLibs->fFragmentLibrary = 743 GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler); 744 break; 745 } 746 747 case kSKSL_Tag: { 748 std::string msl[kGrShaderTypeCount]; 749 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(), 750 shaders[kVertex_GrShaderType], 751 SkSL::ProgramKind::kVertex, 752 settings, 753 &msl[kVertex_GrShaderType], 754 &interfaces[kVertex_GrShaderType], 755 errorHandler)) { 756 return false; 757 } 758 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(), 759 shaders[kFragment_GrShaderType], 760 SkSL::ProgramKind::kFragment, 761 settings, 762 &msl[kFragment_GrShaderType], 763 &interfaces[kFragment_GrShaderType], 764 errorHandler)) { 765 return false; 766 } 767 precompiledLibs->fVertexLibrary = 768 GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler); 769 precompiledLibs->fFragmentLibrary = 770 GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler); 771 break; 772 } 773 774 default: { 775 return false; 776 } 777 } 778 779 pipelineDescriptor.vertexFunction = 780 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"]; 781 pipelineDescriptor.fragmentFunction = 782 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"]; 783 784 { 785 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor"); 786 MTLNewRenderPipelineStateCompletionHandler completionHandler = 787 ^(id<MTLRenderPipelineState> state, NSError* error) { 788 if (error) { 789 SkDebugf("Error creating pipeline: %s\n", 790 [[error localizedDescription] 791 cStringUsingEncoding: NSASCIIStringEncoding]); 792 } 793 }; 794 795 // kick off asynchronous pipeline build and depend on Apple's cache to manage it 796 [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor 797 completionHandler: completionHandler]; 798 } 799 800 precompiledLibs->fRTFlip = (interfaces[kFragment_GrShaderType].fRTFlipUniform != 801 SkSL::Program::Interface::kRTFlip_None); 802 return true; 803} 804 805GR_NORETAIN_END 806