Store the correct number of samples in GrProgramInfo

Bug: skia:11396
Change-Id: I9480b89635bd7a6bdff8ab4876c8eeafdbc27c8b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/442096
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/bench/VertexColorSpaceBench.cpp b/bench/VertexColorSpaceBench.cpp
index 3ca3fb5..4ec5bb4 100644
--- a/bench/VertexColorSpaceBench.cpp
+++ b/bench/VertexColorSpaceBench.cpp
@@ -184,6 +184,7 @@
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
                                                                    arena,
                                                                    writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView,
                                                                    gp,
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index b048b68..ee47b67 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -103,6 +103,7 @@
         GrPipeline::InputFlags flags = GrPipeline::InputFlags::kNone;
 
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView, gp,
                                                                    std::move(fProcessorSet),
diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp
index 5731051..1c8e5df 100644
--- a/gm/clockwise.cpp
+++ b/gm/clockwise.cpp
@@ -150,13 +150,14 @@
     GrProgramInfo* createProgramInfo(const GrCaps* caps,
                                      SkArenaAlloc* arena,
                                      const GrSurfaceProxyView& writeView,
+                                     bool usesMSAASurface,
                                      GrAppliedClip&& appliedClip,
                                      const GrDstProxyView& dstProxyView,
                                      GrXferBarrierFlags renderPassXferBarriers,
                                      GrLoadOp colorLoadOp) const {
         GrGeometryProcessor* geomProc = ClockwiseTestProcessor::Make(arena, fReadSkFragCoord);
 
-        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView,
+        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView, usesMSAASurface,
                                               std::move(appliedClip), dstProxyView,
                                               geomProc, SkBlendMode::kPlus,
                                               GrPrimitiveType::kTriangleStrip,
@@ -167,6 +168,7 @@
         return this->createProgramInfo(&flushState->caps(),
                                        flushState->allocator(),
                                        flushState->writeView(),
+                                       flushState->usesMSAASurface(),
                                        flushState->detachAppliedClip(),
                                        flushState->dstProxyView(),
                                        flushState->renderPassBarriers(),
@@ -181,12 +183,15 @@
                       GrLoadOp colorLoadOp) final {
         SkArenaAlloc* arena = context->priv().recordTimeAllocator();
 
+        // DMSAA is not supported on DDL.
+        bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+
         // This is equivalent to a GrOpFlushState::detachAppliedClip
         GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip::Disabled();
 
         fProgramInfo = this->createProgramInfo(context->priv().caps(), arena, writeView,
-                                               std::move(appliedClip), dstProxyView,
-                                               renderPassXferBarriers, colorLoadOp);
+                                               usesMSAASurface, std::move(appliedClip),
+                                               dstProxyView, renderPassXferBarriers, colorLoadOp);
 
         context->priv().recordProgramInfo(fProgramInfo);
     }
diff --git a/gm/fwidth_squircle.cpp b/gm/fwidth_squircle.cpp
index 831c31c..42d5e8b 100644
--- a/gm/fwidth_squircle.cpp
+++ b/gm/fwidth_squircle.cpp
@@ -171,13 +171,14 @@
     GrProgramInfo* createProgramInfo(const GrCaps* caps,
                                      SkArenaAlloc* arena,
                                      const GrSurfaceProxyView& writeView,
+                                     bool usesMSAASurface,
                                      GrAppliedClip&& appliedClip,
                                      const GrDstProxyView& dstProxyView,
                                      GrXferBarrierFlags renderPassXferBarriers,
                                      GrLoadOp colorLoadOp) const {
         GrGeometryProcessor* geomProc = FwidthSquircleTestProcessor::Make(arena, fViewMatrix);
 
-        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView,
+        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView, usesMSAASurface,
                                               std::move(appliedClip), dstProxyView,
                                               geomProc, SkBlendMode::kSrcOver,
                                               GrPrimitiveType::kTriangleStrip,
@@ -188,6 +189,7 @@
         return this->createProgramInfo(&flushState->caps(),
                                        flushState->allocator(),
                                        flushState->writeView(),
+                                       flushState->usesMSAASurface(),
                                        flushState->detachAppliedClip(),
                                        flushState->dstProxyView(),
                                        flushState->renderPassBarriers(),
@@ -202,12 +204,15 @@
                       GrLoadOp colorLoadOp) final {
         SkArenaAlloc* arena = context->priv().recordTimeAllocator();
 
+        // DMSAA is not supported on DDL.
+        bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+
         // This is equivalent to a GrOpFlushState::detachAppliedClip
         GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip::Disabled();
 
         fProgramInfo = this->createProgramInfo(context->priv().caps(), arena, writeView,
-                                               std::move(appliedClip), dstProxyView,
-                                               renderPassXferBarriers, colorLoadOp);
+                                               usesMSAASurface, std::move(appliedClip),
+                                               dstProxyView, renderPassXferBarriers, colorLoadOp);
 
         context->priv().recordProgramInfo(fProgramInfo);
     }
diff --git a/gm/tessellation.cpp b/gm/tessellation.cpp
index c86c076..f7a9c79 100644
--- a/gm/tessellation.cpp
+++ b/gm/tessellation.cpp
@@ -336,7 +336,8 @@
             shader = std::make_unique<TessellationTestRectShader>(fViewMatrix);
         }
 
-        GrProgramInfo programInfo(state->writeView(), &pipeline, &GrUserStencilSettings::kUnused,
+        GrProgramInfo programInfo(state->caps(), state->writeView(), state->usesMSAASurface(),
+                                  &pipeline, &GrUserStencilSettings::kUnused,
                                   shader.get(), GrPrimitiveType::kPatches,
                                   tessellationPatchVertexCount, state->renderPassBarriers(),
                                   state->colorLoadOp());
diff --git a/samplecode/SamplePathTessellators.cpp b/samplecode/SamplePathTessellators.cpp
index 1a98a4a..109e84c 100644
--- a/samplecode/SamplePathTessellators.cpp
+++ b/samplecode/SamplePathTessellators.cpp
@@ -109,6 +109,7 @@
         }
         fTessellator->prepare(flushState, this->bounds(), {pathMatrix, fPath}, fPath.countVerbs());
         fProgram = GrTessellationShader::MakeProgram({alloc, flushState->writeView(),
+                                                     flushState->usesMSAASurface(),
                                                      &flushState->dstProxyView(),
                                                      flushState->renderPassBarriers(),
                                                      GrLoadOp::kClear, &flushState->caps()},
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 67da4ab..4ce2094 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -51,7 +51,9 @@
             ++fCurrUpload;
         }
 
-        GrProgramInfo programInfo(this->writeView(),
+        GrProgramInfo programInfo(this->caps(),
+                                  this->writeView(),
+                                  this->usesMSAASurface(),
                                   pipeline,
                                   userStencilSettings,
                                   fCurrDraw->fGeometryProcessor,
diff --git a/src/gpu/GrProgramInfo.h b/src/gpu/GrProgramInfo.h
index 3d63f30..9f1f602 100644
--- a/src/gpu/GrProgramInfo.h
+++ b/src/gpu/GrProgramInfo.h
@@ -16,7 +16,9 @@
 
 class GrProgramInfo {
 public:
-    GrProgramInfo(const GrSurfaceProxyView& targetView,
+    GrProgramInfo(const GrCaps& caps,
+                  const GrSurfaceProxyView& targetView,
+                  bool usesMSAASurface,
                   const GrPipeline* pipeline,
                   const GrUserStencilSettings* userStencilSettings,
                   const GrGeometryProcessor* geomProc,
@@ -24,8 +26,7 @@
                   uint8_t tessellationPatchVertexCount,
                   GrXferBarrierFlags renderPassXferBarriers,
                   GrLoadOp colorLoadOp)
-            : fNumSamples(targetView.asRenderTargetProxy()->numSamples())
-            , fNeedsStencil(targetView.asRenderTargetProxy()->needsStencil())
+            : fNeedsStencil(targetView.asRenderTargetProxy()->needsStencil())
             , fBackendFormat(targetView.proxy()->backendFormat())
             , fOrigin(targetView.origin())
             , fTargetHasVkResolveAttachmentWithInput(
@@ -41,7 +42,11 @@
             , fTessellationPatchVertexCount(tessellationPatchVertexCount)
             , fRenderPassXferBarriers(renderPassXferBarriers)
             , fColorLoadOp(colorLoadOp) {
-        SkASSERT(this->numSamples() > 0);
+        SkASSERT(fTargetsNumSamples > 0);
+        fNumSamples = fTargetsNumSamples;
+        if (fNumSamples == 1 && usesMSAASurface) {
+            fNumSamples = caps.internalMultisampleCount(this->backendFormat());
+        }
         SkASSERT((GrPrimitiveType::kPatches == fPrimitiveType) ==
                  (fTessellationPatchVertexCount > 0));
         SkDEBUGCODE(this->validate(false);)
@@ -96,9 +101,9 @@
 
 private:
     int                                   fNumSamples;
-    const bool                            fNeedsStencil;
-    const GrBackendFormat                 fBackendFormat;
-    const GrSurfaceOrigin                 fOrigin;
+    bool                                  fNeedsStencil;
+    GrBackendFormat                       fBackendFormat;
+    GrSurfaceOrigin                       fOrigin;
     bool                                  fTargetHasVkResolveAttachmentWithInput;
     int                                   fTargetsNumSamples;
     const GrPipeline*                     fPipeline;
diff --git a/src/gpu/ops/AAConvexPathRenderer.cpp b/src/gpu/ops/AAConvexPathRenderer.cpp
index fde56ce..c8d702c 100644
--- a/src/gpu/ops/AAConvexPathRenderer.cpp
+++ b/src/gpu/ops/AAConvexPathRenderer.cpp
@@ -742,7 +742,7 @@
                                                                   fHelper.usesLocalCoords(),
                                                                   fWideColor);
 
-        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
+        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
                                                             std::move(appliedClip),
                                                             dstProxyView, quadProcessor,
                                                             GrPrimitiveType::kTriangles,
diff --git a/src/gpu/ops/AAHairLinePathRenderer.cpp b/src/gpu/ops/AAHairLinePathRenderer.cpp
index a008e87..59794d8 100644
--- a/src/gpu/ops/AAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/AAHairLinePathRenderer.cpp
@@ -828,18 +828,21 @@
 private:
     void makeLineProgramInfo(const GrCaps&, SkArenaAlloc*, const GrPipeline*,
                              const GrSurfaceProxyView& writeView,
+                             bool usesMSAASurface,
                              const SkMatrix* geometryProcessorViewM,
                              const SkMatrix* geometryProcessorLocalM,
                              GrXferBarrierFlags renderPassXferBarriers,
                              GrLoadOp colorLoadOp);
     void makeQuadProgramInfo(const GrCaps&, SkArenaAlloc*, const GrPipeline*,
                              const GrSurfaceProxyView& writeView,
+                             bool usesMSAASurface,
                              const SkMatrix* geometryProcessorViewM,
                              const SkMatrix* geometryProcessorLocalM,
                              GrXferBarrierFlags renderPassXferBarriers,
                              GrLoadOp colorLoadOp);
     void makeConicProgramInfo(const GrCaps&, SkArenaAlloc*, const GrPipeline*,
                               const GrSurfaceProxyView& writeView,
+                              bool usesMSAASurface,
                               const SkMatrix* geometryProcessorViewM,
                               const SkMatrix* geometryProcessorLocalM,
                               GrXferBarrierFlags renderPassXferBarriers,
@@ -946,6 +949,7 @@
 void AAHairlineOp::makeLineProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
                                        const GrPipeline* pipeline,
                                        const GrSurfaceProxyView& writeView,
+                                       bool usesMSAASurface,
                                        const SkMatrix* geometryProcessorViewM,
                                        const SkMatrix* geometryProcessorLocalM,
                                        GrXferBarrierFlags renderPassXferBarriers,
@@ -972,13 +976,14 @@
     }
 
     fProgramInfos[0] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
-            arena, pipeline, writeView, lineGP, GrPrimitiveType::kTriangles,
+            &caps, arena, pipeline, writeView, usesMSAASurface, lineGP, GrPrimitiveType::kTriangles,
             renderPassXferBarriers, colorLoadOp, fHelper.stencilSettings());
 }
 
 void AAHairlineOp::makeQuadProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
                                        const GrPipeline* pipeline,
                                        const GrSurfaceProxyView& writeView,
+                                       bool usesMSAASurface,
                                        const SkMatrix* geometryProcessorViewM,
                                        const SkMatrix* geometryProcessorLocalM,
                                        GrXferBarrierFlags renderPassXferBarriers,
@@ -997,13 +1002,14 @@
     SkASSERT(sizeof(BezierVertex) == quadGP->vertexStride());
 
     fProgramInfos[1] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
-            arena, pipeline, writeView, quadGP, GrPrimitiveType::kTriangles,
+            &caps, arena, pipeline, writeView, usesMSAASurface, quadGP, GrPrimitiveType::kTriangles,
             renderPassXferBarriers, colorLoadOp, fHelper.stencilSettings());
 }
 
 void AAHairlineOp::makeConicProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
                                         const GrPipeline* pipeline,
                                         const GrSurfaceProxyView& writeView,
+                                        bool usesMSAASurface,
                                         const SkMatrix* geometryProcessorViewM,
                                         const SkMatrix* geometryProcessorLocalM,
                                         GrXferBarrierFlags renderPassXferBarriers,
@@ -1022,8 +1028,9 @@
     SkASSERT(sizeof(BezierVertex) == conicGP->vertexStride());
 
     fProgramInfos[2] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
-            arena, pipeline, writeView, conicGP, GrPrimitiveType::kTriangles,
-            renderPassXferBarriers, colorLoadOp, fHelper.stencilSettings());
+            &caps, arena, pipeline, writeView, usesMSAASurface, conicGP,
+            GrPrimitiveType::kTriangles, renderPassXferBarriers, colorLoadOp,
+            fHelper.stencilSettings());
 }
 
 AAHairlineOp::Program AAHairlineOp::predictPrograms(const GrCaps* caps) const {
@@ -1079,17 +1086,17 @@
                                            std::move(appliedClip), dstProxyView);
 
     if (fCharacterization & Program::kLine) {
-        this->makeLineProgramInfo(*caps, arena, pipeline, writeView,
+        this->makeLineProgramInfo(*caps, arena, pipeline, writeView, usesMSAASurface,
                                   geometryProcessorViewM, geometryProcessorLocalM,
                                   renderPassXferBarriers, colorLoadOp);
     }
     if (fCharacterization & Program::kQuad) {
-        this->makeQuadProgramInfo(*caps, arena, pipeline, writeView,
+        this->makeQuadProgramInfo(*caps, arena, pipeline, writeView, usesMSAASurface,
                                   geometryProcessorViewM, geometryProcessorLocalM,
                                   renderPassXferBarriers, colorLoadOp);
     }
     if (fCharacterization & Program::kConic) {
-        this->makeConicProgramInfo(*caps, arena, pipeline, writeView,
+        this->makeConicProgramInfo(*caps, arena, pipeline, writeView, usesMSAASurface,
                                    geometryProcessorViewM, geometryProcessorLocalM,
                                    renderPassXferBarriers, colorLoadOp);
 
diff --git a/src/gpu/ops/AALinearizingConvexPathRenderer.cpp b/src/gpu/ops/AALinearizingConvexPathRenderer.cpp
index 584d7e6..a78afff 100644
--- a/src/gpu/ops/AALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/AALinearizingConvexPathRenderer.cpp
@@ -165,7 +165,7 @@
             return;
         }
 
-        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
+        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
                                                             std::move(appliedClip), dstProxyView,
                                                             gp, GrPrimitiveType::kTriangles,
                                                             renderPassXferBarriers, colorLoadOp);
diff --git a/src/gpu/ops/DefaultPathRenderer.cpp b/src/gpu/ops/DefaultPathRenderer.cpp
index dcb9112..77c0b7d 100644
--- a/src/gpu/ops/DefaultPathRenderer.cpp
+++ b/src/gpu/ops/DefaultPathRenderer.cpp
@@ -486,8 +486,9 @@
         SkASSERT(gp->vertexStride() == sizeof(SkPoint));
 
         fProgramInfo =  fHelper.createProgramInfoWithStencil(caps, arena, writeView,
-                                                             std::move(appliedClip),
-                                                             dstProxyView, gp, this->primType(),
+                                                             usesMSAASurface,
+                                                             std::move(appliedClip), dstProxyView,
+                                                             gp, this->primType(),
                                                              renderPassXferBarriers, colorLoadOp);
 
     }
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index d76768d..35ffdb7 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -349,6 +349,7 @@
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
                                                                    arena,
                                                                    writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView,
                                                                    gp,
diff --git a/src/gpu/ops/GrDrawAtlasOp.cpp b/src/gpu/ops/GrDrawAtlasOp.cpp
index 4d2d909..1533899 100644
--- a/src/gpu/ops/GrDrawAtlasOp.cpp
+++ b/src/gpu/ops/GrDrawAtlasOp.cpp
@@ -214,9 +214,10 @@
                                       this->color(),
                                       this->viewMatrix());
 
-    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                             dstProxyView, gp, GrPrimitiveType::kTriangles,
-                                             renderPassXferBarriers, colorLoadOp);
+    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                             std::move(appliedClip), dstProxyView, gp,
+                                             GrPrimitiveType::kTriangles, renderPassXferBarriers,
+                                             colorLoadOp);
 }
 
 void DrawAtlasOp::onPrepareDraws(GrMeshDrawTarget* target) {
diff --git a/src/gpu/ops/GrDrawAtlasPathOp.cpp b/src/gpu/ops/GrDrawAtlasPathOp.cpp
index 0bd069d..7c63571 100644
--- a/src/gpu/ops/GrDrawAtlasPathOp.cpp
+++ b/src/gpu/ops/GrDrawAtlasPathOp.cpp
@@ -158,8 +158,9 @@
                                             std::move(appliedClip));
     auto shader = arena->make<DrawAtlasPathShader>(fUsesLocalCoords, &fAtlasHelper,
                                                    *caps.shaderCaps());
-    fProgram = arena->make<GrProgramInfo>(writeView, pipeline, &GrUserStencilSettings::kUnused,
-                                          shader, GrPrimitiveType::kTriangleStrip, 0,
+    fProgram = arena->make<GrProgramInfo>(caps, writeView, usesMSAASurface, pipeline,
+                                          &GrUserStencilSettings::kUnused, shader,
+                                          GrPrimitiveType::kTriangleStrip, 0,
                                           renderPassXferBarriers, colorLoadOp);
 }
 
@@ -168,10 +169,11 @@
                                      GrAppliedClip* appliedClip, const GrDstProxyView& dstProxyView,
                                      GrXferBarrierFlags renderPassXferBarriers,
                                      GrLoadOp colorLoadOp) {
+    // DMSAA is not supported on DDL.
+    bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
     this->prepareProgram(*rContext->priv().caps(), rContext->priv().recordTimeAllocator(),
-                         writeView, writeView.asRenderTargetProxy()->numSamples() > 1,
-                         std::move(*appliedClip), dstProxyView, renderPassXferBarriers,
-                         colorLoadOp);
+                         writeView, usesMSAASurface, std::move(*appliedClip), dstProxyView,
+                         renderPassXferBarriers, colorLoadOp);
     SkASSERT(fProgram);
     rContext->priv().recordProgramInfo(fProgram);
 }
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index 64fc03a..26d32b4 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -389,9 +389,10 @@
                                          GrXferBarrierFlags renderPassXferBarriers,
                                          GrLoadOp colorLoadOp) {
     GrGeometryProcessor* gp = this->makeGP(arena);
-    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                             dstProxyView, gp, this->primitiveType(),
-                                             renderPassXferBarriers, colorLoadOp);
+    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                             std::move(appliedClip), dstProxyView, gp,
+                                             this->primitiveType(), renderPassXferBarriers,
+                                             colorLoadOp);
 }
 
 void DrawVerticesOp::onPrepareDraws(GrMeshDrawTarget* target) {
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index d533a5d..eb89aaa 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -773,9 +773,10 @@
         fProcessorFlags |= ProcessorFlags::kMSAAEnabled;
     }
     GrGeometryProcessor* gp = Processor::Make(arena, fHelper.aaType(), fProcessorFlags);
-    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                             dstProxyView, gp, GrPrimitiveType::kTriangles,
-                                             renderPassXferBarriers, colorLoadOp);
+    fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                             std::move(appliedClip), dstProxyView, gp,
+                                             GrPrimitiveType::kTriangles, renderPassXferBarriers,
+                                             colorLoadOp);
 }
 
 void FillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index 8d9ecc5..6cd91e6 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -213,7 +213,7 @@
         GrGeometryProcessor* gp = GrQuadPerEdgeAA::MakeProcessor(arena, vertexSpec);
         SkASSERT(gp->vertexStride() == vertexSpec.vertexSize());
 
-        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
+        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
                                                             std::move(appliedClip),
                                                             dstProxyView, gp,
                                                             vertexSpec.primitiveType(),
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 5e5e956..9718e56 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -215,6 +215,7 @@
         }
 
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView, gp,
                                                                    fHelper.detachProcessorSet(),
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index ea0f419..5bff43b 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -1258,6 +1258,7 @@
         fProgramInfo = fHelper.createProgramInfo(caps,
                                                  arena,
                                                  writeView,
+                                                 usesMSAASurface,
                                                  std::move(appliedClip),
                                                  dstProxyView,
                                                  gp,
@@ -1629,6 +1630,7 @@
         fProgramInfo = fHelper.createProgramInfo(caps,
                                                  arena,
                                                  writeView,
+                                                 usesMSAASurface,
                                                  std::move(appliedClip),
                                                  dstProxyView,
                                                  gp,
@@ -1964,6 +1966,7 @@
         fProgramInfo = fHelper.createProgramInfo(caps,
                                                  arena,
                                                  writeView,
+                                                 usesMSAASurface,
                                                  std::move(appliedClip),
                                                  dstProxyView,
                                                  gp,
@@ -2245,8 +2248,9 @@
                                                                    this->viewMatrix(),
                                                                    this->style());
 
-        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                                 dstProxyView, gp, GrPrimitiveType::kTriangles,
+        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                                 std::move(appliedClip), dstProxyView, gp,
+                                                 GrPrimitiveType::kTriangles,
                                                  renderPassXferBarriers, colorLoadOp);
     }
 
@@ -2659,8 +2663,9 @@
                                                                 false, false, false, false,
                                                                 fWideColor, localMatrix);
 
-        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                                 dstProxyView, gp, GrPrimitiveType::kTriangles,
+        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                                 std::move(appliedClip), dstProxyView, gp,
+                                                 GrPrimitiveType::kTriangles,
                                                  renderPassXferBarriers, colorLoadOp);
     }
 
@@ -2979,8 +2984,9 @@
         GrGeometryProcessor* gp = EllipseGeometryProcessor::Make(arena, fStroked, fWideColor,
                                                                  fUseScale, localMatrix);
 
-        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(appliedClip),
-                                                 dstProxyView, gp, GrPrimitiveType::kTriangles,
+        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                                 std::move(appliedClip), dstProxyView, gp,
+                                                 GrPrimitiveType::kTriangles,
                                                  renderPassXferBarriers, colorLoadOp);
     }
 
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index 9ccacf9..ee63835 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -97,7 +97,7 @@
             return;
         }
 
-        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
+        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
                                                             std::move(appliedClip), dstProxyView,
                                                             gp, GrPrimitiveType::kTriangles,
                                                             renderPassXferBarriers, colorLoadOp);
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index cd3b9ac..afe3315 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -537,6 +537,7 @@
         SkASSERT(sizeof(CircleVertex) == gp->vertexStride());
 
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView, gp,
                                                                    GrProcessorSet::MakeEmptySet(),
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
index a6fb1b2..538f305 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
@@ -166,6 +166,7 @@
             const GrCaps* caps,
             SkArenaAlloc* arena,
             const GrSurfaceProxyView& writeView,
+            bool usesMSAASurface,
             GrAppliedClip&& appliedClip,
             const GrDstProxyView& dstProxyView,
             GrGeometryProcessor* geometryProcessor,
@@ -183,19 +184,23 @@
                                    std::move(processorSet),
                                    pipelineFlags);
 
-    return CreateProgramInfo(arena, pipeline, writeView, geometryProcessor, primitiveType,
-                             renderPassXferBarriers, colorLoadOp, stencilSettings);
+    return CreateProgramInfo(caps, arena, pipeline, writeView, usesMSAASurface, geometryProcessor,
+                             primitiveType, renderPassXferBarriers, colorLoadOp, stencilSettings);
 }
 
-GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(SkArenaAlloc* arena,
+GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(const GrCaps* caps,
+                                                           SkArenaAlloc* arena,
                                                            const GrPipeline* pipeline,
                                                            const GrSurfaceProxyView& writeView,
+                                                           bool usesMSAASurface,
                                                            GrGeometryProcessor* geometryProcessor,
                                                            GrPrimitiveType primitiveType,
                                                            GrXferBarrierFlags xferBarrierFlags,
                                                            GrLoadOp colorLoadOp,
                                                            const GrUserStencilSettings* stencilSettings) {
-    auto tmp = arena->make<GrProgramInfo>(writeView,
+    auto tmp = arena->make<GrProgramInfo>(*caps,
+                                          writeView,
+                                          usesMSAASurface,
                                           pipeline,
                                           stencilSettings,
                                           geometryProcessor,
@@ -210,6 +215,7 @@
                                             const GrCaps* caps,
                                             SkArenaAlloc* arena,
                                             const GrSurfaceProxyView& writeView,
+                                            bool usesMSAASurface,
                                             GrAppliedClip&& appliedClip,
                                             const GrDstProxyView& dstProxyView,
                                             GrGeometryProcessor* gp,
@@ -219,6 +225,7 @@
     return CreateProgramInfo(caps,
                              arena,
                              writeView,
+                             usesMSAASurface,
                              std::move(appliedClip),
                              dstProxyView,
                              gp,
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
index 9ea1180..c5545da 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
@@ -131,9 +131,11 @@
                                      GrAppliedClip&&,
                                      const GrDstProxyView&);
 
-    static GrProgramInfo* CreateProgramInfo(SkArenaAlloc*,
+    static GrProgramInfo* CreateProgramInfo(const GrCaps*,
+                                            SkArenaAlloc*,
                                             const GrPipeline*,
                                             const GrSurfaceProxyView& writeView,
+                                            bool usesMSAASurface,
                                             GrGeometryProcessor*,
                                             GrPrimitiveType,
                                             GrXferBarrierFlags renderPassXferBarriers,
@@ -147,6 +149,7 @@
     static GrProgramInfo* CreateProgramInfo(const GrCaps*,
                                             SkArenaAlloc*,
                                             const GrSurfaceProxyView& writeView,
+                                            bool usesMSAASurface,
                                             GrAppliedClip&&,
                                             const GrDstProxyView&,
                                             GrGeometryProcessor*,
@@ -162,6 +165,7 @@
     GrProgramInfo* createProgramInfo(const GrCaps*,
                                      SkArenaAlloc*,
                                      const GrSurfaceProxyView& writeView,
+                                     bool usesMSAASurface,
                                      GrAppliedClip&&,
                                      const GrDstProxyView&,
                                      GrGeometryProcessor*,
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
index e25da42..a7a8a4d 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
@@ -45,7 +45,8 @@
 GrProgramInfo* GrSimpleMeshDrawOpHelperWithStencil::createProgramInfoWithStencil(
                                             const GrCaps* caps,
                                             SkArenaAlloc* arena,
-                                            const GrSurfaceProxyView& writeViewSwizzle,
+                                            const GrSurfaceProxyView& writeView,
+                                            bool usesMSAASurface,
                                             GrAppliedClip&& appliedClip,
                                             const GrDstProxyView& dstProxyView,
                                             GrGeometryProcessor* gp,
@@ -54,7 +55,8 @@
                                             GrLoadOp colorLoadOp) {
     return CreateProgramInfo(caps,
                              arena,
-                             writeViewSwizzle,
+                             writeView,
+                             usesMSAASurface,
                              std::move(appliedClip),
                              dstProxyView,
                              gp,
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
index 460877f..c174ae8 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
@@ -24,7 +24,8 @@
 
     GrProgramInfo* createProgramInfoWithStencil(const GrCaps*,
                                                 SkArenaAlloc*,
-                                                const GrSurfaceProxyView& writeViewSwizzle,
+                                                const GrSurfaceProxyView& writeView,
+                                                bool usesMSAASurface,
                                                 GrAppliedClip&&,
                                                 const GrDstProxyView&,
                                                 GrGeometryProcessor*,
diff --git a/src/gpu/ops/GrStrokeRectOp.cpp b/src/gpu/ops/GrStrokeRectOp.cpp
index a4a2abd..1b129d0 100644
--- a/src/gpu/ops/GrStrokeRectOp.cpp
+++ b/src/gpu/ops/GrStrokeRectOp.cpp
@@ -191,8 +191,8 @@
         GrPrimitiveType primType = (fStrokeWidth > 0) ? GrPrimitiveType::kTriangleStrip
                                                       : GrPrimitiveType::kLineStrip;
 
-        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, std::move(clip),
-                                                 dstProxyView, gp, primType,
+        fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
+                                                 std::move(clip), dstProxyView, gp, primType,
                                                  renderPassXferBarriers, colorLoadOp);
     }
 
@@ -603,6 +603,7 @@
     fProgramInfo = fHelper.createProgramInfo(caps,
                                              arena,
                                              writeView,
+                                             usesMSAASurface,
                                              std::move(appliedClip),
                                              dstProxyView,
                                              gp,
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index bca463b..78e5969 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -689,7 +689,7 @@
         }
 
         fDesc->fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
-                caps, arena, writeView, std::move(appliedClip), dstProxyView, gp,
+                caps, arena, writeView, usesMSAASurface, std::move(appliedClip), dstProxyView, gp,
                 GrProcessorSet::MakeEmptySet(), fDesc->fVertexSpec.primitiveType(),
                 renderPassXferBarriers, colorLoadOp, GrPipeline::InputFlags::kNone);
     }
diff --git a/src/gpu/ops/PathInnerTriangulateOp.cpp b/src/gpu/ops/PathInnerTriangulateOp.cpp
index 18a4f6c..9e8d1b8 100644
--- a/src/gpu/ops/PathInnerTriangulateOp.cpp
+++ b/src/gpu/ops/PathInnerTriangulateOp.cpp
@@ -367,8 +367,11 @@
                                           const GrDstProxyView& dstProxyView,
                                           GrXferBarrierFlags renderPassXferBarriers,
                                           GrLoadOp colorLoadOp) {
-    this->prePreparePrograms({context->priv().recordTimeAllocator(), writeView, &dstProxyView,
-                             renderPassXferBarriers, colorLoadOp, context->priv().caps()},
+    // DMSAA is not supported on DDL.
+    bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+    this->prePreparePrograms({context->priv().recordTimeAllocator(), writeView, usesMSAASurface,
+                             &dstProxyView, renderPassXferBarriers, colorLoadOp,
+                             context->priv().caps()},
                              (clip) ? std::move(*clip) : GrAppliedClip::Disabled());
     if (fStencilCurvesProgram) {
         context->priv().recordProgramInfo(fStencilCurvesProgram);
@@ -386,9 +389,9 @@
 void PathInnerTriangulateOp::onPrepare(GrOpFlushState* flushState) {
     if (!fFanTriangulator) {
         this->prePreparePrograms({flushState->allocator(), flushState->writeView(),
-                                 &flushState->dstProxyView(), flushState->renderPassBarriers(),
-                                 flushState->colorLoadOp(), &flushState->caps()},
-                                 flushState->detachAppliedClip());
+                                 flushState->usesMSAASurface(), &flushState->dstProxyView(),
+                                 flushState->renderPassBarriers(), flushState->colorLoadOp(),
+                                 &flushState->caps()}, flushState->detachAppliedClip());
         if (!fFanTriangulator) {
             return;
         }
diff --git a/src/gpu/ops/PathStencilCoverOp.cpp b/src/gpu/ops/PathStencilCoverOp.cpp
index dc56c74..15cd7f8 100644
--- a/src/gpu/ops/PathStencilCoverOp.cpp
+++ b/src/gpu/ops/PathStencilCoverOp.cpp
@@ -184,9 +184,11 @@
         auto* bboxStencil = GrPathTessellationShader::TestAndResetStencilSettings(
                 SkPathFillType_IsInverse(this->pathFillType()));
         fCoverBBoxProgram = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
+                args.fCaps,
                 args.fArena,
                 bboxPipeline,
                 args.fWriteView,
+                args.fUsesMSAASurface,
                 bboxShader,
                 GrPrimitiveType::kTriangleStrip,
                 args.fXferBarrierFlags,
@@ -200,8 +202,11 @@
                                       const GrDstProxyView& dstProxyView,
                                       GrXferBarrierFlags renderPassXferBarriers,
                                       GrLoadOp colorLoadOp) {
-    this->prePreparePrograms({context->priv().recordTimeAllocator(), writeView, &dstProxyView,
-                             renderPassXferBarriers, colorLoadOp, context->priv().caps()},
+    // DMSAA is not supported on DDL.
+    bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+    this->prePreparePrograms({context->priv().recordTimeAllocator(), writeView, usesMSAASurface,
+                             &dstProxyView, renderPassXferBarriers, colorLoadOp,
+                             context->priv().caps()},
                              (clip) ? std::move(*clip) : GrAppliedClip::Disabled());
     if (fStencilFanProgram) {
         context->priv().recordProgramInfo(fStencilFanProgram);
@@ -219,9 +224,9 @@
 void PathStencilCoverOp::onPrepare(GrOpFlushState* flushState) {
     if (!fTessellator) {
         this->prePreparePrograms({flushState->allocator(), flushState->writeView(),
-                                  &flushState->dstProxyView(), flushState->renderPassBarriers(),
-                                  flushState->colorLoadOp(), &flushState->caps()},
-                                  flushState->detachAppliedClip());
+                                 flushState->usesMSAASurface(), &flushState->dstProxyView(),
+                                 flushState->renderPassBarriers(), flushState->colorLoadOp(),
+                                 &flushState->caps()}, flushState->detachAppliedClip());
         if (!fTessellator) {
             return;
         }
diff --git a/src/gpu/ops/PathTessellateOp.cpp b/src/gpu/ops/PathTessellateOp.cpp
index 801e445..6249a22 100644
--- a/src/gpu/ops/PathTessellateOp.cpp
+++ b/src/gpu/ops/PathTessellateOp.cpp
@@ -46,8 +46,11 @@
                                     const GrDstProxyView& dstProxyView,
                                     GrXferBarrierFlags renderPassXferBarriers,
                                     GrLoadOp colorLoadOp) {
-    this->prepareTessellator({context->priv().recordTimeAllocator(), writeView, &dstProxyView,
-                             renderPassXferBarriers, colorLoadOp, context->priv().caps()},
+    // DMSAA is not supported on DDL.
+    bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+    this->prepareTessellator({context->priv().recordTimeAllocator(), writeView, usesMSAASurface,
+                             &dstProxyView, renderPassXferBarriers, colorLoadOp,
+                             context->priv().caps()},
                              (clip) ? std::move(*clip) : GrAppliedClip::Disabled());
     SkASSERT(fTessellationProgram);
     context->priv().recordProgramInfo(fTessellationProgram);
@@ -56,9 +59,9 @@
 void PathTessellateOp::onPrepare(GrOpFlushState* flushState) {
     if (!fTessellator) {
         this->prepareTessellator({flushState->allocator(), flushState->writeView(),
-                                  &flushState->dstProxyView(), flushState->renderPassBarriers(),
-                                  flushState->colorLoadOp(), &flushState->caps()},
-                                  flushState->detachAppliedClip());
+                                 flushState->usesMSAASurface(), &flushState->dstProxyView(),
+                                 flushState->renderPassBarriers(), flushState->colorLoadOp(),
+                                 &flushState->caps()}, flushState->detachAppliedClip());
         SkASSERT(fTessellator);
     }
     fTessellator->prepare(flushState, this->bounds(), {SkMatrix::I(), fPath}, fPath.countVerbs());
diff --git a/src/gpu/ops/StrokeTessellateOp.cpp b/src/gpu/ops/StrokeTessellateOp.cpp
index a1c9521..a755802 100644
--- a/src/gpu/ops/StrokeTessellateOp.cpp
+++ b/src/gpu/ops/StrokeTessellateOp.cpp
@@ -227,8 +227,11 @@
                                       const GrDstProxyView& dstProxyView,
                                       GrXferBarrierFlags renderPassXferBarriers, GrLoadOp
                                       colorLoadOp) {
-    this->prePrepareTessellator({context->priv().recordTimeAllocator(), writeView, &dstProxyView,
-                                renderPassXferBarriers, colorLoadOp, context->priv().caps()},
+    // DMSAA is not supported on DDL.
+    bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+    this->prePrepareTessellator({context->priv().recordTimeAllocator(), writeView, usesMSAASurface,
+                                &dstProxyView, renderPassXferBarriers, colorLoadOp,
+                                context->priv().caps()},
                                 (clip) ? std::move(*clip) : GrAppliedClip::Disabled());
     if (fStencilProgram) {
         context->priv().recordProgramInfo(fStencilProgram);
@@ -241,9 +244,9 @@
 void StrokeTessellateOp::onPrepare(GrOpFlushState* flushState) {
     if (!fTessellator) {
         this->prePrepareTessellator({flushState->allocator(), flushState->writeView(),
-                                    &flushState->dstProxyView(), flushState->renderPassBarriers(),
-                                    flushState->colorLoadOp(), &flushState->caps()},
-                                    flushState->detachAppliedClip());
+                                    flushState->usesMSAASurface(), &flushState->dstProxyView(),
+                                    flushState->renderPassBarriers(), flushState->colorLoadOp(),
+                                    &flushState->caps()}, flushState->detachAppliedClip());
     }
     SkASSERT(fTessellator);
     fTessellator->prepare(flushState, fTotalCombinedVerbCnt);
diff --git a/src/gpu/ops/TriangulatingPathRenderer.cpp b/src/gpu/ops/TriangulatingPathRenderer.cpp
index c958f00..0f2fd0a 100644
--- a/src/gpu/ops/TriangulatingPathRenderer.cpp
+++ b/src/gpu/ops/TriangulatingPathRenderer.cpp
@@ -414,6 +414,7 @@
                                                                : GrPrimitiveType::kTriangles;
 
         fProgramInfo =  fHelper.createProgramInfoWithStencil(caps, arena, writeView,
+                                                             usesMSAASurface,
                                                              std::move(appliedClip), dstProxyView,
                                                              gp, primitiveType,
                                                              renderPassXferBarriers, colorLoadOp);
diff --git a/src/gpu/tessellate/shaders/GrTessellationShader.h b/src/gpu/tessellate/shaders/GrTessellationShader.h
index 01bd73b..23f9c51 100644
--- a/src/gpu/tessellate/shaders/GrTessellationShader.h
+++ b/src/gpu/tessellate/shaders/GrTessellationShader.h
@@ -60,6 +60,7 @@
     struct ProgramArgs {
         SkArenaAlloc* fArena;
         const GrSurfaceProxyView& fWriteView;
+        bool fUsesMSAASurface;
         const GrDstProxyView* fDstProxyView;
         GrXferBarrierFlags fXferBarrierFlags;
         GrLoadOp fColorLoadOp;
@@ -73,8 +74,8 @@
                                       const GrTessellationShader* shader,
                                       const GrPipeline* pipeline,
                                       const GrUserStencilSettings* stencil) {
-        return args.fArena->make<GrProgramInfo>(args.fWriteView, pipeline, stencil, shader,
-                                                shader->fPrimitiveType,
+        return args.fArena->make<GrProgramInfo>(*args.fCaps, args.fWriteView, args.fUsesMSAASurface,
+                                                pipeline, stencil, shader, shader->fPrimitiveType,
                                                 shader->fTessellationPatchVertexCount,
                                                 args.fXferBarrierFlags, args.fColorLoadOp);
     }
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index 6cbb3f1..47e6d48 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -570,9 +570,9 @@
     GrGeometryProcessor* mtp = MeshTestProcessor::Make(fState->allocator(), isInstanced,
                                                        hasVertexBuffer);
 
-    GrProgramInfo programInfo(fState->writeView(), pipeline, &GrUserStencilSettings::kUnused,
-                              mtp, primitiveType, 0, fState->renderPassBarriers(),
-                              fState->colorLoadOp());
+    GrProgramInfo programInfo(fState->caps(), fState->writeView(), fState->usesMSAASurface(),
+                              pipeline, &GrUserStencilSettings::kUnused, mtp, primitiveType, 0,
+                              fState->renderPassBarriers(), fState->colorLoadOp());
 
     fState->opsRenderPass()->bindPipeline(programInfo, SkRect::MakeIWH(kImageWidth, kImageHeight));
     return fState->opsRenderPass();
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index cdd1095..3c06464 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -160,7 +160,9 @@
 
         auto geomProc = PipelineDynamicStateTestProcessor::Make(flushState->allocator());
 
-        GrProgramInfo programInfo(flushState->writeView(),
+        GrProgramInfo programInfo(flushState->caps(),
+                                  flushState->writeView(),
+                                  flushState->usesMSAASurface(),
                                   &pipeline,
                                   &GrUserStencilSettings::kUnused,
                                   geomProc,
diff --git a/tests/GrThreadSafeCacheTest.cpp b/tests/GrThreadSafeCacheTest.cpp
index f8d1704..b5e47f0 100644
--- a/tests/GrThreadSafeCacheTest.cpp
+++ b/tests/GrThreadSafeCacheTest.cpp
@@ -457,6 +457,7 @@
     GrProgramInfo* createProgramInfo(const GrCaps* caps,
                                      SkArenaAlloc* arena,
                                      const GrSurfaceProxyView& writeView,
+                                     bool usesMSAASurface,
                                      GrAppliedClip&& appliedClip,
                                      const GrDstProxyView& dstProxyView,
                                      GrXferBarrierFlags renderPassXferBarriers,
@@ -470,7 +471,7 @@
                                      LocalCoords::kUnused_Type,
                                      SkMatrix::I());
 
-        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView,
+        return sk_gpu_test::CreateProgramInfo(caps, arena, writeView, usesMSAASurface,
                                               std::move(appliedClip), dstProxyView,
                                               gp, SkBlendMode::kSrcOver,
                                               GrPrimitiveType::kTriangleStrip,
@@ -481,6 +482,7 @@
         return this->createProgramInfo(&flushState->caps(),
                                        flushState->allocator(),
                                        flushState->writeView(),
+                                       flushState->usesMSAASurface(),
                                        flushState->detachAppliedClip(),
                                        flushState->dstProxyView(),
                                        flushState->renderPassBarriers(),
@@ -555,12 +557,15 @@
                       GrLoadOp colorLoadOp) override {
         SkArenaAlloc* arena = rContext->priv().recordTimeAllocator();
 
+        // DMSAA is not supported on DDL.
+        bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
+
         // This is equivalent to a GrOpFlushState::detachAppliedClip
         GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip::Disabled();
 
         fProgramInfo = this->createProgramInfo(rContext->priv().caps(), arena, writeView,
-                                               std::move(appliedClip), dstProxyView,
-                                               renderPassXferBarriers, colorLoadOp);
+                                               usesMSAASurface, std::move(appliedClip),
+                                               dstProxyView, renderPassXferBarriers, colorLoadOp);
 
         rContext->priv().recordProgramInfo(fProgramInfo);
 
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index 39cb9bd..c3b64d0 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -130,6 +130,7 @@
         fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
                                                                    arena,
                                                                    writeView,
+                                                                   usesMSAASurface,
                                                                    std::move(appliedClip),
                                                                    dstProxyView,
                                                                    gp,
diff --git a/tools/gpu/ProxyUtils.cpp b/tools/gpu/ProxyUtils.cpp
index 2e998a7..370494d 100644
--- a/tools/gpu/ProxyUtils.cpp
+++ b/tools/gpu/ProxyUtils.cpp
@@ -95,6 +95,7 @@
 GrProgramInfo* CreateProgramInfo(const GrCaps* caps,
                                  SkArenaAlloc* arena,
                                  const GrSurfaceProxyView& writeView,
+                                 bool usesMSAASurface,
                                  GrAppliedClip&& appliedClip,
                                  const GrDstProxyView& dstProxyView,
                                  GrGeometryProcessor* geomProc,
@@ -115,7 +116,7 @@
                                                      GrClampType::kAuto, &analysisColor);
     SkASSERT(!analysis.requiresDstTexture());
 
-    return GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
+    return GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView, usesMSAASurface,
                                                        std::move(appliedClip), dstProxyView,
                                                        geomProc, std::move(processors),
                                                        primitiveType, renderPassXferBarriers,
diff --git a/tools/gpu/ProxyUtils.h b/tools/gpu/ProxyUtils.h
index 198af97..41cdaec 100644
--- a/tools/gpu/ProxyUtils.h
+++ b/tools/gpu/ProxyUtils.h
@@ -32,6 +32,7 @@
 GrProgramInfo* CreateProgramInfo(const GrCaps*,
                                  SkArenaAlloc*,
                                  const GrSurfaceProxyView& writeView,
+                                 bool usesMSAASurface,
                                  GrAppliedClip&&,
                                  const GrDstProxyView&,
                                  GrGeometryProcessor*,
diff --git a/tools/gpu/TestOps.cpp b/tools/gpu/TestOps.cpp
index 572abc1..5e103e3 100644
--- a/tools/gpu/TestOps.cpp
+++ b/tools/gpu/TestOps.cpp
@@ -187,6 +187,7 @@
     fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
                                                                arena,
                                                                writeView,
+                                                               usesMSAASurface,
                                                                std::move(appliedClip),
                                                                dstProxyView,
                                                                &fGP,