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