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.fRTHeight) { 95 this->addRTHeightUniform(SKSL_RTHEIGHT_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 // set up vertex descriptor 404 { 405 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init]; 406 uint32_t vertexBinding = reader->readUInt(); 407 uint32_t instanceBinding = reader->readUInt(); 408 409 int attributeIndex = 0; 410 411 // vertex attributes 412 int vertexAttributeCount = reader->readInt(); 413 for (int i = 0; i < vertexAttributeCount; ++i) { 414 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex]; 415 mtlAttribute.format = (MTLVertexFormat) reader->readInt(); 416 mtlAttribute.offset = reader->readUInt(); 417 mtlAttribute.bufferIndex = reader->readUInt(); 418 ++attributeIndex; 419 } 420 if (vertexAttributeCount) { 421 MTLVertexBufferLayoutDescriptor* vertexBufferLayout = 422 vertexDescriptor.layouts[vertexBinding]; 423 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex; 424 vertexBufferLayout.stepRate = 1; 425 vertexBufferLayout.stride = reader->readUInt(); 426 } 427 428 // instance attributes 429 int instanceAttributeCount = reader->readInt(); 430 for (int i = 0; i < instanceAttributeCount; ++i) { 431 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex]; 432 mtlAttribute.format = (MTLVertexFormat) reader->readInt(); 433 mtlAttribute.offset = reader->readUInt(); 434 mtlAttribute.bufferIndex = reader->readUInt(); 435 ++attributeIndex; 436 } 437 if (instanceAttributeCount) { 438 MTLVertexBufferLayoutDescriptor* instanceBufferLayout = 439 vertexDescriptor.layouts[instanceBinding]; 440 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance; 441 instanceBufferLayout.stepRate = 1; 442 instanceBufferLayout.stride = reader->readUInt(); 443 } 444 pipelineDescriptor.vertexDescriptor = vertexDescriptor; 445 } 446 447 // set up color attachments 448 { 449 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init]; 450 451 mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt(); 452 mtlColorAttachment.blendingEnabled = reader->readBool(); 453 if (mtlColorAttachment.blendingEnabled) { 454 mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt(); 455 mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt(); 456 mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt(); 457 mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt(); 458 mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt(); 459 mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt(); 460 } 461 if (reader->readBool()) { 462 mtlColorAttachment.writeMask = MTLColorWriteMaskAll; 463 } else { 464 mtlColorAttachment.writeMask = MTLColorWriteMaskNone; 465 } 466 467 pipelineDescriptor.colorAttachments[0] = mtlColorAttachment; 468 } 469 470 pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt(); 471 472 return pipelineDescriptor; 473} 474 475GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize( 476 const GrProgramDesc& desc, const GrProgramInfo& programInfo, 477 const GrMtlPrecompiledLibraries* precompiledLibs) { 478 TRACE_EVENT0("skia.shaders", TRACE_FUNC); 479 480 // Geometry shaders are not supported 481 SkASSERT(!this->geometryProcessor().willUseGeoShader()); 482 483 if (precompiledLibs) { 484 SkASSERT(precompiledLibs->fPipelineState); 485 if (precompiledLibs->fRTHeight) { 486 this->addRTHeightUniform(SKSL_RTHEIGHT_NAME); 487 } 488 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset, 489 fUniformHandler.fCurrentUBOMaxAlignment); 490 return new GrMtlPipelineState(fGpu, 491 precompiledLibs->fPipelineState, 492 GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat()), 493 fUniformHandles, 494 fUniformHandler.fUniforms, 495 bufferSize, 496 (uint32_t)fUniformHandler.numSamplers(), 497 std::move(fGeometryProcessor), 498 std::move(fXferProcessor), 499 std::move(fFPImpls)); 500 } 501 502 // build from scratch 503 std::unique_ptr<SkBinaryWriteBuffer> writer; 504 505 sk_sp<SkData> cached; 506 auto persistentCache = fGpu->getContext()->priv().getPersistentCache(); 507 if (persistentCache) { 508 sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.keyLength()); 509 cached = persistentCache->load(*key); 510 } 511 if (persistentCache && !cached) { 512 writer.reset(new SkBinaryWriteBuffer()); 513 } 514 515 // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above. 516 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; 517 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(), 518 writer.get()); 519 520 MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat()); 521 if (pixelFormat == MTLPixelFormatInvalid) { 522 return nullptr; 523 } 524 525 pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat, 526 programInfo.pipeline(), 527 writer.get()); 528 pipelineDescriptor.sampleCount = programInfo.numSamples(); 529 GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps(); 530 pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc); 531 if (writer) { 532 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat); 533 } 534 SkASSERT(pipelineDescriptor.vertexDescriptor); 535 SkASSERT(pipelineDescriptor.colorAttachments[0]); 536 537 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount]; 538 539 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); 540 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); 541 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); 542 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); 543 544 this->finalizeShaders(); 545 546 SkSL::Program::Settings settings; 547 settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin; 548 settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures; 549 SkASSERT(!this->fragColorIsInOut()); 550 551 SkReadBuffer reader; 552 SkFourByteTag shaderType = 0; 553 if (persistentCache && cached) { 554 reader.setMemory(cached->data(), cached->size()); 555 shaderType = GrPersistentCacheUtils::GetType(&reader); 556 } 557 558 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler(); 559 SkSL::String msl[kGrShaderTypeCount]; 560 SkSL::Program::Inputs inputs[kGrShaderTypeCount]; 561 562 // Unpack any stored shaders from the persistent cache 563 if (cached) { 564 switch (shaderType) { 565 case kMSL_Tag: { 566 GrPersistentCacheUtils::UnpackCachedShaders(&reader, msl, inputs, 567 kGrShaderTypeCount); 568 break; 569 } 570 571 case kSKSL_Tag: { 572 SkSL::String cached_sksl[kGrShaderTypeCount]; 573 if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs, 574 kGrShaderTypeCount)) { 575 bool success = GrSkSLToMSL(fGpu, 576 cached_sksl[kVertex_GrShaderType], 577 SkSL::ProgramKind::kVertex, 578 settings, 579 &msl[kVertex_GrShaderType], 580 &inputs[kVertex_GrShaderType], 581 errorHandler); 582 success = success && GrSkSLToMSL(fGpu, 583 cached_sksl[kFragment_GrShaderType], 584 SkSL::ProgramKind::kFragment, 585 settings, 586 &msl[kFragment_GrShaderType], 587 &inputs[kFragment_GrShaderType], 588 errorHandler); 589 if (!success) { 590 return nullptr; 591 } 592 } 593 break; 594 } 595 596 default: { 597 break; 598 } 599 } 600 } 601 602 // Create any MSL shaders from pipeline data if necessary and cache 603 if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) { 604 bool success = true; 605 if (msl[kVertex_GrShaderType].empty()) { 606 success = GrSkSLToMSL(fGpu, 607 fVS.fCompilerString, 608 SkSL::ProgramKind::kVertex, 609 settings, 610 &msl[kVertex_GrShaderType], 611 &inputs[kVertex_GrShaderType], 612 errorHandler); 613 } 614 if (success && msl[kFragment_GrShaderType].empty()) { 615 success = GrSkSLToMSL(fGpu, 616 fFS.fCompilerString, 617 SkSL::ProgramKind::kFragment, 618 settings, 619 &msl[kFragment_GrShaderType], 620 &inputs[kFragment_GrShaderType], 621 errorHandler); 622 } 623 if (!success) { 624 return nullptr; 625 } 626 627 if (persistentCache && !cached) { 628 sk_sp<SkData> pipelineData = writer->snapshotAsData(); 629 if (fGpu->getContext()->priv().options().fShaderCacheStrategy == 630 GrContextOptions::ShaderCacheStrategy::kSkSL) { 631 SkSL::String sksl[kGrShaderTypeCount]; 632 sksl[kVertex_GrShaderType] = GrShaderUtils::PrettyPrint(fVS.fCompilerString); 633 sksl[kFragment_GrShaderType] = GrShaderUtils::PrettyPrint(fFS.fCompilerString); 634 this->storeShadersInCache(sksl, inputs, &settings, 635 std::move(pipelineData), true); 636 } else { 637 /*** dump pipeline data here */ 638 this->storeShadersInCache(msl, inputs, nullptr, 639 std::move(pipelineData), false); 640 } 641 } 642 } 643 644 // Compile MSL to libraries 645 shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary( 646 msl[kVertex_GrShaderType], 647 inputs[kVertex_GrShaderType], 648 errorHandler); 649 shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary( 650 msl[kFragment_GrShaderType], 651 inputs[kFragment_GrShaderType], 652 errorHandler); 653 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) { 654 return nullptr; 655 } 656 657 pipelineDescriptor.vertexFunction = 658 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"]; 659 pipelineDescriptor.fragmentFunction = 660 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"]; 661 662 if (pipelineDescriptor.vertexFunction == nil) { 663 SkDebugf("Couldn't find vertexMain() in library\n"); 664 return nullptr; 665 } 666 if (pipelineDescriptor.fragmentFunction == nil) { 667 SkDebugf("Couldn't find fragmentMain() in library\n"); 668 return nullptr; 669 } 670 SkASSERT(pipelineDescriptor.vertexFunction); 671 SkASSERT(pipelineDescriptor.fragmentFunction); 672 673 NSError* error = nil; 674#if GR_METAL_SDK_VERSION >= 230 675 if (@available(macOS 11.0, iOS 14.0, *)) { 676 id<MTLBinaryArchive> archive = fGpu->binaryArchive(); 677 if (archive) { 678 NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil]; 679 pipelineDescriptor.binaryArchives = archiveArray; 680 BOOL result; 681 { 682 TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor"); 683 result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor 684 error: &error]; 685 } 686 if (!result && error) { 687 SkDebugf("Error storing pipeline: %s\n", 688 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]); 689 } 690 } 691 } 692#endif 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 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset, 715 fUniformHandler.fCurrentUBOMaxAlignment); 716 return new GrMtlPipelineState(fGpu, 717 pipelineState, 718 pipelineDescriptor.colorAttachments[0].pixelFormat, 719 fUniformHandles, 720 fUniformHandler.fUniforms, 721 bufferSize, 722 (uint32_t)fUniformHandler.numSamplers(), 723 std::move(fGeometryProcessor), 724 std::move(fXferProcessor), 725 std::move(fFPImpls)); 726} 727 728////////////////////////////////////////////////////////////////////////////// 729 730bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData, 731 GrMtlPrecompiledLibraries* precompiledLibs) { 732 SkASSERT(precompiledLibs); 733 734 SkReadBuffer reader(cachedData.data(), cachedData.size()); 735 SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader); 736 737 auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler(); 738 739 SkSL::Program::Settings settings; 740 settings.fSharpenTextures = gpu->getContext()->priv().options().fSharpenMipmappedTextures; 741 GrPersistentCacheUtils::ShaderMetadata meta; 742 meta.fSettings = &settings; 743 744 SkSL::String shaders[kGrShaderTypeCount]; 745 SkSL::Program::Inputs inputs[kGrShaderTypeCount]; 746 if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount, 747 &meta)) { 748 return false; 749 } 750 751 // skip the size 752 reader.readUInt(); 753 auto pipelineDescriptor = read_pipeline_data(&reader); 754 if (!reader.isValid()) { 755 return false; 756 } 757 758 id<MTLLibrary> vertexLibrary; 759 id<MTLLibrary> fragmentLibrary; 760 switch (shaderType) { 761 case kMSL_Tag: { 762 vertexLibrary = 763 GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler); 764 fragmentLibrary = 765 GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler); 766 break; 767 } 768 769 case kSKSL_Tag: { 770 SkSL::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 vertexLibrary = 790 GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler); 791 fragmentLibrary = 792 GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler); 793 break; 794 } 795 796 default: { 797 return false; 798 } 799 } 800 801 pipelineDescriptor.vertexFunction = 802 [vertexLibrary newFunctionWithName: @"vertexMain"]; 803 pipelineDescriptor.fragmentFunction = 804 [fragmentLibrary newFunctionWithName: @"fragmentMain"]; 805 806 NSError* error = nil; 807#if GR_METAL_SDK_VERSION >= 230 808 if (@available(macOS 11.0, iOS 14.0, *)) { 809 id<MTLBinaryArchive> archive = gpu->binaryArchive(); 810 if (archive) { 811 NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil]; 812 pipelineDescriptor.binaryArchives = archiveArray; 813 BOOL result; 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#if defined(SK_BUILD_FOR_MAC) 829 precompiledLibs->fPipelineState = 830 GrMtlNewRenderPipelineStateWithDescriptor(gpu->device(), pipelineDescriptor, &error); 831#else 832 precompiledLibs->fPipelineState = 833 [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor 834 error: &error]; 835#endif 836 } 837 if (error) { 838 SkDebugf("Error creating pipeline: %s\n", 839 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]); 840 return false; 841 } 842 843 precompiledLibs->fRTHeight = inputs[kFragment_GrShaderType].fRTHeight; 844 return true; 845} 846 847GR_NORETAIN_END 848