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]);
 }