Fix stencil setup in Metal We could have a case where stencil is disabled but the framebuffer has a stencil buffer, and the framebuffer and pipeline must match. Bug: skia:8243 Change-Id: I460543392ffaf7198d693fd067fbdc96cda71fd3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/197764 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.h b/src/gpu/mtl/GrMtlPipelineStateBuilder.h index fe4ef02..470fa87 100644 --- a/src/gpu/mtl/GrMtlPipelineStateBuilder.h +++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.h
@@ -72,7 +72,8 @@ const GrTextureProxy* const primProcProxies[], GrProgramDesc*); - GrMtlPipelineState* finalize(const GrPrimitiveProcessor& primProc, + GrMtlPipelineState* finalize(GrRenderTarget* renderTarget, + const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, Desc*);
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm index 8f0003b..c7945b2 100644 --- a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm +++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
@@ -14,6 +14,8 @@ #include "GrMtlPipelineState.h" #include "GrMtlUtil.h" +#include "GrRenderTargetPriv.h" + #import <simd/simd.h> GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState( @@ -29,7 +31,7 @@ if (!builder.emitAndInstallProcs()) { return nullptr; } - return builder.finalize(primProc, pipeline, desc); + return builder.finalize(renderTarget, primProc, pipeline, desc); } GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu, @@ -315,7 +317,8 @@ return offset + offsetDiff; } -GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(const GrPrimitiveProcessor& primProc, +GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget, + const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, Desc* desc) { auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; @@ -356,10 +359,11 @@ pipelineDescriptor.fragmentFunction = fragmentFunction; pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc); pipelineDescriptor.colorAttachments[0] = create_color_attachment(this->config(), pipeline); + bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment()); GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps(); pipelineDescriptor.stencilAttachmentPixelFormat = - pipeline.isStencilEnabled() ? mtlCaps->preferredStencilFormat().fInternalFormat - : MTLPixelFormatInvalid; + hasStencilAttachment ? mtlCaps->preferredStencilFormat().fInternalFormat + : MTLPixelFormatInvalid; SkASSERT(pipelineDescriptor.vertexFunction); SkASSERT(pipelineDescriptor.fragmentFunction); @@ -420,8 +424,10 @@ b.add32(renderTarget->config()); b.add32(renderTarget->numColorSamples()); - b.add32(pipeline.isStencilEnabled() ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat - : MTLPixelFormatInvalid); + bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment()); + b.add32(hasStencilAttachment ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat + : MTLPixelFormatInvalid); + b.add32((uint32_t)pipeline.isStencilEnabled()); // Stencil samples don't seem to be tracked in the MTLRenderPipeline b.add32(pipeline.getBlendInfoKey());
diff --git a/src/gpu/mtl/GrMtlStencilAttachment.mm b/src/gpu/mtl/GrMtlStencilAttachment.mm index b6fb18c..a2d8fa3 100644 --- a/src/gpu/mtl/GrMtlStencilAttachment.mm +++ b/src/gpu/mtl/GrMtlStencilAttachment.mm
@@ -23,12 +23,13 @@ int height, int sampleCnt, const Format& format) { - MTLTextureDescriptor* desc = [MTLTextureDescriptor - texture2DDescriptorWithPixelFormat:MTLPixelFormatStencil8 - width:width - height:height - mipmapped:NO]; + MTLTextureDescriptor* desc = + [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format.fInternalFormat + width:width + height:height + mipmapped:NO]; desc.resourceOptions = MTLResourceStorageModePrivate; + desc.usage = MTLTextureUsageRenderTarget; return new GrMtlStencilAttachment(gpu, format, [gpu->device() newTextureWithDescriptor:desc]); }