30#if !__has_feature(objc_arc)
31#error This file must be compiled with Arc. Use -fobjc-arc flag
42 if (!builder.emitAndInstallProcs()) {
45 return builder.finalize(
desc, programInfo, precompiledLibs);
48GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(
GrMtlGpu* gpu,
53 , fUniformHandler(this)
54 , fVaryingHandler(this) {
68void GrMtlPipelineStateBuilder::storeShadersInCache(
const std::string shaders[],
74 this->
desc().keyLength());
86id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
87 const std::string& shader,
91 if (shaderLibrary != nil &&
101 return MTLVertexFormatFloat;
103 return MTLVertexFormatFloat2;
105 return MTLVertexFormatFloat3;
107 return MTLVertexFormatFloat4;
109 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
110 return MTLVertexFormatHalf;
112 return MTLVertexFormatInvalid;
115 return MTLVertexFormatHalf2;
117 return MTLVertexFormatHalf4;
119 return MTLVertexFormatInt2;
121 return MTLVertexFormatInt3;
123 return MTLVertexFormatInt4;
125 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
126 return MTLVertexFormatChar;
128 return MTLVertexFormatInvalid;
131 return MTLVertexFormatChar2;
133 return MTLVertexFormatChar4;
135 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
136 return MTLVertexFormatUChar;
138 return MTLVertexFormatInvalid;
141 return MTLVertexFormatUChar2;
143 return MTLVertexFormatUChar4;
145 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
146 return MTLVertexFormatUCharNormalized;
148 return MTLVertexFormatInvalid;
151 return MTLVertexFormatUChar4Normalized;
153 return MTLVertexFormatShort2;
155 return MTLVertexFormatShort4;
157 return MTLVertexFormatUShort2;
159 return MTLVertexFormatUShort2Normalized;
161 return MTLVertexFormatInt;
163 return MTLVertexFormatUInt;
165 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
166 return MTLVertexFormatUShortNormalized;
168 return MTLVertexFormatInvalid;
171 return MTLVertexFormatUShort4Normalized;
173 SK_ABORT(
"Unknown vertex attribute type");
178 uint32_t vertexBinding = 0, instanceBinding = 0;
182 vertexBinding = nextBinding++;
186 instanceBinding = nextBinding;
193 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
194 int attributeIndex = 0;
198 writer->
writeInt(vertexAttributeCount);
201 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
204 mtlAttribute.format =
format;
205 mtlAttribute.offset = *attribute.offset();
206 mtlAttribute.bufferIndex = vertexBinding;
216 if (vertexAttributeCount) {
217 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
218 vertexDescriptor.layouts[vertexBinding];
219 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
220 vertexBufferLayout.stepRate = 1;
229 writer->
writeInt(instanceAttributeCount);
232 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
235 mtlAttribute.format =
format;
236 mtlAttribute.offset = *attribute.offset();
237 mtlAttribute.bufferIndex = instanceBinding;
247 if (instanceAttributeCount) {
248 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
249 vertexDescriptor.layouts[instanceBinding];
250 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
251 instanceBufferLayout.stepRate = 1;
257 return vertexDescriptor;
263 return MTLBlendFactorZero;
265 return MTLBlendFactorOne;
267 return MTLBlendFactorSourceColor;
269 return MTLBlendFactorOneMinusSourceColor;
271 return MTLBlendFactorDestinationColor;
273 return MTLBlendFactorOneMinusDestinationColor;
275 return MTLBlendFactorSourceAlpha;
277 return MTLBlendFactorOneMinusSourceAlpha;
279 return MTLBlendFactorDestinationAlpha;
281 return MTLBlendFactorOneMinusDestinationAlpha;
283 return MTLBlendFactorBlendColor;
285 return MTLBlendFactorOneMinusBlendColor;
287 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
288 return MTLBlendFactorSource1Color;
290 return MTLBlendFactorZero;
293 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
294 return MTLBlendFactorOneMinusSource1Color;
296 return MTLBlendFactorZero;
299 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
300 return MTLBlendFactorSource1Alpha;
302 return MTLBlendFactorZero;
305 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
306 return MTLBlendFactorOneMinusSource1Alpha;
308 return MTLBlendFactorZero;
311 return MTLBlendFactorZero;
314 SK_ABORT(
"Unknown blend coefficient");
318 static const MTLBlendOperation gTable[] = {
319 MTLBlendOperationAdd,
320 MTLBlendOperationSubtract,
321 MTLBlendOperationReverseSubtract,
329 return gTable[(
int)equation];
334 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
337 mtlColorAttachment.pixelFormat =
format;
350 mtlColorAttachment.blendingEnabled = blendOn;
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);
372 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
374 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
379 return mtlColorAttachment;
385 uint32_t offsetDiff =
offset & maxAlignment;
386 if (offsetDiff != 0) {
387 offsetDiff = maxAlignment - offsetDiff + 1;
389 return offset + offsetDiff;
393 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
395#ifdef SK_ENABLE_MTL_DEBUG_INFO
400 pipelineDescriptor.label = @(description.
c_str());
406 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
407 uint32_t vertexBinding = reader->
readUInt();
408 uint32_t instanceBinding = reader->
readUInt();
410 int attributeIndex = 0;
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();
421 if (vertexAttributeCount) {
422 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
423 vertexDescriptor.layouts[vertexBinding];
424 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
425 vertexBufferLayout.stepRate = 1;
426 vertexBufferLayout.stride = reader->
readUInt();
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();
438 if (instanceAttributeCount) {
439 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
440 vertexDescriptor.layouts[instanceBinding];
441 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
442 instanceBufferLayout.stepRate = 1;
443 instanceBufferLayout.stride = reader->
readUInt();
445 pipelineDescriptor.vertexDescriptor = vertexDescriptor;
450 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
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();
463 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
465 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
468 pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
471 pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->
readInt();
473 return pipelineDescriptor;
482 std::unique_ptr<SkBinaryWriteBuffer> writer;
486 if (persistentCache && !precompiledLibs) {
488 cached = persistentCache->load(*
key);
490 if (persistentCache && !cached) {
491 writer = std::make_unique<SkBinaryWriteBuffer>(
SkSerialProcs{});
495 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc]
init];
496#ifdef SK_ENABLE_MTL_DEBUG_INFO
498 int split = description.
find(
"\n");
499 description.
resize(split);
500 pipelineDescriptor.label = @(description.
c_str());
502 writer->writeString(description.
c_str());
510 if (pixelFormat == MTLPixelFormatInvalid) {
517 pipelineDescriptor.rasterSampleCount = programInfo.
numSamples();
522 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
524 SkASSERT(pipelineDescriptor.vertexDescriptor);
525 SkASSERT(pipelineDescriptor.colorAttachments[0]);
527 if (precompiledLibs) {
530 pipelineDescriptor.vertexFunction =
531 [precompiledLibs->
fVertexLibrary newFunctionWithName:
@"vertexMain"];
532 pipelineDescriptor.fragmentFunction =
534 SkASSERT(pipelineDescriptor.vertexFunction);
535 SkASSERT(pipelineDescriptor.fragmentFunction);
536 if (precompiledLibs->
fRTFlip) {
550 if (persistentCache && cached) {
551 reader.
setMemory(cached->data(), cached->size());
561 switch (shaderType) {
624 if (persistentCache && !cached) {
631 this->storeShadersInCache(sksl, interfaces, &settings,
632 std::move(pipelineData),
true);
635 this->storeShadersInCache(msl, interfaces,
nullptr,
636 std::move(pipelineData),
false);
654 pipelineDescriptor.vertexFunction =
656 pipelineDescriptor.fragmentFunction =
660 if (pipelineDescriptor.vertexFunction == nil) {
661 SkDebugf(
"Couldn't find vertexMain() in library\n");
664 if (pipelineDescriptor.fragmentFunction == nil) {
665 SkDebugf(
"Couldn't find fragmentMain() in library\n");
668 SkASSERT(pipelineDescriptor.vertexFunction);
669 SkASSERT(pipelineDescriptor.fragmentFunction);
671 NSError*
error = nil;
672 id<MTLRenderPipelineState> pipelineState;
674 TRACE_EVENT0(
"skia.shaders",
"newRenderPipelineStateWithDescriptor");
675 if (@available(macOS 10.15, *)) {
676 pipelineState = [fGpu->
device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
684 SkDebugf(
"Error creating pipeline: %s\n",
685 [[
error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
688 if (!pipelineState) {
694 uint32_t bufferSize =
buffer_size(fUniformHandler.fCurrentUBOOffset,
695 fUniformHandler.fCurrentUBOMaxAlignment);
697 std::move(renderPipeline),
698 pipelineDescriptor.colorAttachments[0].pixelFormat,
700 fUniformHandler.fUniforms,
702 (uint32_t)fUniformHandler.numSamplers(),
720 settings.fSharpenTextures =
true;
738 switch (shaderType) {
779 pipelineDescriptor.vertexFunction =
780 [precompiledLibs->
fVertexLibrary newFunctionWithName:
@"vertexMain"];
781 pipelineDescriptor.fragmentFunction =
785 TRACE_EVENT0(
"skia.shaders",
"newRenderPipelineStateWithDescriptor");
786 MTLNewRenderPipelineStateCompletionHandler completionHandler =
787 ^(id<MTLRenderPipelineState>
state, NSError*
error) {
789 SkDebugf(
"Error creating pipeline: %s\n",
790 [[
error localizedDescription]
791 cStringUsingEncoding: NSASCIIStringEncoding]);
796 [gpu->
device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
797 completionHandler: completionHandler];
static constexpr SkFourByteTag kSKSL_Tag
static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation)
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static MTLRenderPipelineColorAttachmentDescriptor * create_color_attachment(MTLPixelFormat format, const GrPipeline &pipeline, SkBinaryWriteBuffer *writer)
static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff)
static MTLRenderPipelineDescriptor * read_pipeline_data(SkReadBuffer *reader)
static MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type)
static MTLVertexDescriptor * create_vertex_descriptor(const GrGeometryProcessor &geomProc, SkBinaryWriteBuffer *writer)
static constexpr SkFourByteTag kMSL_Tag
static constexpr SkFourByteTag kSKSL_Tag
id< MTLRenderPipelineState > GrMtlNewRenderPipelineStateWithDescriptor(id< MTLDevice >, MTLRenderPipelineDescriptor *, NSError **)
static MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat &format)
id< MTLLibrary > GrCompileMtlShaderLibrary(const GrMtlGpu *gpu, const std::string &msl, GrContextOptions::ShaderErrorHandler *errorHandler)
@ kUShort_norm_GrVertexAttribType
@ kFloat2_GrVertexAttribType
@ kUShort2_GrVertexAttribType
@ kUInt_GrVertexAttribType
@ kUByte4_norm_GrVertexAttribType
@ kUByte_GrVertexAttribType
@ kShort2_GrVertexAttribType
@ kUShort4_norm_GrVertexAttribType
@ kInt_GrVertexAttribType
@ kByte_GrVertexAttribType
@ kByte4_GrVertexAttribType
@ kFloat3_GrVertexAttribType
@ kFloat_GrVertexAttribType
@ kByte2_GrVertexAttribType
@ kFloat4_GrVertexAttribType
@ kShort4_GrVertexAttribType
@ kUShort2_norm_GrVertexAttribType
@ kInt3_GrVertexAttribType
@ kHalf2_GrVertexAttribType
@ kHalf4_GrVertexAttribType
@ kUByte4_GrVertexAttribType
@ kUByte2_GrVertexAttribType
@ kInt4_GrVertexAttribType
@ kUByte_norm_GrVertexAttribType
@ kInt2_GrVertexAttribType
@ kHalf_GrVertexAttribType
static const int kGrShaderTypeCount
#define SK_ABORT(message,...)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define INHERITED(method,...)
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Type::kYUV Type::kRGBA() int(0.7 *637)
const GrContextOptions & options() const
GrContextOptions::ShaderErrorHandler * getShaderErrorHandler() const
const GrShaderCaps * shaderCaps() const
virtual void store(const SkData &, const SkData &)
GrContextOptions::PersistentCache * getPersistentCache()
GrDirectContextPriv priv()
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
bool fragColorIsInOut() const
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
GrGLSLBuiltinUniformHandles fUniformHandles
const GrProgramInfo & fProgramInfo
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
std::string fCompilerString
int numVertexAttributes() const
int numInstanceAttributes() const
size_t vertexStride() const
bool hasInstanceAttributes() const
const AttributeSet & vertexAttributes() const
const AttributeSet & instanceAttributes() const
size_t instanceStride() const
bool hasVertexAttributes() const
const GrCaps * caps() const
GrDirectContext * getContext()
MTLPixelFormat getStencilPixelFormat(const GrProgramDesc &desc) const
id< MTLDevice > device() const
static GrMtlPipelineState * CreatePipelineState(GrMtlGpu *, const GrProgramDesc &, const GrProgramInfo &, const GrMtlPrecompiledLibraries *precompiledLibs=nullptr)
void finalizeFragmentSecondaryColor(GrShaderVar &outputColor) override
const GrCaps * caps() const override
static bool PrecompileShaders(GrMtlGpu *, const SkData &, GrMtlPrecompiledLibraries *precompiledLibs)
static sk_sp< GrMtlRenderPipeline > Make(id< MTLRenderPipelineState > pso)
const GrXferProcessor & getXferProcessor() const
uint32_t keyLength() const
const uint32_t * asKey() const
static SkString Describe(const GrProgramInfo &, const GrCaps &)
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
const GrBackendFormat & backendFormat() const
void addLayoutQualifier(const char *layoutQualifier)
skgpu::BlendInfo getBlendInfo() const
void writeBool(bool value) override
void writeUInt(uint32_t value) override
void writeInt(int32_t value) override
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
const void * data() const
void setMemory(const void *, size_t)
void readString(SkString *string)
int find(const char substring[]) const
const char * c_str() const
EMSCRIPTEN_KEEPALIVE void empty()
const uint8_t uint32_t uint32_t GError ** error
uint32_t uint32_t * format
sk_sp< SkData > PackCachedShaders(SkFourByteTag shaderType, const std::string shaders[], const SkSL::Program::Interface interfaces[], int numInterfaces, const ShaderMetadata *meta)
bool UnpackCachedShaders(SkReadBuffer *reader, std::string shaders[], SkSL::Program::Interface interfaces[], int numInterfaces, ShaderMetadata *meta)
SkFourByteTag GetType(SkReadBuffer *reader)
std::string PrettyPrint(const std::string &string)
bool SkSLToMSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *msl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
static const int kBlendEquationCnt
ShaderCacheStrategy fShaderCacheStrategy
id< MTLLibrary > fFragmentLibrary
id< MTLLibrary > fVertexLibrary
skgpu::BlendCoeff fDstBlend
skgpu::BlendCoeff fSrcBlend
#define TRACE_EVENT0(category_group, name)