Remove sample count from GrSurfaceDesc.

This leaves just width, height, and GrPixelConfig. Once we remove the
latter we can replace GrSurfaceDesc with SkISize.

Also remove unused GrRenderTarget::overrideResolveRect

Also remove GrSurfaceProxy::Renderable and use GrRenderable instead.

Change-Id: I652fe6169a22ca33d199b144ec6385286ac07b5a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228570
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index db97033..5fd0793 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -50,11 +50,6 @@
     void flagAsNeedingResolve(const SkIRect* rect = nullptr);
 
     /**
-     * Call to override the region that needs to be resolved.
-     */
-    void overrideResolveRect(const SkIRect rect);
-
-    /**
      * Call to indicate that GrRenderTarget was externally resolved. This may
      * allow Gr to skip a redundant resolve step.
      */
@@ -90,7 +85,8 @@
     const GrRenderTargetPriv renderTargetPriv() const;
 
 protected:
-    GrRenderTarget(GrGpu*, const GrSurfaceDesc&, GrProtected, GrStencilAttachment* = nullptr);
+    GrRenderTarget(GrGpu*, const GrSurfaceDesc&, int sampleCount, GrProtected,
+                   GrStencilAttachment* = nullptr);
     ~GrRenderTarget() override;
 
     // override of GrResource
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 74b6782..a928d5e 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -76,7 +76,7 @@
     inline const GrSurfacePriv surfacePriv() const;
 
     static size_t WorstCaseSize(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                bool binSize = false);
+                                int renderTargetSampleCnt, bool binSize = false);
     static size_t ComputeSize(GrPixelConfig config, int width, int height, int colorSamplesPerPixel,
                               GrMipMapped, bool binSize = false);
 
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 4249125..7c2b981 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -148,7 +148,7 @@
  * Describes a surface to be created.
  */
 struct GrSurfaceDesc {
-    GrSurfaceDesc() : fWidth(0) , fHeight(0) , fConfig(kUnknown_GrPixelConfig) , fSampleCnt(1) {}
+    GrSurfaceDesc() : fWidth(0), fHeight(0), fConfig(kUnknown_GrPixelConfig) {}
 
     int                    fWidth;  //!< Width of the texture
     int                    fHeight; //!< Height of the texture
@@ -158,15 +158,6 @@
      * internal format used by 3D API.
      */
     GrPixelConfig          fConfig;
-
-    /**
-     * The number of samples per pixel. Zero is treated equivalently to 1. This only
-     * applies if the kRenderTarget_GrSurfaceFlag is set. The actual number
-     * of samples may not exactly match the request. The request will be rounded
-     * up to the next supported sample count. A value larger than the largest
-     * supported sample count will fail.
-     */
-    int                    fSampleCnt;
 };
 
 /** Ownership rules for external GPU resources imported into Skia. */
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index 691714c..aedff7f 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -142,7 +142,6 @@
     desc.fWidth = fCharacterization.width();
     desc.fHeight = fCharacterization.height();
     desc.fConfig = config;
-    desc.fSampleCnt = fCharacterization.sampleCount();
 
     sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
 
@@ -171,6 +170,7 @@
             },
             fCharacterization.backendFormat(),
             desc,
+            fCharacterization.sampleCount(),
             fCharacterization.origin(),
             surfaceFlags,
             optionalTextureInfo,
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index ffda554..e29094b 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -185,7 +185,7 @@
 
                 return std::move(tex);
             },
-            backendFormat, desc, GrRenderable::kNo, fSurfaceOrigin, GrMipMapped::kNo,
+            backendFormat, desc, GrRenderable::kNo, 1, fSurfaceOrigin, GrMipMapped::kNo,
             GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
             GrProtected::kNo);
 
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 4c39d3b..b9444f3 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -192,7 +192,7 @@
                 // unrelated to the whatever SkImage key may be assigned to the proxy.
                 return {std::move(tex), GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
             },
-            format, desc, GrRenderable::kNo, fSurfaceOrigin, mipMapped,
+            format, desc, GrRenderable::kNo, 1, fSurfaceOrigin, mipMapped,
             GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
             GrProtected::kNo);
 
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index cfbfa9d..8c99f24 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -341,7 +341,7 @@
 }
 
 bool GrCaps::validateSurfaceDesc(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                 GrMipMapped mipped) const {
+                                 int renderTargetSampleCnt, GrMipMapped mipped) const {
     if (!this->isConfigTexturable(desc.fConfig)) {
         return false;
     }
@@ -355,7 +355,7 @@
     }
 
     if (renderable == GrRenderable::kYes) {
-        if (0 == this->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig)) {
+        if (0 == this->getRenderTargetSampleCount(renderTargetSampleCnt, desc.fConfig)) {
             return false;
         }
         int maxRTSize = this->maxRenderTargetSize();
@@ -364,7 +364,7 @@
         }
     } else {
         // We currently do not support multisampled textures
-        if (desc.fSampleCnt > 1) {
+        if (renderTargetSampleCnt != 1) {
             return false;
         }
         int maxSize = this->maxTextureSize();
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index ed86cc0..9311df1 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -367,7 +367,8 @@
         return {};
     }
 
-    bool validateSurfaceDesc(const GrSurfaceDesc&, GrRenderable renderable, GrMipMapped) const;
+    bool validateSurfaceDesc(const GrSurfaceDesc&, GrRenderable renderable,
+                             int renderTargetSampleCnt, GrMipMapped) const;
 
     /**
      * If the GrBackendRenderTarget can be used with the supplied SkColorType the return will be
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 3bae1b2..e5c92c5 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -498,7 +498,7 @@
 
         // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
         // to ops), so it can't have any pending IO.
-        proxy = proxyProvider->createProxy(format, desc, GrRenderable::kNo,
+        proxy = proxyProvider->createProxy(format, desc, GrRenderable::kNo, 1,
                                            kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
                                            SkBudgeted::kYes, GrProtected::kNo);
 
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 7010673..4747b14 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -522,7 +522,7 @@
     int numPlotsY = fTextureHeight/fPlotHeight;
 
     for (uint32_t i = 0; i < this->maxPages(); ++i) {
-        fProxies[i] = proxyProvider->createProxy(fFormat, desc, GrRenderable::kNo,
+        fProxies[i] = proxyProvider->createProxy(fFormat, desc, GrRenderable::kNo, 1,
                                                  kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
                                                  SkBudgeted::kYes, GrProtected::kNo);
         if (!fProxies[i]) {
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 8a2ea3b..5bc4b1d 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -145,8 +145,9 @@
 }
 
 sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, GrRenderable renderable,
-                                      SkBudgeted budgeted, GrProtected isProtected,
-                                      const GrMipLevel texels[], int mipLevelCount) {
+                                      int renderTargetSampleCnt, SkBudgeted budgeted,
+                                      GrProtected isProtected, const GrMipLevel texels[],
+                                      int mipLevelCount) {
     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
     if (GrPixelConfigIsCompressed(origDesc.fConfig)) {
         // Call GrGpu::createCompressedTexture.
@@ -155,15 +156,16 @@
     GrSurfaceDesc desc = origDesc;
 
     GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
-    if (!this->caps()->validateSurfaceDesc(desc, renderable, mipMapped)) {
+    if (!this->caps()->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, mipMapped)) {
         return nullptr;
     }
 
     if (renderable == GrRenderable::kYes) {
-        desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig);
+        renderTargetSampleCnt =
+                this->caps()->getRenderTargetSampleCount(renderTargetSampleCnt, desc.fConfig);
     }
     // Attempt to catch un- or wrongly initialized sample counts.
-    SkASSERT(desc.fSampleCnt > 0 && desc.fSampleCnt <= 64);
+    SkASSERT(renderTargetSampleCnt > 0 && renderTargetSampleCnt <= 64);
 
     bool mustHaveDataForAllLevels = this->caps()->createTextureMustSpecifyAllLevels();
     if (mipLevelCount) {
@@ -177,8 +179,8 @@
     }
 
     this->handleDirtyContext();
-    sk_sp<GrTexture> tex =
-            this->onCreateTexture(desc, renderable, budgeted, isProtected, texels, mipLevelCount);
+    sk_sp<GrTexture> tex = this->onCreateTexture(desc, renderable, renderTargetSampleCnt, budgeted,
+                                                 isProtected, texels, mipLevelCount);
     if (tex) {
         if (!this->caps()->reuseScratchTextures() && renderable == GrRenderable::kNo) {
             tex->resourcePriv().removeScratchKey();
@@ -194,8 +196,10 @@
 }
 
 sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                      SkBudgeted budgeted, GrProtected isProtected) {
-    return this->createTexture(desc, renderable, budgeted, isProtected, nullptr, 0);
+                                      int renderTargetSampleCnt, SkBudgeted budgeted,
+                                      GrProtected isProtected) {
+    return this->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
+                               nullptr, 0);
 }
 
 sk_sp<GrTexture> GrGpu::createCompressedTexture(int width, int height,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index c870799..5889f1f 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -87,6 +87,8 @@
      *
      * @param desc           describes the texture to be created.
      * @param renderable     should the resulting texture be renderable
+     * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is
+     *                       kYes. If renderable is kNo then this must be 1.
      * @param budgeted       does this texture count against the resource cache budget?
      * @param isProtected    should the texture be created as protected.
      * @param texels         array of mipmap levels containing texel data to load.
@@ -105,14 +107,15 @@
      *                       latter if GrCaps::createTextureMustSpecifyAllLevels() is true.
      * @return  The texture object if successful, otherwise nullptr.
      */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, GrRenderable renderable, SkBudgeted,
-                                   GrProtected isProtected, const GrMipLevel texels[],
-                                   int mipLevelCount);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
+                                   int renderTargetSampleCnt, SkBudgeted, GrProtected isProtected,
+                                   const GrMipLevel texels[], int mipLevelCount);
 
     /**
      * Simplified createTexture() interface for when there is no initial texel data to upload.
      */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                   SkBudgeted, GrProtected);
 
     sk_sp<GrTexture> createCompressedTexture(int width, int height, SkImage::CompressionType,
                                              SkBudgeted, const void* data, size_t dataSize);
@@ -528,9 +531,9 @@
     // overridden by backend-specific derived class to create objects.
     // Texture size and sample size will have already been validated in base class before
     // onCreateTexture is called.
-    virtual sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted,
-                                             GrProtected, const GrMipLevel[],
-                                             int mipLevelCount) = 0;
+    virtual sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable,
+                                             int renderTargetSampleCnt, SkBudgeted, GrProtected,
+                                             const GrMipLevel[], int mipLevelCount) = 0;
     virtual sk_sp<GrTexture> onCreateCompressedTexture(int width, int height,
                                                        SkImage::CompressionType, SkBudgeted,
                                                        const void* data) = 0;
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index d31e3d8..956d55b 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -115,8 +115,8 @@
 
 #if GR_TEST_UTILS
 sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createInstantiatedProxy(
-        const GrSurfaceDesc& desc, GrRenderable renderable, GrSurfaceOrigin origin,
-        SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected) {
+        const GrSurfaceDesc& desc, GrRenderable renderable, int renderTargetSampleCnt,
+        GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected) {
     GrContext* direct = fImageContext->priv().asDirectContext();
     if (!direct) {
         return nullptr;
@@ -126,11 +126,12 @@
     sk_sp<GrTexture> tex;
 
     if (SkBackingFit::kApprox == fit) {
-        tex = resourceProvider->createApproxTexture(desc, renderable, isProtected,
+        tex = resourceProvider->createApproxTexture(desc, renderable, renderTargetSampleCnt,
+                                                    isProtected,
                                                     GrResourceProvider::Flags::kNoPendingIO);
     } else {
-        tex = resourceProvider->createTexture(desc, renderable, budgeted, isProtected,
-                                              GrResourceProvider::Flags::kNoPendingIO);
+        tex = resourceProvider->createTexture(desc, renderable, renderTargetSampleCnt, budgeted,
+                                              isProtected, GrResourceProvider::Flags::kNoPendingIO);
     }
     if (!tex) {
         return nullptr;
@@ -248,21 +249,21 @@
     GrSurfaceDesc desc;
     desc.fWidth = srcImage->width();
     desc.fHeight = srcImage->height();
-    desc.fSampleCnt = sampleCnt;
     desc.fConfig = config;
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, renderable, budgeted, srcImage, fit](GrResourceProvider* resourceProvider) {
+            [desc, renderable, sampleCnt, budgeted, srcImage,
+             fit](GrResourceProvider* resourceProvider) {
                 SkPixmap pixMap;
                 SkAssertResult(srcImage->peekPixels(&pixMap));
                 GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() };
 
                 return LazyInstantiationResult(resourceProvider->createTexture(
-                        desc, renderable, budgeted, fit, GrProtected::kNo, mipLevel,
+                        desc, renderable, sampleCnt, budgeted, fit, GrProtected::kNo, mipLevel,
                         GrResourceProvider::Flags::kNoPendingIO));
             },
-            format, desc, renderable, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, surfaceFlags, fit,
-            budgeted, GrProtected::kNo);
+            format, desc, renderable, sampleCnt, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+            surfaceFlags, fit, budgeted, GrProtected::kNo);
 
     if (!proxy) {
         return nullptr;
@@ -287,6 +288,7 @@
 sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrBackendFormat& format,
                                                          const GrSurfaceDesc& desc,
                                                          GrRenderable renderable,
+                                                         int renderTargetSampleCnt,
                                                          GrSurfaceOrigin origin,
                                                          SkBudgeted budgeted,
                                                          GrProtected isProtected) {
@@ -296,8 +298,8 @@
         return nullptr;
     }
 
-    return this->createProxy(format, desc, renderable, origin, GrMipMapped::kYes,
-                             SkBackingFit::kExact, budgeted, isProtected,
+    return this->createProxy(format, desc, renderable, renderTargetSampleCnt, origin,
+                             GrMipMapped::kYes, SkBackingFit::kExact, budgeted, isProtected,
                              GrInternalSurfaceFlags::kNone);
 }
 
@@ -388,10 +390,10 @@
                 }
 
                 return LazyInstantiationResult(resourceProvider->createTexture(
-                        desc, GrRenderable::kNo, SkBudgeted::kYes, GrProtected::kNo, texels.get(),
-                        mipLevelCount));
+                        desc, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
+                        texels.get(), mipLevelCount));
             },
-            format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes,
+            format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kYes,
             SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
 
     if (!proxy) {
@@ -437,6 +439,7 @@
 sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrBackendFormat& format,
                                                    const GrSurfaceDesc& desc,
                                                    GrRenderable renderable,
+                                                   int renderTargetSampleCnt,
                                                    GrSurfaceOrigin origin,
                                                    GrMipMapped mipMapped,
                                                    SkBackingFit fit,
@@ -462,24 +465,20 @@
         }
     }
 
-    if (!caps->validateSurfaceDesc(desc, renderable, mipMapped)) {
+    if (!caps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, mipMapped)) {
         return nullptr;
     }
     GrSurfaceDesc copyDesc = desc;
-    if (renderable == GrRenderable::kYes) {
-        copyDesc.fSampleCnt = caps->getRenderTargetSampleCount(desc.fSampleCnt, colorType, format);
-    }
-
     GrSwizzle texSwizzle = caps->getTextureSwizzle(format, colorType);
-
     if (renderable == GrRenderable::kYes) {
+        renderTargetSampleCnt =
+                caps->getRenderTargetSampleCount(renderTargetSampleCnt, colorType, format);
         // We know anything we instantiate later from this deferred path will be
         // both texturable and renderable
         GrSwizzle outSwizzle = caps->getOutputSwizzle(format, colorType);
-        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*caps, format, copyDesc,
-                                                                    origin, mipMapped, texSwizzle,
-                                                                    outSwizzle, fit, budgeted,
-                                                                    isProtected, surfaceFlags));
+        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(
+                *caps, format, copyDesc, renderTargetSampleCnt, origin, mipMapped, texSwizzle,
+                outSwizzle, fit, budgeted, isProtected, surfaceFlags));
     }
 
     return sk_sp<GrTextureProxy>(new GrTextureProxy(format, copyDesc, origin, mipMapped, texSwizzle,
@@ -505,7 +504,7 @@
                 return LazyInstantiationResult(resourceProvider->createCompressedTexture(
                         width, height, compressionType, budgeted, data.get()));
             },
-            format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+            format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
             SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
 
     if (!proxy) {
@@ -737,12 +736,14 @@
                                                        const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrRenderable renderable,
+                                                       int renderTargetSampleCnt,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
                                                        GrProtected isProtected) {
-    return this->createLazyProxy(std::move(callback), format, desc, renderable, origin, mipMapped,
+    return this->createLazyProxy(std::move(callback), format, desc, renderable,
+                                 renderTargetSampleCnt, origin, mipMapped,
                                  GrInternalSurfaceFlags::kNone, fit, budgeted, isProtected);
 }
 
@@ -750,6 +751,7 @@
                                                        const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrRenderable renderable,
+                                                       int renderTargetSampleCnt,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        GrInternalSurfaceFlags surfaceFlags,
@@ -759,14 +761,16 @@
     // For non-ddl draws always make lazy proxy's single use.
     LazyInstantiationType lazyType = this->renderingDirectly() ? LazyInstantiationType::kSingleUse
                                                                : LazyInstantiationType::kMultipleUse;
-    return this->createLazyProxy(std::move(callback), format, desc, renderable, origin, mipMapped,
-                                 surfaceFlags, fit, budgeted, isProtected, lazyType);
+    return this->createLazyProxy(std::move(callback), format, desc, renderable,
+                                 renderTargetSampleCnt, origin, mipMapped, surfaceFlags, fit,
+                                 budgeted, isProtected, lazyType);
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
                                                        const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
                                                        GrRenderable renderable,
+                                                       int renderTargetSampleCnt,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        GrInternalSurfaceFlags surfaceFlags,
@@ -791,8 +795,9 @@
     return sk_sp<GrTextureProxy>(
             renderable == GrRenderable::kYes
                     ? new GrTextureRenderTargetProxy(std::move(callback), lazyType, format, desc,
-                                                     origin, mipMapped, texSwizzle, outSwizzle, fit,
-                                                     budgeted, isProtected, surfaceFlags)
+                                                     renderTargetSampleCnt, origin, mipMapped,
+                                                     texSwizzle, outSwizzle, fit, budgeted,
+                                                     isProtected, surfaceFlags)
                     : new GrTextureProxy(std::move(callback), lazyType, format, desc, origin,
                                          mipMapped, texSwizzle, fit, budgeted, isProtected,
                                          surfaceFlags));
@@ -800,9 +805,9 @@
 
 sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
         LazyInstantiateCallback&& callback, const GrBackendFormat& format,
-        const GrSurfaceDesc& desc, GrSurfaceOrigin origin, GrInternalSurfaceFlags surfaceFlags,
-        const TextureInfo* textureInfo, SkBackingFit fit, SkBudgeted budgeted,
-        GrProtected isProtected, bool wrapsVkSecondaryCB) {
+        const GrSurfaceDesc& desc, int sampleCnt, GrSurfaceOrigin origin,
+        GrInternalSurfaceFlags surfaceFlags, const TextureInfo* textureInfo, SkBackingFit fit,
+        SkBudgeted budgeted, GrProtected isProtected, bool wrapsVkSecondaryCB) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
 
@@ -827,41 +832,43 @@
         // actual VkImage to texture from.
         SkASSERT(!wrapsVkSecondaryCB);
         return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(
-                std::move(callback), lazyType, format, desc, origin, textureInfo->fMipMapped,
-                texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags));
+                std::move(callback), lazyType, format, desc, sampleCnt, origin,
+                textureInfo->fMipMapped, texSwizzle, outSwizzle, fit, budgeted, isProtected,
+                surfaceFlags));
     }
 
     GrRenderTargetProxy::WrapsVkSecondaryCB vkSCB =
             wrapsVkSecondaryCB ? GrRenderTargetProxy::WrapsVkSecondaryCB::kYes
                                : GrRenderTargetProxy::WrapsVkSecondaryCB::kNo;
 
-    return sk_sp<GrRenderTargetProxy>(
-            new GrRenderTargetProxy(std::move(callback), lazyType, format, desc, origin, texSwizzle,
-                                    outSwizzle, fit, budgeted, isProtected, surfaceFlags, vkSCB));
+    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(
+            std::move(callback), lazyType, format, desc, sampleCnt, origin, texSwizzle, outSwizzle,
+            fit, budgeted, isProtected, surfaceFlags, vkSCB));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::MakeFullyLazyProxy(
-        LazyInstantiateCallback&& callback, const GrBackendFormat& format, Renderable renderable,
-        GrProtected isProtected, GrSurfaceOrigin origin, GrPixelConfig config, const GrCaps& caps,
-        int sampleCnt) {
+        LazyInstantiateCallback&& callback, const GrBackendFormat& format, GrRenderable renderable,
+        int renderTargetSampleCnt, GrProtected isProtected, GrSurfaceOrigin origin,
+        GrPixelConfig config, const GrCaps& caps) {
+    SkASSERT(renderTargetSampleCnt == 1 || renderable == GrRenderable::kYes);
     SkASSERT(validate_backend_format_and_config(&caps, format, config));
     GrSurfaceDesc desc;
     GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
     desc.fWidth = -1;
     desc.fHeight = -1;
     desc.fConfig = config;
-    desc.fSampleCnt = sampleCnt;
 
     GrColorType colorType = GrPixelConfigToColorType(desc.fConfig);
     GrSwizzle texSwizzle = caps.getTextureSwizzle(format, colorType);
     GrSwizzle outSwizzle = caps.getOutputSwizzle(format, colorType);
 
     return sk_sp<GrTextureProxy>(
-            (Renderable::kYes == renderable)
+            (GrRenderable::kYes == renderable)
                     ? new GrTextureRenderTargetProxy(
                               std::move(callback), LazyInstantiationType::kSingleUse, format, desc,
-                              origin, GrMipMapped::kNo, texSwizzle, outSwizzle,
-                              SkBackingFit::kApprox, SkBudgeted::kYes, isProtected, surfaceFlags)
+                              renderTargetSampleCnt, origin, GrMipMapped::kNo, texSwizzle,
+                              outSwizzle, SkBackingFit::kApprox, SkBudgeted::kYes, isProtected,
+                              surfaceFlags)
                     : new GrTextureProxy(std::move(callback), LazyInstantiationType::kSingleUse,
                                          format, desc, origin, GrMipMapped::kNo, texSwizzle,
                                          SkBackingFit::kApprox, SkBudgeted::kYes, isProtected,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 838eac8..dd75171 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -73,7 +73,8 @@
      * based on the width and height in the GrSurfaceDesc.
      */
     sk_sp<GrTextureProxy> createMipMapProxy(const GrBackendFormat&, const GrSurfaceDesc&,
-                                            GrRenderable, GrSurfaceOrigin, SkBudgeted, GrProtected);
+                                            GrRenderable, int renderTargetSampleCnt,
+                                            GrSurfaceOrigin, SkBudgeted, GrProtected);
 
     /*
      * Creates a new texture proxy for the bitmap, optionally with mip levels generated by the cpu.
@@ -84,15 +85,17 @@
      * Create a GrSurfaceProxy without any data.
      */
     sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&, const GrSurfaceDesc&, GrRenderable,
-                                      GrSurfaceOrigin, GrMipMapped, SkBackingFit, SkBudgeted,
-                                      GrProtected, GrInternalSurfaceFlags);
+                                      int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
+                                      SkBackingFit, SkBudgeted, GrProtected,
+                                      GrInternalSurfaceFlags);
 
     sk_sp<GrTextureProxy> createProxy(
             const GrBackendFormat& format, const GrSurfaceDesc& desc, GrRenderable renderable,
-            GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected,
+            int renderTargetSampleCnt, GrSurfaceOrigin origin, SkBackingFit fit,
+            SkBudgeted budgeted, GrProtected isProtected,
             GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) {
-        return this->createProxy(format, desc, renderable, origin, GrMipMapped::kNo, fit, budgeted,
-                                 isProtected, surfaceFlags);
+        return this->createProxy(format, desc, renderable, renderTargetSampleCnt, origin,
+                                 GrMipMapped::kNo, fit, budgeted, isProtected, surfaceFlags);
     }
 
     /*
@@ -143,11 +146,6 @@
     using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult;
     using LazyInstantiateCallback = GrSurfaceProxy::LazyInstantiateCallback;
 
-    enum class Renderable : bool {
-        kNo = false,
-        kYes = true
-    };
-
     struct TextureInfo {
         GrMipMapped fMipMapped;
         GrTextureType fTextureType;
@@ -165,23 +163,27 @@
      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
      */
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
-                                          const GrSurfaceDesc&, GrRenderable, GrSurfaceOrigin,
-                                          GrMipMapped, GrInternalSurfaceFlags, SkBackingFit,
-                                          SkBudgeted, GrProtected, LazyInstantiationType);
+                                          const GrSurfaceDesc&, GrRenderable,
+                                          int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
+                                          GrInternalSurfaceFlags, SkBackingFit, SkBudgeted,
+                                          GrProtected, LazyInstantiationType);
 
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
-                                          const GrSurfaceDesc&, GrRenderable, GrSurfaceOrigin,
-                                          GrMipMapped, GrInternalSurfaceFlags, SkBackingFit,
-                                          SkBudgeted, GrProtected);
+                                          const GrSurfaceDesc&, GrRenderable,
+                                          int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
+                                          GrInternalSurfaceFlags, SkBackingFit, SkBudgeted,
+                                          GrProtected);
 
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
-                                          const GrSurfaceDesc&, GrRenderable, GrSurfaceOrigin,
-                                          GrMipMapped, SkBackingFit, SkBudgeted, GrProtected);
+                                          const GrSurfaceDesc&, GrRenderable,
+                                          int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
+                                          SkBackingFit, SkBudgeted, GrProtected);
 
     /** A null TextureInfo indicates a non-textureable render target. */
     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
                                                            const GrBackendFormat&,
                                                            const GrSurfaceDesc&,
+                                                           int renderTargetSampleCnt,
                                                            GrSurfaceOrigin origin,
                                                            GrInternalSurfaceFlags,
                                                            const TextureInfo*,
@@ -195,9 +197,9 @@
      * (e.g., width, height, getBoundsRect) should be avoided.
      */
     static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&,
-                                                    const GrBackendFormat&, Renderable, GrProtected,
-                                                    GrSurfaceOrigin, GrPixelConfig, const GrCaps&,
-                                                    int sampleCnt = 1);
+                                                    const GrBackendFormat&, GrRenderable,
+                                                    int renderTargetSampleCnt, GrProtected,
+                                                    GrSurfaceOrigin, GrPixelConfig, const GrCaps&);
 
     // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
     // determine if it is going to need a texture domain or a full clear.
@@ -245,6 +247,7 @@
      * Create a texture proxy that is backed by an instantiated GrSurface.
      */
     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const GrSurfaceDesc&, GrRenderable,
+                                                              int renderTargetSampleCnt,
                                                               GrSurfaceOrigin, SkBackingFit,
                                                               SkBudgeted, GrProtected);
     sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrSurfaceOrigin);
diff --git a/src/gpu/GrRecordingContext.cpp b/src/gpu/GrRecordingContext.cpp
index 4545ed4..2ff1978 100644
--- a/src/gpu/GrRecordingContext.cpp
+++ b/src/gpu/GrRecordingContext.cpp
@@ -192,11 +192,11 @@
 
     sk_sp<GrTextureProxy> texture;
     if (GrMipMapped::kNo == mipMapped) {
-        texture = this->proxyProvider()->createProxy(format, desc, GrRenderable::kNo, origin, fit,
-                                                     budgeted, isProtected);
+        texture = this->proxyProvider()->createProxy(format, desc, GrRenderable::kNo, 1, origin,
+                                                     fit, budgeted, isProtected);
     } else {
-        texture = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kNo, origin,
-                                                           budgeted, isProtected);
+        texture = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kNo, 1,
+                                                           origin, budgeted, isProtected);
     }
     if (!texture) {
         return nullptr;
@@ -238,15 +238,14 @@
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = config;
-    desc.fSampleCnt = sampleCnt;
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = this->proxyProvider()->createProxy(format, desc, GrRenderable::kYes, origin, fit,
-                                                 budgeted, isProtected);
+        rtp = this->proxyProvider()->createProxy(format, desc, GrRenderable::kYes, sampleCnt,
+                                                 origin, fit, budgeted, isProtected);
     } else {
-        rtp = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kYes, origin,
-                                                       budgeted, isProtected);
+        rtp = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kYes, sampleCnt,
+                                                       origin, budgeted, isProtected);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index fcb0b35..7777cb6 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -19,10 +19,10 @@
 #include "src/gpu/GrStencilAttachment.h"
 #include "src/gpu/GrStencilSettings.h"
 
-GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, GrProtected isProtected,
-                               GrStencilAttachment* stencil)
+GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, int sampleCount,
+                               GrProtected isProtected, GrStencilAttachment* stencil)
         : INHERITED(gpu, desc, isProtected)
-        , fSampleCnt(desc.fSampleCnt)
+        , fSampleCnt(sampleCount)
         , fSamplePatternKey(GrSamplePatternDictionary::kInvalidSamplePatternKey)
         , fStencilAttachment(stencil) {
     fResolveRect = SkRectPriv::MakeILargestInverted();
@@ -43,17 +43,6 @@
     }
 }
 
-void GrRenderTarget::overrideResolveRect(const SkIRect rect) {
-    fResolveRect = rect;
-    if (fResolveRect.isEmpty()) {
-        fResolveRect = SkRectPriv::MakeILargestInverted();
-    } else {
-        if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
-            fResolveRect = SkRectPriv::MakeILargestInverted();
-        }
-    }
-}
-
 void GrRenderTarget::flagAsResolved() {
     fResolveRect = SkRectPriv::MakeILargestInverted();
 }
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 1d6186d..b827e8d 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -20,29 +20,27 @@
 // TODO: we can probably munge the 'desc' in both the wrapped and deferred
 // cases to make the sampleConfig/numSamples stuff more rational.
 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrBackendFormat& format,
-                                         const GrSurfaceDesc& desc, GrSurfaceOrigin origin,
-                                         const GrSwizzle& textureSwizzle,
+                                         const GrSurfaceDesc& desc, int sampleCount,
+                                         GrSurfaceOrigin origin, const GrSwizzle& textureSwizzle,
                                          const GrSwizzle& outputSwizzle, SkBackingFit fit,
                                          SkBudgeted budgeted, GrProtected isProtected,
                                          GrInternalSurfaceFlags surfaceFlags)
         : INHERITED(format, desc, GrRenderable::kYes, origin, textureSwizzle, fit, budgeted,
                     isProtected, surfaceFlags)
-        , fSampleCnt(desc.fSampleCnt)
+        , fSampleCnt(sampleCount)
         , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo)
         , fOutputSwizzle(outputSwizzle) {}
 
 // Lazy-callback version
-GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
-                                         LazyInstantiationType lazyType,
-                                         const GrBackendFormat& format, const GrSurfaceDesc& desc,
-                                         GrSurfaceOrigin origin, const GrSwizzle& textureSwizzle,
-                                         const GrSwizzle& outputSwizzle, SkBackingFit fit,
-                                         SkBudgeted budgeted, GrProtected isProtected,
-                                         GrInternalSurfaceFlags surfaceFlags,
-                                         WrapsVkSecondaryCB wrapsVkSecondaryCB)
+GrRenderTargetProxy::GrRenderTargetProxy(
+        LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
+        const GrBackendFormat& format, const GrSurfaceDesc& desc, int sampleCount,
+        GrSurfaceOrigin origin, const GrSwizzle& textureSwizzle, const GrSwizzle& outputSwizzle,
+        SkBackingFit fit, SkBudgeted budgeted, GrProtected isProtected,
+        GrInternalSurfaceFlags surfaceFlags, WrapsVkSecondaryCB wrapsVkSecondaryCB)
         : INHERITED(std::move(callback), lazyType, format, desc, GrRenderable::kYes, origin,
                     textureSwizzle, fit, budgeted, isProtected, surfaceFlags)
-        , fSampleCnt(desc.fSampleCnt)
+        , fSampleCnt(sampleCount)
         , fWrapsVkSecondaryCB(wrapsVkSecondaryCB)
         , fOutputSwizzle(outputSwizzle) {}
 
diff --git a/src/gpu/GrRenderTargetProxy.h b/src/gpu/GrRenderTargetProxy.h
index 3e36b6b..f43f7d4 100644
--- a/src/gpu/GrRenderTargetProxy.h
+++ b/src/gpu/GrRenderTargetProxy.h
@@ -76,7 +76,7 @@
 
     // Deferred version
     GrRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
-                        GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
+                        int sampleCount, GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
                         const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted, GrProtected,
                         GrInternalSurfaceFlags);
 
@@ -93,10 +93,10 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
-                        const GrBackendFormat&, const GrSurfaceDesc&, GrSurfaceOrigin,
-                        const GrSwizzle& textureSwizzle, const GrSwizzle& outputSwizzle,
-                        SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags,
-                        WrapsVkSecondaryCB wrapsVkSecondaryCB);
+                        const GrBackendFormat&, const GrSurfaceDesc&, int sampleCount,
+                        GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
+                        const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted, GrProtected,
+                        GrInternalSurfaceFlags, WrapsVkSecondaryCB wrapsVkSecondaryCB);
 
     // Wrapped version
     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index ed3565b..e048b3b 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -77,7 +77,8 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
-                                                   GrRenderable renderable, SkBudgeted budgeted,
+                                                   GrRenderable renderable,
+                                                   int renderTargetSampleCnt, SkBudgeted budgeted,
                                                    GrProtected isProtected,
                                                    const GrMipLevel texels[], int mipLevelCount) {
     ASSERT_SINGLE_OWNER
@@ -89,7 +90,7 @@
     }
 
     GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
-    if (!fCaps->validateSurfaceDesc(desc, renderable, mipMapped)) {
+    if (!fCaps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, mipMapped)) {
         return nullptr;
     }
     bool mustInitializeAllLevels = this->caps()->createTextureMustSpecifyAllLevels();
@@ -111,14 +112,18 @@
             h = std::max(h / 2, 1);
         }
     }
-    return fGpu->createTexture(desc, renderable, budgeted, isProtected, tmpTexels.get(),
-                               mipLevelCount);
+    return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
+                               tmpTexels.get(), mipLevelCount);
 }
 
 sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
-                                                     GrRenderable renderable, SkBudgeted budgeted,
-                                                     GrProtected isProtected, Flags flags) {
-    sk_sp<GrTexture> tex(this->refScratchTexture(desc, renderable, isProtected, flags));
+                                                     GrRenderable renderable,
+                                                     int renderTargetSampleCnt,
+                                                     SkBudgeted budgeted,
+                                                     GrProtected isProtected,
+                                                     Flags flags) {
+    sk_sp<GrTexture> tex(
+            this->refScratchTexture(desc, renderable, renderTargetSampleCnt, isProtected, flags));
     if (tex && SkBudgeted::kNo == budgeted) {
         tex->resourcePriv().makeUnbudgeted();
     }
@@ -128,6 +133,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
                                                    GrRenderable renderable,
+                                                   int renderTargetSampleCnt,
                                                    SkBudgeted budgeted,
                                                    SkBackingFit fit,
                                                    GrProtected isProtected,
@@ -143,7 +149,7 @@
         return nullptr;
     }
 
-    if (!fCaps->validateSurfaceDesc(desc, renderable, GrMipMapped::kNo)) {
+    if (!fCaps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, GrMipMapped::kNo)) {
         return nullptr;
     }
 
@@ -164,8 +170,10 @@
     GrColorType colorType = GrPixelConfigToColorType(desc.fConfig);
     sk_sp<GrTexture> tex =
             (SkBackingFit::kApprox == fit)
-                    ? this->createApproxTexture(desc, renderable, isProtected, flags)
-                    : this->createTexture(desc, renderable, budgeted, isProtected, flags);
+                    ? this->createApproxTexture(desc, renderable, renderTargetSampleCnt,
+                                                isProtected, flags)
+                    : this->createTexture(desc, renderable, renderTargetSampleCnt, budgeted,
+                                          isProtected, flags);
     if (!tex) {
         return nullptr;
     }
@@ -200,21 +208,24 @@
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
-                                                   GrRenderable renderable, SkBudgeted budgeted,
-                                                   GrProtected isProtected, Flags flags) {
+                                                   GrRenderable renderable,
+                                                   int renderTargetSampleCnt,
+                                                   SkBudgeted budgeted,
+                                                   GrProtected isProtected,
+                                                   Flags flags) {
     ASSERT_SINGLE_OWNER
     if (this->isAbandoned()) {
         return nullptr;
     }
 
-    if (!fCaps->validateSurfaceDesc(desc, renderable, GrMipMapped::kNo)) {
+    if (!fCaps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, GrMipMapped::kNo)) {
         return nullptr;
     }
 
     // Compressed textures are read-only so they don't support re-use for scratch.
     if (!GrPixelConfigIsCompressed(desc.fConfig)) {
-        sk_sp<GrTexture> tex =
-                this->getExactScratch(desc, renderable, budgeted, isProtected, flags);
+        sk_sp<GrTexture> tex = this->getExactScratch(desc, renderable, renderTargetSampleCnt,
+                                                     budgeted, isProtected, flags);
         if (tex) {
             return tex;
         }
@@ -227,10 +238,11 @@
         GrMipLevel level;
         level.fRowBytes = rowBytes;
         level.fPixels = zeros.get();
-        return fGpu->createTexture(desc, renderable, budgeted, isProtected, &level, 1);
+        return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected,
+                                   &level, 1);
     }
 
-    return fGpu->createTexture(desc, renderable, budgeted, isProtected);
+    return fGpu->createTexture(desc, renderable, renderTargetSampleCnt, budgeted, isProtected);
 }
 
 // Map 'value' to a larger multiple of 2. Values <= 'kMagicTol' will pop up to
@@ -261,6 +273,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
                                                          GrRenderable renderable,
+                                                         int renderTargetSampleCnt,
                                                          GrProtected isProtected, Flags flags) {
     ASSERT_SINGLE_OWNER
     SkASSERT(Flags::kNone == flags || Flags::kNoPendingIO == flags);
@@ -274,11 +287,12 @@
         return nullptr;
     }
 
-    if (!fCaps->validateSurfaceDesc(desc, renderable, GrMipMapped::kNo)) {
+    if (!fCaps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, GrMipMapped::kNo)) {
         return nullptr;
     }
 
-    if (auto tex = this->refScratchTexture(desc, renderable, isProtected, flags)) {
+    if (auto tex = this->refScratchTexture(desc, renderable, renderTargetSampleCnt, isProtected,
+                                           flags)) {
         return tex;
     }
 
@@ -291,7 +305,8 @@
         wdesc->fHeight = MakeApprox(wdesc->fHeight);
     }
 
-    if (auto tex = this->refScratchTexture(*copyDesc, renderable, isProtected, flags)) {
+    if (auto tex = this->refScratchTexture(*copyDesc, renderable, renderTargetSampleCnt,
+                                           isProtected, flags)) {
         return tex;
     }
 
@@ -302,24 +317,28 @@
         GrMipLevel level;
         level.fRowBytes = rowBytes;
         level.fPixels = zeros.get();
-        return fGpu->createTexture(*copyDesc, renderable, SkBudgeted::kYes, isProtected, &level, 1);
+        return fGpu->createTexture(*copyDesc, renderable, renderTargetSampleCnt, SkBudgeted::kYes,
+                                   isProtected, &level, 1);
     }
-    return fGpu->createTexture(*copyDesc, renderable, SkBudgeted::kYes, isProtected);
+    return fGpu->createTexture(*copyDesc, renderable, renderTargetSampleCnt, SkBudgeted::kYes,
+                               isProtected);
 }
 
 sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc,
                                                        GrRenderable renderable,
-                                                       GrProtected isProtected, Flags flags) {
+                                                       int renderTargetSampleCnt,
+                                                       GrProtected isProtected,
+                                                       Flags flags) {
     ASSERT_SINGLE_OWNER
     SkASSERT(!this->isAbandoned());
     SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
-    SkASSERT(fCaps->validateSurfaceDesc(desc, renderable, GrMipMapped::kNo));
+    SkASSERT(fCaps->validateSurfaceDesc(desc, renderable, renderTargetSampleCnt, GrMipMapped::kNo));
 
     // We could make initial clears work with scratch textures but it is a rare case so we just opt
     // to fall back to making a new texture.
     if (fGpu->caps()->reuseScratchTextures() || renderable == GrRenderable::kYes) {
         GrScratchKey key;
-        GrTexturePriv::ComputeScratchKey(desc, renderable, &key);
+        GrTexturePriv::ComputeScratchKey(desc, renderable, renderTargetSampleCnt, &key);
         auto scratchFlags = GrResourceCache::ScratchFlags::kNone;
         if (Flags::kNoPendingIO & flags) {
             scratchFlags |= GrResourceCache::ScratchFlags::kRequireNoPendingIO;
@@ -329,7 +348,8 @@
             scratchFlags |= GrResourceCache::ScratchFlags::kPreferNoPendingIO;
         }
         GrGpuResource* resource = fCache->findAndRefScratchResource(
-                key, GrSurface::WorstCaseSize(desc, renderable), scratchFlags);
+                key, GrSurface::WorstCaseSize(desc, renderable, renderTargetSampleCnt),
+                scratchFlags);
         if (resource) {
             fGpu->stats()->incNumScratchTexturesReused();
             GrSurface* surface = static_cast<GrSurface*>(resource);
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 74c4c6d..695eb02 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -75,18 +75,20 @@
      * GrRenderTarget. The texture's format and sample count will always match the request.
      * The contents of the texture are undefined.
      */
-    sk_sp<GrTexture> createApproxTexture(const GrSurfaceDesc&, GrRenderable, GrProtected, Flags);
+    sk_sp<GrTexture> createApproxTexture(const GrSurfaceDesc&, GrRenderable,
+                                         int renderTargetSampleCnt, GrProtected, Flags);
 
     /** Create an exact fit texture with no initial data to upload. */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                   Flags = Flags::kNone);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                   SkBudgeted, GrProtected, Flags = Flags::kNone);
 
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                   const GrMipLevel texels[], int mipLevelCount);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                   SkBudgeted, GrProtected, const GrMipLevel texels[],
+                                   int mipLevelCount);
 
     /** Create a potentially loose fit texture with the provided data */
-    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, SkBackingFit,
-                                   GrProtected, const GrMipLevel&, Flags);
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                   SkBudgeted, SkBackingFit, GrProtected, const GrMipLevel&, Flags);
 
     /**
      * Creates a compressed texture. The GrGpu must support the SkImageImage::Compression type.
@@ -266,14 +268,15 @@
 
     // Attempts to find a resource in the cache that exactly matches the GrSurfaceDesc. Failing that
     // it returns null. If non-null, the resulting texture is always budgeted.
-    sk_sp<GrTexture> refScratchTexture(const GrSurfaceDesc&, GrRenderable, GrProtected, Flags);
+    sk_sp<GrTexture> refScratchTexture(const GrSurfaceDesc&, GrRenderable,
+                                       int renderTargetSampleCnt, GrProtected, Flags);
 
     /*
      * Try to find an existing scratch texture that exactly matches 'desc'. If successful
      * update the budgeting accordingly.
      */
-    sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                     Flags);
+    sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                     SkBudgeted, GrProtected, Flags);
 
     GrResourceCache* cache() { return fCache; }
     const GrResourceCache* cache() const { return fCache; }
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 99f7699..febf245 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -184,7 +184,7 @@
     const GrBackendFormat format =
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kAlpha_8);
 
-    return proxyProvider->createProxy(format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin,
+    return proxyProvider->createProxy(format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin,
                                       fit, SkBudgeted::kYes, GrProtected::kNo);
 }
 
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index 67804bf..cd0afcb 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -16,7 +16,8 @@
 #include "src/core/SkMathPriv.h"
 #include "src/gpu/SkGr.h"
 
-size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, GrRenderable renderable, bool binSize) {
+size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, GrRenderable renderable,
+                                int renderTargetSampleCnt, bool binSize) {
     size_t size;
 
     int width  = binSize ? GrResourceProvider::MakeApprox(desc.fWidth)  : desc.fWidth;
@@ -24,9 +25,9 @@
 
     if (renderable == GrRenderable::kYes) {
         // We own one color value for each MSAA sample.
-        SkASSERT(desc.fSampleCnt >= 1);
-        int colorValuesPerPixel = desc.fSampleCnt;
-        if (desc.fSampleCnt > 1) {
+        SkASSERT(renderTargetSampleCnt >= 1);
+        int colorValuesPerPixel = renderTargetSampleCnt;
+        if (renderTargetSampleCnt > 1) {
             // Worse case, we own the resolve buffer so that is one more sample per pixel.
             colorValuesPerPixel += 1;
         }
@@ -41,6 +42,7 @@
         size = colorValuesPerPixel * colorBytes;
         size += colorBytes/3; // in case we have to mipmap
     } else {
+        SkASSERT(renderTargetSampleCnt == 1);
         if (GrPixelConfigIsCompressed(desc.fConfig)) {
             size = GrCompressedFormatDataSize(desc.fConfig, width, height);
         } else {
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index 6ec45d8..cfb2922 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -280,7 +280,6 @@
         GrSurfaceDesc desc;
         desc.fWidth = srcInfo.width();
         desc.fHeight = srcInfo.height();
-        desc.fSampleCnt = 1;
         GrColorType colorType;
 
         GrBackendFormat format;
@@ -308,7 +307,7 @@
         GrSurfaceOrigin tempOrigin =
                 this->asRenderTargetContext() ? kTopLeft_GrSurfaceOrigin : dstProxy->origin();
         auto tempProxy = direct->priv().proxyProvider()->createProxy(
-                format, desc, GrRenderable::kNo, tempOrigin, SkBackingFit::kApprox,
+                format, desc, GrRenderable::kNo, 1, tempOrigin, SkBackingFit::kApprox,
                 SkBudgeted::kYes, GrProtected::kNo);
 
         if (!tempProxy) {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index a82559c..078541b 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -33,7 +33,6 @@
     return desc.fWidth <= 0 &&
            desc.fHeight <= 0 &&
            desc.fConfig != kUnknown_GrPixelConfig &&
-           desc.fSampleCnt == 1 &&
            SkBackingFit::kApprox == fit;
 }
 
@@ -140,7 +139,6 @@
     desc.fWidth = fWidth;
     desc.fHeight = fHeight;
     desc.fConfig = fConfig;
-    desc.fSampleCnt = sampleCnt;
 
     // The explicit resource allocator requires that any resources it pulls out of the
     // cache have no pending IO.
@@ -163,19 +161,19 @@
             texels[i].fRowBytes = 0;
         }
 
-        surface = resourceProvider->createTexture(desc, renderable, fBudgeted, fIsProtected,
-                                                  texels.get(), mipCount);
+        surface = resourceProvider->createTexture(desc, renderable, sampleCnt, fBudgeted,
+                                                  fIsProtected, texels.get(), mipCount);
         if (surface) {
             SkASSERT(surface->asTexture());
             SkASSERT(GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
         }
     } else {
         if (SkBackingFit::kApprox == fFit) {
-            surface = resourceProvider->createApproxTexture(desc, renderable, fIsProtected,
-                                                            resourceProviderFlags);
+            surface = resourceProvider->createApproxTexture(desc, renderable, sampleCnt,
+                                                            fIsProtected, resourceProviderFlags);
         } else {
-            surface = resourceProvider->createTexture(desc, renderable, fBudgeted, fIsProtected,
-                                                      resourceProviderFlags);
+            surface = resourceProvider->createTexture(desc, renderable, sampleCnt, fBudgeted,
+                                                      fIsProtected, resourceProviderFlags);
         }
     }
     if (!surface) {
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 1877e53..627c507 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -116,8 +116,8 @@
 }
 
 void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                      GrScratchKey* key) {
+                                      int sampleCnt, GrScratchKey* key) {
     // Note: the fOrigin field is not used in the scratch key
-    return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight, renderable, desc.fSampleCnt,
+    return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight, renderable, sampleCnt,
                              GrMipMapped::kNo, key);
 }
diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h
index 101f1aa..69404b0 100644
--- a/src/gpu/GrTexturePriv.h
+++ b/src/gpu/GrTexturePriv.h
@@ -50,7 +50,7 @@
                                              : GrSamplerState::Filter::kMipMap;
     }
 
-    static void ComputeScratchKey(const GrSurfaceDesc&, GrRenderable, GrScratchKey*);
+    static void ComputeScratchKey(const GrSurfaceDesc&, GrRenderable, int sampleCnt, GrScratchKey*);
     static void ComputeScratchKey(GrPixelConfig config, int width, int height, GrRenderable,
                                   int sampleCnt, GrMipMapped, GrScratchKey* key);
 
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 22a02f9..63716b5 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -21,6 +21,7 @@
 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
                                                        const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
+                                                       int sampleCnt,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        const GrSwizzle& texSwizzle,
@@ -32,8 +33,8 @@
         : GrSurfaceProxy(format, desc, GrRenderable::kYes, origin, texSwizzle, fit, budgeted,
                          isProtected, surfaceFlags)
         // for now textures w/ data are always wrapped
-        , GrRenderTargetProxy(caps, format, desc, origin, texSwizzle, outSwizzle, fit, budgeted,
-                              isProtected, surfaceFlags)
+        , GrRenderTargetProxy(caps, format, desc, sampleCnt, origin, texSwizzle, outSwizzle, fit,
+                              budgeted, isProtected, surfaceFlags)
         , GrTextureProxy(format, desc, origin, mipMapped, texSwizzle, fit, budgeted, isProtected,
                          surfaceFlags) {}
 
@@ -42,6 +43,7 @@
                                                        LazyInstantiationType lazyType,
                                                        const GrBackendFormat& format,
                                                        const GrSurfaceDesc& desc,
+                                                       int sampleCnt,
                                                        GrSurfaceOrigin origin,
                                                        GrMipMapped mipMapped,
                                                        const GrSwizzle& texSwizzle,
@@ -54,8 +56,8 @@
                          texSwizzle, fit, budgeted, isProtected, surfaceFlags)
         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
-        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, format, desc, origin, texSwizzle,
-                              outSwizzle, fit, budgeted, isProtected, surfaceFlags,
+        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, format, desc, sampleCnt, origin,
+                              texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags,
                               WrapsVkSecondaryCB::kNo)
         , GrTextureProxy(LazyInstantiateCallback(), lazyType, format, desc, origin, mipMapped,
                          texSwizzle, fit, budgeted, isProtected, surfaceFlags) {}
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index efd1432..3270d05 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -29,14 +29,14 @@
 
     // Deferred version
     GrTextureRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
-                               GrSurfaceOrigin, GrMipMapped, const GrSwizzle& textureSwizzle,
-                               const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted,
-                               GrProtected, GrInternalSurfaceFlags);
+                               int sampleCnt, GrSurfaceOrigin, GrMipMapped,
+                               const GrSwizzle& textureSwizzle, const GrSwizzle& outputSwizzle,
+                               SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags);
 
     // Lazy-callback version
     GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
-                               const GrBackendFormat&, const GrSurfaceDesc& desc, GrSurfaceOrigin,
-                               GrMipMapped, const GrSwizzle& textureSwizzle,
+                               const GrBackendFormat&, const GrSurfaceDesc& desc, int sampleCnt,
+                               GrSurfaceOrigin, GrMipMapped, const GrSwizzle& textureSwizzle,
                                const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted,
                                GrProtected, GrInternalSurfaceFlags);
 
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index f3d259b..93eb6ab 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -159,7 +159,7 @@
 
     // TODO: investigate preallocating mip maps here
     sk_sp<GrRenderTargetContext> renderTargetContext(ctx->priv().makeDeferredRenderTargetContext(
-            SkBackingFit::kExact, desc.fWidth, desc.fHeight, colorType, nullptr, desc.fSampleCnt,
+            SkBackingFit::kExact, desc.fWidth, desc.fHeight, colorType, nullptr, 1,
             GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin));
     if (!renderTargetContext) {
         return nullptr;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index df17102..bb8d19b 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -89,7 +89,6 @@
     desc.fWidth = info.width();
     desc.fHeight = info.height();
     desc.fConfig = SkImageInfo2GrPixelConfig(info);
-    desc.fSampleCnt = 1;
     return desc;
 }
 
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 0b2332e..e32036d 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -79,9 +79,8 @@
     const GrBackendFormat format = caps.getBackendFormatFromColorType(colorType);
 
     sk_sp<GrTextureProxy> proxy = GrProxyProvider::MakeFullyLazyProxy(
-            std::bind(callback, std::placeholders::_1, pixelConfig, sampleCount),
-            format, GrProxyProvider::Renderable::kYes, GrProtected::kNo, kTextureOrigin,
-            pixelConfig, caps, sampleCount);
+            std::bind(callback, std::placeholders::_1, pixelConfig, sampleCount), format,
+            GrRenderable::kYes, sampleCount, GrProtected::kNo, kTextureOrigin, pixelConfig, caps);
 
     return proxy;
 }
@@ -120,9 +119,8 @@
             desc.fWidth = fWidth;
             desc.fHeight = fHeight;
             desc.fConfig = pixelConfig;
-            desc.fSampleCnt = sampleCount;
             fBackingTexture = resourceProvider->createTexture(
-                    desc, GrRenderable::kYes, SkBudgeted::kYes, GrProtected::kNo,
+                    desc, GrRenderable::kYes, sampleCount, SkBudgeted::kYes, GrProtected::kNo,
                     GrResourceProvider::Flags::kNoPendingIO);
         }
         return fBackingTexture;
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 6f764de..b7732b3 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -142,12 +142,12 @@
     desc.fWidth = tex.width();
     desc.fHeight = tex.height();
     desc.fConfig = tex.config();
-    desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
-    if (desc.fSampleCnt < 1) {
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
+    if (sampleCnt < 1) {
         return nullptr;
     }
 
-    sk_sp<GrDawnRenderTarget> tgt = GrDawnRenderTarget::MakeWrapped(this, desc, info);
+    sk_sp<GrDawnRenderTarget> tgt = GrDawnRenderTarget::MakeWrapped(this, desc, sampleCnt, info);
     return tgt;
 }
 
diff --git a/src/gpu/dawn/GrDawnRenderTarget.cpp b/src/gpu/dawn/GrDawnRenderTarget.cpp
index 1a28ce2..d60a32f 100644
--- a/src/gpu/dawn/GrDawnRenderTarget.cpp
+++ b/src/gpu/dawn/GrDawnRenderTarget.cpp
@@ -13,29 +13,32 @@
 
 GrDawnRenderTarget::GrDawnRenderTarget(GrDawnGpu* gpu,
                                        const GrSurfaceDesc& desc,
+                                       int sampleCnt,
                                        const GrDawnImageInfo& info,
                                        GrBackendObjectOwnership ownership)
-    : GrSurface(gpu, desc, GrProtected::kNo)
-    , GrRenderTarget(gpu, desc, GrProtected::kNo)
-    , fInfo(info) {
+        : GrSurface(gpu, desc, GrProtected::kNo)
+        , GrRenderTarget(gpu, desc, sampleCnt, GrProtected::kNo)
+        , fInfo(info) {
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
 
 GrDawnRenderTarget*
 GrDawnRenderTarget::Create(GrDawnGpu* gpu,
                            const GrSurfaceDesc& desc,
+                           int sampleCnt,
                            const GrDawnImageInfo& info,
                            GrBackendObjectOwnership ownership) {
     SkASSERT(1 == info.fLevelCount);
-    return new GrDawnRenderTarget(gpu, desc, info, ownership);
+    return new GrDawnRenderTarget(gpu, desc, sampleCnt, info, ownership);
 }
 
 sk_sp<GrDawnRenderTarget>
 GrDawnRenderTarget::MakeWrapped(GrDawnGpu* gpu,
                                 const GrSurfaceDesc& desc,
+                                int sampleCnt,
                                 const GrDawnImageInfo& info) {
     return sk_sp<GrDawnRenderTarget>(
-        GrDawnRenderTarget::Create(gpu, desc, info,
+        GrDawnRenderTarget::Create(gpu, desc, sampleCnt, info,
                                   GrBackendObjectOwnership::kBorrowed));
 }
 
diff --git a/src/gpu/dawn/GrDawnRenderTarget.h b/src/gpu/dawn/GrDawnRenderTarget.h
index 271eff0..6054ef8 100644
--- a/src/gpu/dawn/GrDawnRenderTarget.h
+++ b/src/gpu/dawn/GrDawnRenderTarget.h
@@ -16,7 +16,7 @@
 
 class GrDawnRenderTarget: public GrRenderTarget {
 public:
-    static sk_sp<GrDawnRenderTarget> MakeWrapped(GrDawnGpu*, const GrSurfaceDesc&,
+    static sk_sp<GrDawnRenderTarget> MakeWrapped(GrDawnGpu*, const GrSurfaceDesc&, int sampleCnt,
                                                  const GrDawnImageInfo&);
 
     ~GrDawnRenderTarget() override;
@@ -39,6 +39,7 @@
 protected:
     GrDawnRenderTarget(GrDawnGpu* gpu,
                        const GrSurfaceDesc& desc,
+                       int sampleCnt,
                        const GrDawnImageInfo& info,
                        GrBackendObjectOwnership);
 
@@ -56,7 +57,7 @@
                                       numSamples, GrMipMapped::kNo);
     }
 
-    static GrDawnRenderTarget* Create(GrDawnGpu*, const GrSurfaceDesc&,
+    static GrDawnRenderTarget* Create(GrDawnGpu*, const GrSurfaceDesc&, int sampleCnt,
                                       const GrDawnImageInfo&, GrBackendObjectOwnership);
 
     bool completeStencilAttachment() override;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index f865d44..8821814 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -703,7 +703,6 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = 1;
 
     GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
                                                             : GrMipMapsStatus::kNotAllocated;
@@ -745,14 +744,15 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = caps->getRenderTargetSampleCount(sampleCnt, colorType,
-                                                           backendTex.getBackendFormat());
-    if (surfDesc.fSampleCnt < 1) {
+
+    sampleCnt =
+            caps->getRenderTargetSampleCount(sampleCnt, colorType, backendTex.getBackendFormat());
+    if (sampleCnt < 1) {
         return nullptr;
     }
 
     GrGLRenderTarget::IDDesc rtIDDesc;
-    if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) {
+    if (!this->createRenderTargetObjects(surfDesc, sampleCnt, idDesc.fInfo, &rtIDDesc)) {
         return nullptr;
     }
 
@@ -760,7 +760,7 @@
                                                             : GrMipMapsStatus::kNotAllocated;
 
     sk_sp<GrGLTextureRenderTarget> texRT(GrGLTextureRenderTarget::MakeWrapped(
-            this, surfDesc, idDesc, backendTex.getGLTextureParams(), rtIDDesc, cacheable,
+            this, surfDesc, sampleCnt, idDesc, backendTex.getGLTextureParams(), rtIDDesc, cacheable,
             mipMapsStatus));
     texRT->baseLevelWasBoundToFBO();
     // We don't know what parameters are already set on wrapped textures.
@@ -789,10 +789,11 @@
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
-    desc.fSampleCnt =
+    int sampleCount =
             this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config());
 
-    return GrGLRenderTarget::MakeWrapped(this, desc, info.fFormat, idDesc, backendRT.stencilBits());
+    return GrGLRenderTarget::MakeWrapped(this, desc, sampleCount, info.fFormat, idDesc,
+                                         backendRT.stencilBits());
 }
 
 sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
@@ -814,13 +815,13 @@
     surfDesc.fWidth = tex.width();
     surfDesc.fHeight = tex.height();
     surfDesc.fConfig = tex.config();
-    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
+    int sampleCount = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
 
     GrGLRenderTarget::IDDesc rtIDDesc;
-    if (!this->createRenderTargetObjects(surfDesc, info, &rtIDDesc)) {
+    if (!this->createRenderTargetObjects(surfDesc, sampleCount, info, &rtIDDesc)) {
         return nullptr;
     }
-    return GrGLRenderTarget::MakeWrapped(this, surfDesc, info.fFormat, rtIDDesc, 0);
+    return GrGLRenderTarget::MakeWrapped(this, surfDesc, sampleCount, info.fFormat, rtIDDesc, 0);
 }
 
 static bool check_write_and_transfer_input(GrGLTexture* glTex) {
@@ -1346,6 +1347,7 @@
 }
 
 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
+                                        int sampleCount,
                                         const GrGLTextureInfo& texInfo,
                                         GrGLRenderTarget::IDDesc* idDesc) {
     idDesc->fMSColorRenderbufferID = 0;
@@ -1362,7 +1364,7 @@
         goto FAILED;
     }
 
-    if (desc.fSampleCnt > 1 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
+    if (sampleCount > 1 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
         goto FAILED;
     }
 
@@ -1375,7 +1377,7 @@
     // the texture bound to the other. The exception is the IMG multisample extension. With this
     // extension the texture is multisampled when rendered to and then auto-resolves it when it is
     // rendered from.
-    if (desc.fSampleCnt > 1 && this->glCaps().usesMSAARenderBuffers()) {
+    if (sampleCount > 1 && this->glCaps().usesMSAARenderBuffers()) {
         GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID));
         GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
         if (!idDesc->fRTFBOID ||
@@ -1390,11 +1392,9 @@
     // below here we may bind the FBO
     fHWBoundRenderTargetUniqueID.makeInvalid();
     if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
-        SkASSERT(desc.fSampleCnt > 1);
+        SkASSERT(sampleCount > 1);
         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID));
-        if (!renderbuffer_storage_msaa(*fGLContext,
-                                       desc.fSampleCnt,
-                                       colorRenderbufferFormat,
+        if (!renderbuffer_storage_msaa(*fGLContext, sampleCount, colorRenderbufferFormat,
                                        desc.fWidth, desc.fHeight)) {
             goto FAILED;
         }
@@ -1413,11 +1413,9 @@
     }
     this->bindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID);
 
-    if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 1) {
-        GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
-                                                GR_GL_COLOR_ATTACHMENT0,
-                                                texInfo.fTarget,
-                                                texInfo.fID, 0, desc.fSampleCnt));
+    if (this->glCaps().usesImplicitMSAAResolve() && sampleCount > 1) {
+        GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
+                                                texInfo.fTarget, texInfo.fID, 0, sampleCount));
     } else {
         GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
                                      GR_GL_COLOR_ATTACHMENT0,
@@ -1472,6 +1470,7 @@
 
 sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
                                           GrRenderable renderable,
+                                          int renderTargetSampleCnt,
                                           SkBudgeted budgeted,
                                           GrProtected isProtected,
                                           const GrMipLevel texels[],
@@ -1480,10 +1479,7 @@
     if (isProtected == GrProtected::kYes) {
         return nullptr;
     }
-    // We fail if the MSAA was requested and is not available.
-    if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt > 1) {
-        return return_null_texture();
-    }
+    SkASSERT(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType() || renderTargetSampleCnt == 1);
 
     GrGLTexture::IDDesc idDesc;
     idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
@@ -1500,12 +1496,13 @@
         GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0));
         GrGLRenderTarget::IDDesc rtIDDesc;
 
-        if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) {
+        if (!this->createRenderTargetObjects(desc, renderTargetSampleCnt, idDesc.fInfo,
+                                             &rtIDDesc)) {
             GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
             return return_null_texture();
         }
-        tex = sk_make_sp<GrGLTextureRenderTarget>(this, budgeted, desc, idDesc, rtIDDesc,
-                                                  mipMapsStatus);
+        tex = sk_make_sp<GrGLTextureRenderTarget>(this, budgeted, desc, renderTargetSampleCnt,
+                                                  idDesc, rtIDDesc, mipMapsStatus);
         tex->baseLevelWasBoundToFBO();
     } else {
         tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, mipMapsStatus);
@@ -1544,7 +1541,6 @@
     desc.fConfig = GrCompressionTypePixelConfig(compression);
     desc.fWidth = width;
     desc.fHeight = height;
-    desc.fSampleCnt = 1;
     auto tex =
             sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, GrMipMapsStatus::kNotAllocated);
     // The non-sampler params are still at their default values.
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index c6d65b3..54a2b28 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -191,8 +191,9 @@
 
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
 
-    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                     const GrMipLevel[], int mipLevelCount) override;
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                     SkBudgeted, GrProtected, const GrMipLevel[],
+                                     int mipLevelCount) override;
     sk_sp<GrTexture> onCreateCompressedTexture(int width, int height,
                                                SkImage::CompressionType compression, SkBudgeted,
                                                const void* data) override;
@@ -398,8 +399,8 @@
     GrGLenum uploadCompressedTexData(SkImage::CompressionType, int width, int height,
                                      GrGLenum target, const void* data);
 
-    bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
-                                   GrGLRenderTarget::IDDesc*);
+    bool createRenderTargetObjects(const GrSurfaceDesc&, int sampleCount,
+                                   const GrGLTextureInfo& texInfo, GrGLRenderTarget::IDDesc*);
 
     enum TempFBOTarget {
         kSrc_TempFBOTarget,
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index 0b48f73..104b6e9 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -21,20 +21,21 @@
 // Constructor for wrapped render targets.
 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
                                    const GrSurfaceDesc& desc,
+                                   int sampleCount,
                                    GrGLenum format,
                                    const IDDesc& idDesc,
                                    GrGLStencilAttachment* stencil)
-    : GrSurface(gpu, desc, GrProtected::kNo)
-    , INHERITED(gpu, desc, GrProtected::kNo, stencil) {
+        : GrSurface(gpu, desc, GrProtected::kNo)
+        , INHERITED(gpu, desc, sampleCount, GrProtected::kNo, stencil) {
     this->setFlags(gpu->glCaps(), idDesc);
     this->init(desc, format, idDesc);
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
 
-GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, GrGLenum format,
-                                   const IDDesc& idDesc)
-    : GrSurface(gpu, desc, GrProtected::kNo)
-    , INHERITED(gpu, desc, GrProtected::kNo) {
+GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, int sampleCount,
+                                   GrGLenum format, const IDDesc& idDesc)
+        : GrSurface(gpu, desc, GrProtected::kNo)
+        , INHERITED(gpu, desc, sampleCount, GrProtected::kNo) {
     this->setFlags(gpu->glCaps(), idDesc);
     this->init(desc, format, idDesc);
 }
@@ -58,6 +59,7 @@
 
 sk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu,
                                                       const GrSurfaceDesc& desc,
+                                                      int sampleCount,
                                                       GrGLenum format,
                                                       const IDDesc& idDesc,
                                                       int stencilBits) {
@@ -70,10 +72,10 @@
         format.fStencilBits = stencilBits;
         format.fTotalBits = stencilBits;
         // Ownership of sb is passed to the GrRenderTarget so doesn't need to be deleted
-        sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight,
-                                       desc.fSampleCnt, format);
+        sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight, sampleCount, format);
     }
-    return sk_sp<GrGLRenderTarget>(new GrGLRenderTarget(gpu, desc, format, idDesc, sb));
+    return sk_sp<GrGLRenderTarget>(
+            new GrGLRenderTarget(gpu, desc, sampleCount, format, idDesc, sb));
 }
 
 GrBackendRenderTarget GrGLRenderTarget::getBackendRenderTarget() const {
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index e34065b..fb2cd9c 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -35,6 +35,7 @@
 
     static sk_sp<GrGLRenderTarget> MakeWrapped(GrGLGpu*,
                                                const GrSurfaceDesc&,
+                                               int sampleCount,
                                                GrGLenum format,
                                                const IDDesc&,
                                                int stencilBits);
@@ -69,7 +70,8 @@
 
 protected:
     // Constructor for subclasses.
-    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, GrGLenum format, const IDDesc&);
+    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, int sampleCount, GrGLenum format,
+                     const IDDesc&);
 
     void init(const GrSurfaceDesc&, GrGLenum format, const IDDesc&);
 
@@ -80,8 +82,8 @@
 
 private:
     // Constructor for instances wrapping backend objects.
-    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, GrGLenum format, const IDDesc&,
-                     GrGLStencilAttachment*);
+    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, int sampleCount, GrGLenum format,
+                     const IDDesc&, GrGLStencilAttachment*);
 
     void setFlags(const GrGLCaps&, const IDDesc&);
 
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp
index b46538a..de86e9f 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.cpp
+++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp
@@ -15,17 +15,19 @@
 GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
                                                  SkBudgeted budgeted,
                                                  const GrSurfaceDesc& desc,
+                                                 int sampleCount,
                                                  const GrGLTexture::IDDesc& texIDDesc,
                                                  const GrGLRenderTarget::IDDesc& rtIDDesc,
                                                  GrMipMapsStatus mipMapsStatus)
         : GrSurface(gpu, desc, GrProtected::kNo)
         , GrGLTexture(gpu, desc, texIDDesc, nullptr, mipMapsStatus)
-        , GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
+        , GrGLRenderTarget(gpu, desc, sampleCount, texIDDesc.fInfo.fFormat, rtIDDesc) {
     this->registerWithCache(budgeted);
 }
 
 GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
                                                  const GrSurfaceDesc& desc,
+                                                 int sampleCount,
                                                  const GrGLTexture::IDDesc& texIDDesc,
                                                  sk_sp<GrGLTextureParameters> parameters,
                                                  const GrGLRenderTarget::IDDesc& rtIDDesc,
@@ -33,7 +35,7 @@
                                                  GrMipMapsStatus mipMapsStatus)
         : GrSurface(gpu, desc, GrProtected::kNo)
         , GrGLTexture(gpu, desc, texIDDesc, std::move(parameters), mipMapsStatus)
-        , GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
+        , GrGLRenderTarget(gpu, desc, sampleCount, texIDDesc.fInfo.fFormat, rtIDDesc) {
     this->registerWithCacheWrapped(cacheable);
 }
 
@@ -58,11 +60,13 @@
 }
 
 sk_sp<GrGLTextureRenderTarget> GrGLTextureRenderTarget::MakeWrapped(
-        GrGLGpu* gpu, const GrSurfaceDesc& desc, const GrGLTexture::IDDesc& texIDDesc,
-        sk_sp<GrGLTextureParameters> parameters, const GrGLRenderTarget::IDDesc& rtIDDesc,
-        GrWrapCacheable cacheable, GrMipMapsStatus mipMapsStatus) {
-    return sk_sp<GrGLTextureRenderTarget>(new GrGLTextureRenderTarget(
-            gpu, desc, texIDDesc, std::move(parameters), rtIDDesc, cacheable, mipMapsStatus));
+        GrGLGpu* gpu, const GrSurfaceDesc& desc, int sampleCount,
+        const GrGLTexture::IDDesc& texIDDesc, sk_sp<GrGLTextureParameters> parameters,
+        const GrGLRenderTarget::IDDesc& rtIDDesc, GrWrapCacheable cacheable,
+        GrMipMapsStatus mipMapsStatus) {
+    return sk_sp<GrGLTextureRenderTarget>(
+            new GrGLTextureRenderTarget(gpu, desc, sampleCount, texIDDesc, std::move(parameters),
+                                        rtIDDesc, cacheable, mipMapsStatus));
 }
 
 size_t GrGLTextureRenderTarget::onGpuMemorySize() const {
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h
index c386822..004a61c 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.h
+++ b/src/gpu/gl/GrGLTextureRenderTarget.h
@@ -27,6 +27,7 @@
     GrGLTextureRenderTarget(GrGLGpu* gpu,
                             SkBudgeted budgeted,
                             const GrSurfaceDesc& desc,
+                            int sampleCount,
                             const GrGLTexture::IDDesc& texIDDesc,
                             const GrGLRenderTarget::IDDesc& rtIDDesc,
                             GrMipMapsStatus);
@@ -36,6 +37,7 @@
     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
 
     static sk_sp<GrGLTextureRenderTarget> MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
+                                                      int sampleCount,
                                                       const GrGLTexture::IDDesc& texIDDesc,
                                                       sk_sp<GrGLTextureParameters> parameters,
                                                       const GrGLRenderTarget::IDDesc& rtIDDesc,
@@ -61,6 +63,7 @@
     // Constructor for instances wrapping backend objects.
     GrGLTextureRenderTarget(GrGLGpu* gpu,
                             const GrSurfaceDesc& desc,
+                            int sampleCount,
                             const GrGLTexture::IDDesc& texIDDesc,
                             sk_sp<GrGLTextureParameters> parameters,
                             const GrGLRenderTarget::IDDesc& rtIDDesc,
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index f7c40c4..5de09e7 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -143,8 +143,9 @@
 }
 
 sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                            SkBudgeted budgeted, GrProtected isProtected,
-                                            const GrMipLevel texels[], int mipLevelCount) {
+                                            int renderTargetSampleCnt, SkBudgeted budgeted,
+                                            GrProtected isProtected, const GrMipLevel texels[],
+                                            int mipLevelCount) {
     if (fMockOptions.fFailTextureAllocations) {
         return nullptr;
     }
@@ -159,7 +160,8 @@
     GrMockTextureInfo texInfo(ct, NextInternalTextureID());
     if (renderable == GrRenderable::kYes) {
         GrMockRenderTargetInfo rtInfo(ct, NextInternalRenderTargetID());
-        return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc, isProtected,
+        return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc,
+                                                              renderTargetSampleCnt, isProtected,
                                                               mipMapsStatus, texInfo, rtInfo));
     }
     return sk_sp<GrTexture>(
@@ -211,8 +213,8 @@
     GrMockRenderTargetInfo rtInfo(texInfo.fColorType, NextInternalRenderTargetID());
 
     auto isProtected = GrProtected(tex.isProtected());
-    return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, desc, isProtected, mipMapsStatus,
-                                                          texInfo, rtInfo, cacheable));
+    return sk_sp<GrTexture>(new GrMockTextureRenderTarget(
+            this, desc, sampleCnt, isProtected, mipMapsStatus, texInfo, rtInfo, cacheable));
 }
 
 sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& rt) {
@@ -225,8 +227,8 @@
     desc.fConfig = info.pixelConfig();
 
     auto isProtected = GrProtected(rt.isProtected());
-    return sk_sp<GrRenderTarget>(
-            new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, isProtected, info));
+    return sk_sp<GrRenderTarget>(new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc,
+                                                        rt.sampleCnt(), isProtected, info));
 }
 
 sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
@@ -238,14 +240,13 @@
     desc.fWidth = tex.width();
     desc.fHeight = tex.height();
     desc.fConfig = texInfo.pixelConfig();
-    desc.fSampleCnt = sampleCnt;
 
     // The client gave us the texture ID but we supply the render target ID.
     GrMockRenderTargetInfo rtInfo(texInfo.fColorType, NextInternalRenderTargetID());
 
     auto isProtected = GrProtected(tex.isProtected());
-    return sk_sp<GrRenderTarget>(
-            new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, isProtected, rtInfo));
+    return sk_sp<GrRenderTarget>(new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc,
+                                                        sampleCnt, isProtected, rtInfo));
 }
 
 sk_sp<GrGpuBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType type,
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 8ba87a9..b001787 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -60,8 +60,9 @@
 
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
 
-    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                     const GrMipLevel[], int mipLevelCount) override;
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                     SkBudgeted, GrProtected, const GrMipLevel[],
+                                     int mipLevelCount) override;
 
     sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, SkImage::CompressionType,
                                                SkBudgeted, const void* data) override;
diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h
index 6a60141..7406ced 100644
--- a/src/gpu/mock/GrMockTexture.h
+++ b/src/gpu/mock/GrMockTexture.h
@@ -76,15 +76,19 @@
 class GrMockRenderTarget : public GrRenderTarget {
 public:
     GrMockRenderTarget(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
-                       GrProtected isProtected, const GrMockRenderTargetInfo& info)
-            : GrSurface(gpu, desc, isProtected), INHERITED(gpu, desc, isProtected), fInfo(info) {
+                       int sampleCnt, GrProtected isProtected, const GrMockRenderTargetInfo& info)
+            : GrSurface(gpu, desc, isProtected)
+            , INHERITED(gpu, desc, sampleCnt, isProtected)
+            , fInfo(info) {
         this->registerWithCache(budgeted);
     }
 
     enum Wrapped { kWrapped };
-    GrMockRenderTarget(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc, GrProtected isProtected,
-                       const GrMockRenderTargetInfo& info)
-            : GrSurface(gpu, desc, isProtected), INHERITED(gpu, desc, isProtected), fInfo(info) {
+    GrMockRenderTarget(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc, int sampleCnt,
+                       GrProtected isProtected, const GrMockRenderTargetInfo& info)
+            : GrSurface(gpu, desc, isProtected)
+            , INHERITED(gpu, desc, sampleCnt, isProtected)
+            , fInfo(info) {
         this->registerWithCacheWrapped(GrWrapCacheable::kNo);
     }
 
@@ -116,9 +120,11 @@
 
 protected:
     // constructor for subclasses
-    GrMockRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc, GrProtected isProtected,
-                       const GrMockRenderTargetInfo& info)
-            : GrSurface(gpu, desc, isProtected), INHERITED(gpu, desc, isProtected), fInfo(info) {}
+    GrMockRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt,
+                       GrProtected isProtected, const GrMockRenderTargetInfo& info)
+            : GrSurface(gpu, desc, isProtected)
+            , INHERITED(gpu, desc, sampleCnt, isProtected)
+            , fInfo(info) {}
 
 private:
     GrMockRenderTargetInfo fInfo;
@@ -130,22 +136,23 @@
 public:
     // Internally created.
     GrMockTextureRenderTarget(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
-                              GrProtected isProtected, GrMipMapsStatus mipMapsStatus,
+                              int sampleCnt, GrProtected isProtected, GrMipMapsStatus mipMapsStatus,
                               const GrMockTextureInfo& texInfo,
                               const GrMockRenderTargetInfo& rtInfo)
             : GrSurface(gpu, desc, isProtected)
             , GrMockTexture(gpu, desc, isProtected, mipMapsStatus, texInfo)
-            , GrMockRenderTarget(gpu, desc, isProtected, rtInfo) {
+            , GrMockRenderTarget(gpu, desc, sampleCnt, isProtected, rtInfo) {
         this->registerWithCache(budgeted);
     }
 
     // Renderable wrapped backend texture.
-    GrMockTextureRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc, GrProtected isProtected,
-                              GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& texInfo,
+    GrMockTextureRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt,
+                              GrProtected isProtected, GrMipMapsStatus mipMapsStatus,
+                              const GrMockTextureInfo& texInfo,
                               const GrMockRenderTargetInfo& rtInfo, GrWrapCacheable cacheble)
             : GrSurface(gpu, desc, isProtected)
             , GrMockTexture(gpu, desc, isProtected, mipMapsStatus, texInfo)
-            , GrMockRenderTarget(gpu, desc, isProtected, rtInfo) {
+            , GrMockRenderTarget(gpu, desc, sampleCnt, isProtected, rtInfo) {
         this->registerWithCacheWrapped(cacheble);
     }
 
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 7024f93..134a391 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -135,7 +135,8 @@
 
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
 
-    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, GrRenderable, SkBudgeted budgeted,
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, GrRenderable,
+                                     int renderTargetSampleCnt, SkBudgeted budgeted,
                                      GrProtected, const GrMipLevel texels[],
                                      int mipLevelCount) override;
     sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, SkImage::CompressionType,
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index d2e12f1..118c95d 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -408,8 +408,9 @@
 }
 
 sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                           SkBudgeted budgeted, GrProtected isProtected,
-                                           const GrMipLevel texels[], int mipLevelCount) {
+                                           int renderTargetSampleCnt, SkBudgeted budgeted,
+                                           GrProtected isProtected, const GrMipLevel texels[],
+                                           int mipLevelCount) {
     // We don't support protected textures in Metal.
     if (isProtected == GrProtected::kYes) {
         return nullptr;
@@ -460,7 +461,8 @@
 
     if (renderable == GrRenderable::kYes) {
         tex = GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(this, budgeted,
-                                                                   desc, texDesc, mipMapsStatus);
+                                                                   desc, renderTargetSampleCnt,
+                                                                   texDesc, mipMapsStatus);
     } else {
         tex = GrMtlTexture::MakeNewTexture(this, budgeted, desc, texDesc, mipMapsStatus);
     }
@@ -516,7 +518,6 @@
     surfaceDesc->fWidth = mtlTexture.width;
     surfaceDesc->fHeight = mtlTexture.height;
     surfaceDesc->fConfig = config;
-    surfaceDesc->fSampleCnt = 1;
 }
 
 sk_sp<GrTexture> GrMtlGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
@@ -546,14 +547,14 @@
     GrSurfaceDesc surfDesc;
     init_surface_desc(&surfDesc, mtlTexture, GrRenderable::kYes, backendTex.config());
 
-    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, colorType,
-                                                                   backendTex.getBackendFormat());
-    if (!surfDesc.fSampleCnt) {
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, colorType,
+                                                         backendTex.getBackendFormat());
+    if (!sampleCnt) {
         return nullptr;
     }
 
-    return GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, mtlTexture,
-                                                                    cacheable);
+    return GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, sampleCnt,
+                                                                    mtlTexture, cacheable);
 }
 
 sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
@@ -569,7 +570,8 @@
     GrSurfaceDesc surfDesc;
     init_surface_desc(&surfDesc, mtlTexture, GrRenderable::kYes, backendRT.config());
 
-    return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, mtlTexture);
+    return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, backendRT.sampleCnt(),
+                                                      mtlTexture);
 }
 
 sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendTextureAsRenderTarget(
@@ -581,12 +583,12 @@
 
     GrSurfaceDesc surfDesc;
     init_surface_desc(&surfDesc, mtlTexture, GrRenderable::kYes, backendTex.config());
-    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, surfDesc.fConfig);
-    if (!surfDesc.fSampleCnt) {
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, surfDesc.fConfig);
+    if (!sampleCnt) {
         return nullptr;
     }
 
-    return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, mtlTexture);
+    return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, sampleCnt, mtlTexture);
 }
 
 bool GrMtlGpu::onRegenerateMipMapLevels(GrTexture* texture) {
diff --git a/src/gpu/mtl/GrMtlRenderTarget.h b/src/gpu/mtl/GrMtlRenderTarget.h
index 5b1377c..e1ab313 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.h
+++ b/src/gpu/mtl/GrMtlRenderTarget.h
@@ -20,6 +20,7 @@
 public:
     static sk_sp<GrMtlRenderTarget> MakeWrappedRenderTarget(GrMtlGpu*,
                                                             const GrSurfaceDesc&,
+                                                            int sampleCnt,
                                                             id<MTLTexture>);
 
     ~GrMtlRenderTarget() override;
@@ -46,6 +47,7 @@
 protected:
     GrMtlRenderTarget(GrMtlGpu* gpu,
                       const GrSurfaceDesc& desc,
+                      int sampleCnt,
                       id<MTLTexture> colorTexture,
                       id<MTLTexture> resolveTexture);
 
@@ -79,6 +81,7 @@
     enum Wrapped { kWrapped };
     GrMtlRenderTarget(GrMtlGpu* gpu,
                       const GrSurfaceDesc& desc,
+                      int sampleCnt,
                       id<MTLTexture> colorTexture,
                       id<MTLTexture> resolveTexture,
                       Wrapped);
diff --git a/src/gpu/mtl/GrMtlRenderTarget.mm b/src/gpu/mtl/GrMtlRenderTarget.mm
index 8e239e3..123715b 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.mm
+++ b/src/gpu/mtl/GrMtlRenderTarget.mm
@@ -17,14 +17,15 @@
 // Called for wrapped non-texture render targets.
 GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
                                      const GrSurfaceDesc& desc,
+                                     int sampleCnt,
                                      id<MTLTexture> colorTexture,
                                      id<MTLTexture> resolveTexture,
                                      Wrapped)
         : GrSurface(gpu, desc, GrProtected::kNo)
-        , GrRenderTarget(gpu, desc, GrProtected::kNo)
+        , GrRenderTarget(gpu, desc, sampleCnt, GrProtected::kNo)
         , fColorTexture(colorTexture)
         , fResolveTexture(resolveTexture) {
-    SkASSERT(desc.fSampleCnt > 1);
+    SkASSERT(sampleCnt > 1);
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
 
@@ -33,44 +34,43 @@
                                      id<MTLTexture> colorTexture,
                                      Wrapped)
         : GrSurface(gpu, desc, GrProtected::kNo)
-        , GrRenderTarget(gpu, desc, GrProtected::kNo)
+        , GrRenderTarget(gpu, desc, 1, GrProtected::kNo)
         , fColorTexture(colorTexture)
         , fResolveTexture(nil) {
-    SkASSERT(1 == desc.fSampleCnt);
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
 
 // Called by subclass constructors.
 GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
                                      const GrSurfaceDesc& desc,
+                                     int sampleCnt,
                                      id<MTLTexture> colorTexture,
                                      id<MTLTexture> resolveTexture)
         : GrSurface(gpu, desc, GrProtected::kNo)
-        , GrRenderTarget(gpu, desc, GrProtected::kNo)
+        , GrRenderTarget(gpu, desc, sampleCnt, GrProtected::kNo)
         , fColorTexture(colorTexture)
         , fResolveTexture(resolveTexture) {
-    SkASSERT(desc.fSampleCnt > 1);
+    SkASSERT(sampleCnt > 1);
 }
 
 GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
                                      const GrSurfaceDesc& desc,
                                      id<MTLTexture> colorTexture)
         : GrSurface(gpu, desc, GrProtected::kNo)
-        , GrRenderTarget(gpu, desc, GrProtected::kNo)
+        , GrRenderTarget(gpu, desc, 1, GrProtected::kNo)
         , fColorTexture(colorTexture)
-        , fResolveTexture(nil) {
-    SkASSERT(1 == desc.fSampleCnt);
-}
+        , fResolveTexture(nil) {}
 
-sk_sp<GrMtlRenderTarget>
-GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu, const GrSurfaceDesc& desc,
-                                           id<MTLTexture> texture) {
+sk_sp<GrMtlRenderTarget> GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu,
+                                                                    const GrSurfaceDesc& desc,
+                                                                    int sampleCnt,
+                                                                    id<MTLTexture> texture) {
     SkASSERT(nil != texture);
     SkASSERT(1 == texture.mipmapLevelCount);
     SkASSERT(MTLTextureUsageRenderTarget & texture.usage);
 
     GrMtlRenderTarget* mtlRT;
-    if (desc.fSampleCnt > 1) {
+    if (sampleCnt > 1) {
         MTLPixelFormat format;
         if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
             return nullptr;
@@ -82,7 +82,7 @@
         texDesc.height = desc.fHeight;
         texDesc.depth = 1;
         texDesc.mipmapLevelCount = 1;
-        texDesc.sampleCount = desc.fSampleCnt;
+        texDesc.sampleCount = sampleCnt;
         texDesc.arrayLength = 1;
         texDesc.storageMode = MTLStorageModePrivate;
         texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
@@ -92,7 +92,7 @@
             return nullptr;
         }
         SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
-        mtlRT = new GrMtlRenderTarget(gpu, desc, colorTexture, texture, kWrapped);
+        mtlRT = new GrMtlRenderTarget(gpu, desc, sampleCnt, colorTexture, texture, kWrapped);
     } else {
         mtlRT = new GrMtlRenderTarget(gpu, desc, texture, kWrapped);
     }
diff --git a/src/gpu/mtl/GrMtlTextureRenderTarget.h b/src/gpu/mtl/GrMtlTextureRenderTarget.h
index da73135..0340e53 100644
--- a/src/gpu/mtl/GrMtlTextureRenderTarget.h
+++ b/src/gpu/mtl/GrMtlTextureRenderTarget.h
@@ -16,11 +16,13 @@
     static sk_sp<GrMtlTextureRenderTarget> MakeNewTextureRenderTarget(GrMtlGpu*,
                                                                       SkBudgeted,
                                                                       const GrSurfaceDesc&,
+                                                                      int sampleCnt,
                                                                       MTLTextureDescriptor*,
                                                                       GrMipMapsStatus);
 
     static sk_sp<GrMtlTextureRenderTarget> MakeWrappedTextureRenderTarget(GrMtlGpu*,
                                                                           const GrSurfaceDesc&,
+                                                                          int sampleCnt,
                                                                           id<MTLTexture>,
                                                                           GrWrapCacheable);
     GrBackendFormat backendFormat() const override {
@@ -42,6 +44,7 @@
     GrMtlTextureRenderTarget(GrMtlGpu* gpu,
                              SkBudgeted budgeted,
                              const GrSurfaceDesc& desc,
+                             int sampleCnt,
                              id<MTLTexture> colorTexture,
                              id<MTLTexture> resolveTexture,
                              GrMipMapsStatus);
@@ -54,6 +57,7 @@
 
     GrMtlTextureRenderTarget(GrMtlGpu* gpu,
                              const GrSurfaceDesc& desc,
+                             int sampleCnt,
                              id<MTLTexture> colorTexture,
                              id<MTLTexture> resolveTexture,
                              GrMipMapsStatus,
diff --git a/src/gpu/mtl/GrMtlTextureRenderTarget.mm b/src/gpu/mtl/GrMtlTextureRenderTarget.mm
index 7c86b61..768b57d 100644
--- a/src/gpu/mtl/GrMtlTextureRenderTarget.mm
+++ b/src/gpu/mtl/GrMtlTextureRenderTarget.mm
@@ -16,12 +16,13 @@
 GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
                                                    SkBudgeted budgeted,
                                                    const GrSurfaceDesc& desc,
+                                                   int sampleCnt,
                                                    id<MTLTexture> colorTexture,
                                                    id<MTLTexture> resolveTexture,
                                                    GrMipMapsStatus mipMapsStatus)
         : GrSurface(gpu, desc, GrProtected::kNo)
         , GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
-        , GrMtlRenderTarget(gpu, desc, colorTexture, resolveTexture) {
+        , GrMtlRenderTarget(gpu, desc, sampleCnt, colorTexture, resolveTexture) {
     this->registerWithCache(budgeted);
 }
 
@@ -38,13 +39,14 @@
 
 GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
                                                    const GrSurfaceDesc& desc,
+                                                   int sampleCnt,
                                                    id<MTLTexture> colorTexture,
                                                    id<MTLTexture> resolveTexture,
                                                    GrMipMapsStatus mipMapsStatus,
                                                    GrWrapCacheable cacheable)
         : GrSurface(gpu, desc, GrProtected::kNo)
         , GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
-        , GrMtlRenderTarget(gpu, desc, colorTexture, resolveTexture) {
+        , GrMtlRenderTarget(gpu, desc, sampleCnt, colorTexture, resolveTexture) {
     this->registerWithCacheWrapped(cacheable);
 }
 
@@ -59,7 +61,7 @@
     this->registerWithCacheWrapped(cacheable);
 }
 
-id<MTLTexture> create_msaa_texture(GrMtlGpu* gpu, const GrSurfaceDesc& desc) {
+id<MTLTexture> create_msaa_texture(GrMtlGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt) {
     MTLPixelFormat format;
     if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
         return nullptr;
@@ -71,7 +73,7 @@
     texDesc.height = desc.fHeight;
     texDesc.depth = 1;
     texDesc.mipmapLevelCount = 1;
-    texDesc.sampleCount = desc.fSampleCnt;
+    texDesc.sampleCount = sampleCnt;
     texDesc.arrayLength = 1;
     texDesc.storageMode = MTLStorageModePrivate;
     texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
@@ -79,27 +81,27 @@
     return [gpu->device() newTextureWithDescriptor:texDesc];
 }
 
-sk_sp<GrMtlTextureRenderTarget>
-GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(GrMtlGpu* gpu,
-                                                     SkBudgeted budgeted,
-                                                     const GrSurfaceDesc& desc,
-                                                     MTLTextureDescriptor* texDesc,
-                                                     GrMipMapsStatus mipMapsStatus) {
+sk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(
+        GrMtlGpu* gpu,
+        SkBudgeted budgeted,
+        const GrSurfaceDesc& desc,
+        int sampleCnt,
+        MTLTextureDescriptor* texDesc,
+        GrMipMapsStatus mipMapsStatus) {
     id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc];
     if (!texture) {
         return nullptr;
     }
     SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
 
-    if (desc.fSampleCnt > 1) {
-        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc);
+    if (sampleCnt > 1) {
+        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc, sampleCnt);
         if (!colorTexture) {
             return nullptr;
         }
         SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
-        return sk_sp<GrMtlTextureRenderTarget>(
-                new GrMtlTextureRenderTarget(gpu, budgeted, desc, colorTexture, texture,
-                                             mipMapsStatus));
+        return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget(
+                gpu, budgeted, desc, sampleCnt, colorTexture, texture, mipMapsStatus));
     } else {
         return sk_sp<GrMtlTextureRenderTarget>(
                 new GrMtlTextureRenderTarget(gpu, budgeted, desc, texture, mipMapsStatus));
@@ -109,6 +111,7 @@
 sk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
         GrMtlGpu* gpu,
         const GrSurfaceDesc& desc,
+        int sampleCnt,
         id<MTLTexture> texture,
         GrWrapCacheable cacheable) {
     SkASSERT(nil != texture);
@@ -116,15 +119,14 @@
     GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1
                                             ? GrMipMapsStatus::kDirty
                                             : GrMipMapsStatus::kNotAllocated;
-    if (desc.fSampleCnt > 1) {
-        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc);
+    if (sampleCnt > 1) {
+        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc, sampleCnt);
         if (!colorTexture) {
             return nullptr;
         }
         SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
-        return sk_sp<GrMtlTextureRenderTarget>(
-                new GrMtlTextureRenderTarget(gpu, desc, colorTexture, texture, mipMapsStatus,
-                                             cacheable));
+        return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget(
+                gpu, desc, sampleCnt, colorTexture, texture, mipMapsStatus, cacheable));
     } else {
         return sk_sp<GrMtlTextureRenderTarget>(
                 new GrMtlTextureRenderTarget(gpu, desc, texture, mipMapsStatus, cacheable));
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index e4625d1..d53f8f9 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -408,7 +408,7 @@
             random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     const GrBackendFormat format =
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
-    auto proxy = context->priv().proxyProvider()->createProxy(format, desc, GrRenderable::kNo,
+    auto proxy = context->priv().proxyProvider()->createProxy(format, desc, GrRenderable::kNo, 1,
                                                               origin, SkBackingFit::kExact,
                                                               SkBudgeted::kYes, GrProtected::kNo);
 
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index a1921fb..8b7d8c1 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -694,7 +694,7 @@
 
     GrProxyProvider* proxyProvider = context->priv().proxyProvider();
     sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-            format, desc, GrRenderable::kNo, origin, mipMapped, fit, SkBudgeted::kNo,
+            format, desc, GrRenderable::kNo, 1, origin, mipMapped, fit, SkBudgeted::kNo,
             GrProtected::kNo, GrInternalSurfaceFlags::kNone);
 
     SkRect rect = GrTest::TestRect(random);
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index a394fc7..38dadc9 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -788,7 +788,6 @@
         surfDesc.fWidth = width;
         surfDesc.fHeight = height;
         surfDesc.fConfig = kRGBA_8888_GrPixelConfig;
-        surfDesc.fSampleCnt = 1;
 
         VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT |
                                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
@@ -950,8 +949,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, GrRenderable renderable,
-                                          SkBudgeted budgeted, GrProtected isProtected,
-                                          const GrMipLevel texels[], int mipLevelCount) {
+                                          int renderTargetSampleCnt, SkBudgeted budgeted,
+                                          GrProtected isProtected, const GrMipLevel texels[],
+                                          int mipLevelCount) {
     VkFormat pixelFormat;
     SkAssertResult(GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat));
 
@@ -996,8 +996,8 @@
 
     sk_sp<GrVkTexture> tex;
     if (renderable == GrRenderable::kYes) {
-        tex = GrVkTextureRenderTarget::MakeNewTextureRenderTarget(this, budgeted, desc, imageDesc,
-                                                                  mipMapsStatus);
+        tex = GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
+                this, budgeted, desc, renderTargetSampleCnt, imageDesc, mipMapsStatus);
     } else {
         tex = GrVkTexture::MakeNewTexture(this, budgeted, desc, imageDesc, mipMapsStatus);
     }
@@ -1189,7 +1189,6 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = 1;
 
     sk_sp<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
     SkASSERT(layout);
@@ -1231,14 +1230,14 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, colorType,
-                                                                   backendTex.getBackendFormat());
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, colorType,
+                                                         backendTex.getBackendFormat());
 
     sk_sp<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
     SkASSERT(layout);
 
     return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
-            this, surfDesc, ownership, cacheable, imageInfo, std::move(layout));
+            this, surfDesc, sampleCnt, ownership, cacheable, imageInfo, std::move(layout));
 }
 
 sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT){
@@ -1270,12 +1269,11 @@
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
-    desc.fSampleCnt = 1;
 
     sk_sp<GrVkImageLayout> layout = backendRT.getGrVkImageLayout();
 
-    sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info,
-                                                                            std::move(layout));
+    sk_sp<GrVkRenderTarget> tgt =
+            GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, 1, info, std::move(layout));
 
     // We don't allow the client to supply a premade stencil buffer. We always create one if needed.
     SkASSERT(!backendRT.stencilBits());
@@ -1308,15 +1306,16 @@
     desc.fWidth = tex.width();
     desc.fHeight = tex.height();
     desc.fConfig = tex.config();
-    desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
-    if (!desc.fSampleCnt) {
+    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
+    if (!sampleCnt) {
         return nullptr;
     }
 
     sk_sp<GrVkImageLayout> layout = tex.getGrVkImageLayout();
     SkASSERT(layout);
 
-    return GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, imageInfo, std::move(layout));
+    return GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, sampleCnt, imageInfo,
+                                                     std::move(layout));
 }
 
 sk_sp<GrRenderTarget> GrVkGpu::onWrapVulkanSecondaryCBAsRenderTarget(
@@ -1345,7 +1344,6 @@
     desc.fWidth = imageInfo.width();
     desc.fHeight = imageInfo.height();
     desc.fConfig = config;
-    desc.fSampleCnt = sampleCnt;
 
     return GrVkRenderTarget::MakeSecondaryCBRenderTarget(this, desc, vkInfo);
 }
@@ -2399,7 +2397,6 @@
         surfDesc.fWidth = width;
         surfDesc.fHeight = height;
         surfDesc.fConfig = kRGBA_8888_GrPixelConfig;
-        surfDesc.fSampleCnt = 1;
 
         VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                                        VK_IMAGE_USAGE_SAMPLED_BIT |
@@ -2418,7 +2415,7 @@
         imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
 
         copySurface = GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
-                this, SkBudgeted::kYes, surfDesc, imageDesc, GrMipMapsStatus::kNotAllocated);
+                this, SkBudgeted::kYes, surfDesc, 1, imageDesc, GrMipMapsStatus::kNotAllocated);
         if (!copySurface) {
             return false;
         }
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 9d782f9..e94274d 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -191,8 +191,9 @@
 
     void destroyResources();
 
-    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, SkBudgeted, GrProtected,
-                                     const GrMipLevel[], int mipLevelCount) override;
+    sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, GrRenderable, int renderTargetSampleCnt,
+                                     SkBudgeted, GrProtected, const GrMipLevel[],
+                                     int mipLevelCount) override;
     sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, SkImage::CompressionType,
                                                SkBudgeted, const void* data) override;
 
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index 28282dd..de73bb7 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -24,6 +24,7 @@
 // constructor must be explicitly called.
 GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
                                    const GrSurfaceDesc& desc,
+                                   int sampleCnt,
                                    const GrVkImageInfo& info,
                                    sk_sp<GrVkImageLayout> layout,
                                    const GrVkImageInfo& msaaInfo,
@@ -33,7 +34,7 @@
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
         // for the moment we only support 1:1 color to stencil
-        , GrRenderTarget(gpu, desc, info.fProtected)
+        , GrRenderTarget(gpu, desc, sampleCnt, info.fProtected)
         , fColorAttachmentView(colorAttachmentView)
         , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout),
                                    GrBackendObjectOwnership::kOwned))
@@ -41,7 +42,7 @@
         , fFramebuffer(nullptr)
         , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(info.fProtected == msaaInfo.fProtected);
-    SkASSERT(desc.fSampleCnt > 1);
+    SkASSERT(sampleCnt > 1);
     this->createFramebuffer(gpu);
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
@@ -50,6 +51,7 @@
 // constructor must be explicitly called.
 GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
                                    const GrSurfaceDesc& desc,
+                                   int sampleCnt,
                                    const GrVkImageInfo& info,
                                    sk_sp<GrVkImageLayout> layout,
                                    const GrVkImageInfo& msaaInfo,
@@ -60,7 +62,7 @@
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, std::move(layout), ownership)
         // for the moment we only support 1:1 color to stencil
-        , GrRenderTarget(gpu, desc, info.fProtected)
+        , GrRenderTarget(gpu, desc, sampleCnt, info.fProtected)
         , fColorAttachmentView(colorAttachmentView)
         , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout),
                                    GrBackendObjectOwnership::kOwned))
@@ -68,7 +70,7 @@
         , fFramebuffer(nullptr)
         , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(info.fProtected == msaaInfo.fProtected);
-    SkASSERT(desc.fSampleCnt > 1);
+    SkASSERT(sampleCnt > 1);
     this->createFramebuffer(gpu);
 }
 
@@ -81,13 +83,12 @@
                                    const GrVkImageView* colorAttachmentView)
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
-        , GrRenderTarget(gpu, desc, info.fProtected)
+        , GrRenderTarget(gpu, desc, 1, info.fProtected)
         , fColorAttachmentView(colorAttachmentView)
         , fMSAAImage(nullptr)
         , fResolveAttachmentView(nullptr)
         , fFramebuffer(nullptr)
         , fCachedSimpleRenderPass(nullptr) {
-    SkASSERT(1 == desc.fSampleCnt);
     this->createFramebuffer(gpu);
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
@@ -102,13 +103,12 @@
                                    GrBackendObjectOwnership ownership)
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, std::move(layout), ownership)
-        , GrRenderTarget(gpu, desc, info.fProtected)
+        , GrRenderTarget(gpu, desc, 1, info.fProtected)
         , fColorAttachmentView(colorAttachmentView)
         , fMSAAImage(nullptr)
         , fResolveAttachmentView(nullptr)
         , fFramebuffer(nullptr)
         , fCachedSimpleRenderPass(nullptr) {
-    SkASSERT(1 == desc.fSampleCnt);
     this->createFramebuffer(gpu);
 }
 
@@ -120,7 +120,7 @@
                                    GrVkSecondaryCommandBuffer* secondaryCommandBuffer)
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed, true)
-        , GrRenderTarget(gpu, desc, info.fProtected)
+        , GrRenderTarget(gpu, desc, 1, info.fProtected)
         , fColorAttachmentView(nullptr)
         , fMSAAImage(nullptr)
         , fResolveAttachmentView(nullptr)
@@ -130,9 +130,11 @@
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
 }
 
-sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(
-        GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info,
-        sk_sp<GrVkImageLayout> layout) {
+sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
+                                                                  const GrSurfaceDesc& desc,
+                                                                  int sampleCnt,
+                                                                  const GrVkImageInfo& info,
+                                                                  sk_sp<GrVkImageLayout> layout) {
     SkASSERT(VK_NULL_HANDLE != info.fImage);
 
     SkASSERT(1 == info.fLevelCount);
@@ -145,14 +147,14 @@
     GrVkImageInfo msInfo;
     sk_sp<GrVkImageLayout> msLayout;
     const GrVkImageView* resolveAttachmentView = nullptr;
-    if (desc.fSampleCnt > 1) {
+    if (sampleCnt > 1) {
         GrVkImage::ImageDesc msImageDesc;
         msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
         msImageDesc.fFormat = pixelFormat;
         msImageDesc.fWidth = desc.fWidth;
         msImageDesc.fHeight = desc.fHeight;
         msImageDesc.fLevels = 1;
-        msImageDesc.fSamples = desc.fSampleCnt;
+        msImageDesc.fSamples = sampleCnt;
         msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
         msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT |
@@ -186,7 +188,7 @@
                                                                      GrVkImageView::kColor_Type, 1,
                                                                      GrVkYcbcrConversionInfo());
     if (!colorAttachmentView) {
-        if (desc.fSampleCnt > 1) {
+        if (sampleCnt > 1) {
             resolveAttachmentView->unref(gpu);
             GrVkImage::DestroyImageInfo(gpu, &msInfo);
         }
@@ -194,8 +196,8 @@
     }
 
     GrVkRenderTarget* vkRT;
-    if (desc.fSampleCnt > 1) {
-        vkRT = new GrVkRenderTarget(gpu, desc, info, std::move(layout), msInfo,
+    if (sampleCnt > 1) {
+        vkRT = new GrVkRenderTarget(gpu, desc, sampleCnt, info, std::move(layout), msInfo,
                                     std::move(msLayout), colorAttachmentView,
                                     resolveAttachmentView);
     } else {
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index fa45e91..23a6fe4 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -34,7 +34,7 @@
 class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage {
 public:
     static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
-                                                           const GrVkImageInfo&,
+                                                           int sampleCnt, const GrVkImageInfo&,
                                                            sk_sp<GrVkImageLayout>);
 
     static sk_sp<GrVkRenderTarget> MakeSecondaryCBRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
@@ -97,6 +97,7 @@
 protected:
     GrVkRenderTarget(GrVkGpu* gpu,
                      const GrSurfaceDesc& desc,
+                     int sampleCnt,
                      const GrVkImageInfo& info,
                      sk_sp<GrVkImageLayout> layout,
                      const GrVkImageInfo& msaaInfo,
@@ -137,6 +138,7 @@
 private:
     GrVkRenderTarget(GrVkGpu* gpu,
                      const GrSurfaceDesc& desc,
+                     int sampleCnt,
                      const GrVkImageInfo& info,
                      sk_sp<GrVkImageLayout> layout,
                      const GrVkImageInfo& msaaInfo,
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index dff2301..dc93aaa 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -21,6 +21,7 @@
 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
                                                  SkBudgeted budgeted,
                                                  const GrSurfaceDesc& desc,
+                                                 int sampleCnt,
                                                  const GrVkImageInfo& info,
                                                  sk_sp<GrVkImageLayout> layout,
                                                  const GrVkImageView* texView,
@@ -33,7 +34,7 @@
         , GrVkImage(info, layout, GrBackendObjectOwnership::kOwned)
         , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus,
                       GrBackendObjectOwnership::kOwned)
-        , GrVkRenderTarget(gpu, desc, info, layout, msaaInfo, std::move(msaaLayout),
+        , GrVkRenderTarget(gpu, desc, sampleCnt, info, layout, msaaInfo, std::move(msaaLayout),
                            colorAttachmentView, resolveAttachmentView,
                            GrBackendObjectOwnership::kOwned) {
     SkASSERT(info.fProtected == msaaInfo.fProtected);
@@ -59,6 +60,7 @@
 
 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
                                                  const GrSurfaceDesc& desc,
+                                                 int sampleCnt,
                                                  const GrVkImageInfo& info,
                                                  sk_sp<GrVkImageLayout> layout,
                                                  const GrVkImageView* texView,
@@ -72,7 +74,7 @@
         : GrSurface(gpu, desc, info.fProtected)
         , GrVkImage(info, layout, ownership)
         , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership)
-        , GrVkRenderTarget(gpu, desc, info, layout, msaaInfo, std::move(msaaLayout),
+        , GrVkRenderTarget(gpu, desc, sampleCnt, info, layout, msaaInfo, std::move(msaaLayout),
                            colorAttachmentView, resolveAttachmentView, ownership) {
     SkASSERT(info.fProtected == msaaInfo.fProtected);
     this->registerWithCacheWrapped(cacheable);
@@ -104,7 +106,8 @@
 };
 }  // anonymous namespace
 
-static Views create_views(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info) {
+static Views create_views(GrVkGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt,
+                          const GrVkImageInfo& info) {
     VkImage image = info.fImage;
     // Create the texture ImageView
     Views views;
@@ -120,14 +123,14 @@
     VkImage colorImage;
 
     // create msaa surface if necessary
-    if (desc.fSampleCnt > 1) {
+    if (sampleCnt > 1) {
         GrVkImage::ImageDesc msImageDesc;
         msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
         msImageDesc.fFormat = pixelFormat;
         msImageDesc.fWidth = desc.fWidth;
         msImageDesc.fHeight = desc.fHeight;
         msImageDesc.fLevels = 1;
-        msImageDesc.fSamples = desc.fSampleCnt;
+        msImageDesc.fSamples = sampleCnt;
         msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
         msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT |
@@ -160,7 +163,7 @@
     views.colorAttachmentView = GrVkImageView::Create(
             gpu, colorImage, pixelFormat, GrVkImageView::kColor_Type, 1, GrVkYcbcrConversionInfo());
     if (!views.colorAttachmentView) {
-        if (desc.fSampleCnt > 1) {
+        if (sampleCnt > 1) {
             views.resolveAttachmentView->unref(gpu);
             GrVkImage::DestroyImageInfo(gpu, &views.msInfo);
         }
@@ -170,12 +173,13 @@
     return views;
 }
 
-sk_sp<GrVkTextureRenderTarget>
-GrVkTextureRenderTarget::MakeNewTextureRenderTarget(GrVkGpu* gpu,
-                                                    SkBudgeted budgeted,
-                                                    const GrSurfaceDesc& desc,
-                                                    const GrVkImage::ImageDesc& imageDesc,
-                                                    GrMipMapsStatus mipMapsStatus) {
+sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
+        GrVkGpu* gpu,
+        SkBudgeted budgeted,
+        const GrSurfaceDesc& desc,
+        int sampleCnt,
+        const GrVkImage::ImageDesc& imageDesc,
+        GrMipMapsStatus mipMapsStatus) {
     SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
     SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
 
@@ -185,16 +189,16 @@
     }
     sk_sp<GrVkImageLayout> layout(new GrVkImageLayout(info.fImageLayout));
 
-    Views views = create_views(gpu, desc, info);
+    Views views = create_views(gpu, desc, sampleCnt, info);
     if (!views.colorAttachmentView) {
         GrVkImage::DestroyImageInfo(gpu, &info);
         return nullptr;
     }
-    if (desc.fSampleCnt > 1) {
+    if (sampleCnt > 1) {
         return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, budgeted, desc, info, std::move(layout), views.imageView, views.msInfo,
-                std::move(views.msLayout), views.colorAttachmentView, views.resolveAttachmentView,
-                mipMapsStatus));
+                gpu, budgeted, desc, sampleCnt, info, std::move(layout), views.imageView,
+                views.msInfo, std::move(views.msLayout), views.colorAttachmentView,
+                views.resolveAttachmentView, mipMapsStatus));
     } else {
         return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
                 gpu, budgeted, desc, info, std::move(layout), views.imageView,
@@ -205,6 +209,7 @@
 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
         GrVkGpu* gpu,
         const GrSurfaceDesc& desc,
+        int sampleCnt,
         GrWrapOwnership wrapOwnership,
         GrWrapCacheable cacheable,
         const GrVkImageInfo& info,
@@ -218,13 +223,13 @@
 
     GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
             ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
-    Views views = create_views(gpu, desc, info);
+    Views views = create_views(gpu, desc, sampleCnt, info);
     if (!views.colorAttachmentView) {
         return nullptr;
     }
-    if (desc.fSampleCnt > 1) {
+    if (sampleCnt > 1) {
         return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, desc, info, std::move(layout), views.imageView, views.msInfo,
+                gpu, desc, sampleCnt, info, std::move(layout), views.imageView, views.msInfo,
                 std::move(views.msLayout), views.colorAttachmentView, views.resolveAttachmentView,
                 mipMapsStatus, ownership, cacheable));
     } else {
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index 67d6f0e..0771431 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -28,11 +28,13 @@
 public:
     static sk_sp<GrVkTextureRenderTarget> MakeNewTextureRenderTarget(GrVkGpu*, SkBudgeted,
                                                                      const GrSurfaceDesc&,
+                                                                     int sampleCnt,
                                                                      const GrVkImage::ImageDesc&,
                                                                      GrMipMapsStatus);
 
     static sk_sp<GrVkTextureRenderTarget> MakeWrappedTextureRenderTarget(GrVkGpu*,
                                                                          const GrSurfaceDesc&,
+                                                                         int sampleCnt,
                                                                          GrWrapOwnership,
                                                                          GrWrapCacheable,
                                                                          const GrVkImageInfo&,
@@ -58,6 +60,7 @@
     GrVkTextureRenderTarget(GrVkGpu* gpu,
                             SkBudgeted budgeted,
                             const GrSurfaceDesc& desc,
+                            int sampleCnt,
                             const GrVkImageInfo& info,
                             sk_sp<GrVkImageLayout> layout,
                             const GrVkImageView* texView,
@@ -80,6 +83,7 @@
     // MSAA, wrapped
     GrVkTextureRenderTarget(GrVkGpu* gpu,
                             const GrSurfaceDesc& desc,
+                            int sampleCnt,
                             const GrVkImageInfo& info,
                             sk_sp<GrVkImageLayout> layout,
                             const GrVkImageView* texView,
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index fd863ac..830c7eb 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -491,7 +491,7 @@
     // We pass kReadOnly here since we should treat content of the client's texture as immutable.
     // The promise API provides no way for the client to indicated that the texture is protected.
     return proxyProvider->createLazyProxy(
-            std::move(callback), backendFormat, desc, GrRenderable::kNo, origin, mipMapped,
+            std::move(callback), backendFormat, desc, GrRenderable::kNo, 1, origin, mipMapped,
             GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
             GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kDeinstantiate);
 }
diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp
index c1c5439..a81a68f 100644
--- a/tests/BlendTest.cpp
+++ b/tests/BlendTest.cpp
@@ -95,11 +95,10 @@
     backingDesc.fWidth = width;
     backingDesc.fHeight = height;
     backingDesc.fConfig = config;
-    backingDesc.fSampleCnt = sampleCnt;
 
     auto resourceProvider = context->priv().resourceProvider();
 
-    *backingSurface = resourceProvider->createTexture(backingDesc, GrRenderable::kYes,
+    *backingSurface = resourceProvider->createTexture(backingDesc, GrRenderable::kYes, sampleCnt,
                                                       SkBudgeted::kNo, GrProtected::kNo,
                                                       GrResourceProvider::Flags::kNoPendingIO);
     if (!(*backingSurface)) {
diff --git a/tests/DetermineDomainModeTest.cpp b/tests/DetermineDomainModeTest.cpp
index fd3cf74..b01f1b4 100644
--- a/tests/DetermineDomainModeTest.cpp
+++ b/tests/DetermineDomainModeTest.cpp
@@ -146,7 +146,7 @@
               (isPowerOfTwo || isExact) ? RectInfo::kHard : RectInfo::kBad,
               name);
 
-    return proxyProvider->createProxy(format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin,
+    return proxyProvider->createProxy(format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin,
                                       fit, SkBudgeted::kYes, GrProtected::kNo);
 }
 
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 0c1d155..2d3edc9 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -273,7 +273,7 @@
         dummyDesc.fConfig = kRGBA_8888_GrPixelConfig;
         const GrBackendFormat format =
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
-        proxies[0] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kYes,
+        proxies[0] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kYes, 1,
                                                 kBottomLeft_GrSurfaceOrigin, mipMapped,
                                                 SkBackingFit::kExact, SkBudgeted::kNo,
                                                 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
@@ -285,7 +285,7 @@
         dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
         const GrBackendFormat format =
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kAlpha_8);
-        proxies[1] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kNo,
+        proxies[1] = proxyProvider->createProxy(format, dummyDesc, GrRenderable::kNo, 1,
                                                 kTopLeft_GrSurfaceOrigin, mipMapped,
                                                 SkBackingFit::kExact, SkBudgeted::kNo,
                                                 GrProtected::kNo, GrInternalSurfaceFlags::kNone);
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index c951c32..726f8fb 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -32,9 +32,8 @@
     desc.fWidth = 256;
     desc.fHeight = 256;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = 1;
     sk_sp<GrSurface> texRT1 = resourceProvider->createTexture(
-            desc, GrRenderable::kYes, SkBudgeted::kNo, GrProtected::kNo,
+            desc, GrRenderable::kYes, 1, SkBudgeted::kNo, GrProtected::kNo,
             GrResourceProvider::Flags::kNoPendingIO);
 
     REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asRenderTarget());
@@ -47,7 +46,7 @@
                     static_cast<GrSurface*>(texRT1->asTexture()));
 
     sk_sp<GrTexture> tex1 = resourceProvider->createTexture(
-            desc, GrRenderable::kNo, SkBudgeted::kNo, GrProtected::kNo,
+            desc, GrRenderable::kNo, 1, SkBudgeted::kNo, GrProtected::kNo,
             GrResourceProvider::Flags::kNoPendingIO);
     REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
     REPORTER_ASSERT(reporter, tex1.get() == tex1->asTexture());
@@ -108,8 +107,7 @@
             desc.fWidth = width;
             desc.fHeight = height;
             desc.fConfig = config;
-            desc.fSampleCnt = 1;
-            return rp->createTexture(desc, renderable, SkBudgeted::kNo, GrProtected::kNo,
+            return rp->createTexture(desc, renderable, 1, SkBudgeted::kNo, GrProtected::kNo,
                                      GrResourceProvider::Flags::kNoPendingIO);
         }
     };
@@ -160,16 +158,15 @@
             desc.fWidth = kW;
             desc.fHeight = kH;
             desc.fConfig = config;
-            desc.fSampleCnt = 1;
 
             sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(
-                    format, desc, GrRenderable::kNo, origin, SkBudgeted::kNo, GrProtected::kNo);
+                    format, desc, GrRenderable::kNo, 1, origin, SkBudgeted::kNo, GrProtected::kNo);
             REPORTER_ASSERT(reporter,
                             SkToBool(proxy.get()) ==
                                     (caps->isConfigTexturable(desc.fConfig) &&
                                      caps->mipMapSupport() && !GrPixelConfigIsCompressed(config)));
 
-            tex = resourceProvider->createTexture(desc, GrRenderable::kYes, SkBudgeted::kNo,
+            tex = resourceProvider->createTexture(desc, GrRenderable::kYes, 1, SkBudgeted::kNo,
                                                   GrProtected::kNo,
                                                   GrResourceProvider::Flags::kNoPendingIO);
             bool isRenderable = caps->isConfigRenderable(config);
@@ -177,8 +174,7 @@
                             "config:%d, tex:%d, isRenderable:%d", config, SkToBool(tex),
                             isRenderable);
 
-            desc.fSampleCnt = 2;
-            tex = resourceProvider->createTexture(desc, GrRenderable::kYes, SkBudgeted::kNo,
+            tex = resourceProvider->createTexture(desc, GrRenderable::kYes, 2, SkBudgeted::kNo,
                                                   GrProtected::kNo,
                                                   GrResourceProvider::Flags::kNoPendingIO);
             isRenderable = SkToBool(caps->getRenderTargetSampleCount(2, config));
@@ -227,7 +223,8 @@
                      {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
                     for (auto fit : {SkBackingFit::kApprox, SkBackingFit::kExact}) {
                         auto proxy = proxyProvider->testingOnly_createInstantiatedProxy(
-                                desc, renderable, origin, fit, SkBudgeted::kYes, GrProtected::kNo);
+                                desc, renderable, 1, origin, fit, SkBudgeted::kYes,
+                                GrProtected::kNo);
                         if (!proxy) {
                             continue;
                         }
@@ -286,8 +283,8 @@
                             sk_sp<GrSurfaceContext> surfCtx;
                             if (renderable == GrRenderable::kYes) {
                                 surfCtx = context->priv().makeDeferredRenderTargetContext(
-                                        fit, desc.fWidth, desc.fHeight, colorType, nullptr,
-                                        desc.fSampleCnt, GrMipMapped::kNo, origin, nullptr);
+                                        fit, desc.fWidth, desc.fHeight, colorType, nullptr, 1,
+                                        GrMipMapped::kNo, origin, nullptr);
                             } else {
                                 surfCtx = context->priv().makeDeferredTextureContext(
                                         fit, desc.fWidth, desc.fHeight, colorType,
@@ -455,7 +452,7 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
     desc.fWidth = desc.fHeight = kSurfSize;
     return context->priv().resourceProvider()->createTexture(
-            desc, renderable, SkBudgeted::kNo, GrProtected::kNo,
+            desc, renderable, 1, SkBudgeted::kNo, GrProtected::kNo,
             GrResourceProvider::Flags::kNoPendingIO);
 }
 
@@ -553,7 +550,7 @@
                     budgeted = SkBudgeted::kNo;
                 }
                 auto proxy = context->priv().proxyProvider()->createLazyProxy(
-                        singleUseLazyCB, backendFormat, desc, renderable,
+                        singleUseLazyCB, backendFormat, desc, renderable, 1,
                         GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                         GrInternalSurfaceFlags ::kNone, SkBackingFit::kExact, budgeted,
                         GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kSingleUse);
@@ -590,7 +587,7 @@
                     return GrSurfaceProxy::LazyInstantiationResult{std::move(texture), mode};
                 };
                 proxy = context->priv().proxyProvider()->createLazyProxy(
-                        deinstantiateLazyCB, backendFormat, desc, renderable,
+                        deinstantiateLazyCB, backendFormat, desc, renderable, 1,
                         GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                         GrInternalSurfaceFlags ::kNone, SkBackingFit::kExact, budgeted,
                         GrProtected::kNo, GrSurfaceProxy::LazyInstantiationType::kDeinstantiate);
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index 58a9c1e..3764c7c 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -96,14 +96,14 @@
                             desc.fHeight = 567;
                             desc.fConfig = kRGB_565_GrPixelConfig;
                             sk_sp<GrTexture> texture = rp->createTexture(
-                                    desc, GrRenderable::kNo, SkBudgeted::kYes, GrProtected::kNo,
+                                    desc, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
                                     GrResourceProvider::Flags::kNoPendingIO);
                             REPORTER_ASSERT(fTest->fReporter, texture);
                             return std::move(texture);
                         }
                     },
-                    format, GrProxyProvider::Renderable::kNo, GrProtected::kNo,
-                    kTopLeft_GrSurfaceOrigin, kRGB_565_GrPixelConfig, *proxyProvider->caps());
+                    format, GrRenderable::kNo, 1, GrProtected::kNo, kTopLeft_GrSurfaceOrigin,
+                    kRGB_565_GrPixelConfig, *proxyProvider->caps());
 
             this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
                             GrOp::IsZeroArea::kNo);
@@ -139,8 +139,8 @@
                         fAtlas->instantiate(rp);
                         return sk_ref_sp(fAtlas->peekTexture());
                     },
-                    format, GrProxyProvider::Renderable::kYes, GrProtected::kNo,
-                    kBottomLeft_GrSurfaceOrigin, kAlpha_half_GrPixelConfig, *proxyProvider->caps());
+                    format, GrRenderable::kYes, 1, GrProtected::kNo, kBottomLeft_GrSurfaceOrigin,
+                    kAlpha_half_GrPixelConfig, *proxyProvider->caps());
             fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
                           GrSamplerState::WrapMode::kClamp);
             this->setTextureSamplerCnt(1);
@@ -265,7 +265,7 @@
                 int* fValue = nullptr;
             };
             sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
-                    TestCallback(&testCount), format, desc, GrRenderable::kNo,
+                    TestCallback(&testCount), format, desc, GrRenderable::kNo, 1,
                     kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
                     SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, lazyType);
 
@@ -331,12 +331,12 @@
                         *testExecuteValue = 1;
                         return {};
                     }
-                    return {rp->createTexture(desc, GrRenderable::kNo, SkBudgeted::kNo,
+                    return {rp->createTexture(desc, GrRenderable::kNo, 1, SkBudgeted::kNo,
                                               GrProtected::kNo,
                                               GrResourceProvider::Flags::kNoPendingIO),
                             GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
                 },
-                format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+                format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                 SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo);
 
         SkASSERT(fLazyProxy.get());
@@ -472,7 +472,7 @@
                     texture->setRelease(DeinstantiateReleaseProc, releasePtr);
                     return std::move(texture);
                 },
-                format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+                format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
                 GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
                 GrProtected::kNo, lazyType);
 
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index fbb73ec..8502724 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -314,12 +314,13 @@
                     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
                     auto texture = resourceProvider->createTexture(
-                            desc, GrRenderable::kYes, SkBudgeted::kYes, GrProtected::kNo,
+                            desc, GrRenderable::kYes, 1, SkBudgeted::kYes, GrProtected::kNo,
                             GrResourceProvider::Flags::kNoPendingIO);
                     return std::move(texture);
                 },
                 format,
-                GrProxyProvider::Renderable::kYes,
+                GrRenderable::kYes,
+                1,
                 GrProtected::kNo,
                 kBottomLeft_GrSurfaceOrigin,
                 kRGBA_8888_GrPixelConfig,
diff --git a/tests/OpChainTest.cpp b/tests/OpChainTest.cpp
index 587bb25..f650149 100644
--- a/tests/OpChainTest.cpp
+++ b/tests/OpChainTest.cpp
@@ -171,7 +171,7 @@
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
 
     auto proxy = context->priv().proxyProvider()->createProxy(
-            format, desc, GrRenderable::kYes, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+            format, desc, GrRenderable::kYes, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
             SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, GrInternalSurfaceFlags::kNone);
     SkASSERT(proxy);
     proxy->instantiate(context->priv().resourceProvider());
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index 0caf47f..15ae0a5 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -178,7 +178,7 @@
                             SkBackingFit::kApprox, 1, 1, GrColorType::kRGBA_8888, nullptr));
             {
                 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                        format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin,
+                        format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin,
                         SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
 
                 {
diff --git a/tests/PromiseImageTest.cpp b/tests/PromiseImageTest.cpp
index 4c38672..625abff 100644
--- a/tests/PromiseImageTest.cpp
+++ b/tests/PromiseImageTest.cpp
@@ -424,7 +424,7 @@
         desc.fConfig = kRGBA_8888_GrPixelConfig;
         desc.fWidth = desc.fHeight = 100;
         textures[i] = ctx->priv().resourceProvider()->createTexture(
-                desc, GrRenderable::kNo, SkBudgeted::kYes, GrProtected::kNo,
+                desc, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
                 GrResourceProvider::Flags::kNoPendingIO);
         REPORTER_ASSERT(reporter, textures[i]);
     }
diff --git a/tests/ProxyConversionTest.cpp b/tests/ProxyConversionTest.cpp
index 5ef0a09..878d104 100644
--- a/tests/ProxyConversionTest.cpp
+++ b/tests/ProxyConversionTest.cpp
@@ -24,8 +24,6 @@
                                              skiatest::Reporter* reporter,
                                              const GrSurfaceDesc& desc,
                                              GrSurfaceOrigin origin) {
-    // We don't currently have a way of making MSAA backend render targets.
-    SkASSERT(1 == desc.fSampleCnt);
     auto ct = GrPixelConfigToColorType(desc.fConfig);
     auto backendRT = gpu->createTestingOnlyBackendRenderTarget(desc.fWidth, desc.fHeight, ct);
     return provider->wrapBackendRenderTarget(backendRT, origin, nullptr, nullptr);
@@ -42,7 +40,7 @@
 static sk_sp<GrSurfaceProxy> make_offscreen_rt(GrProxyProvider* provider,
                                                const GrSurfaceDesc& desc,
                                                GrSurfaceOrigin origin) {
-    return provider->testingOnly_createInstantiatedProxy(desc, GrRenderable::kYes, origin,
+    return provider->testingOnly_createInstantiatedProxy(desc, GrRenderable::kYes, 1, origin,
                                                          SkBackingFit::kExact, SkBudgeted::kYes,
                                                          GrProtected::kNo);
 }
@@ -52,7 +50,7 @@
                                           GrRenderable renderable,
                                           GrSurfaceOrigin origin) {
     return provider->testingOnly_createInstantiatedProxy(
-            desc, renderable, origin, SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
+            desc, renderable, 1, origin, SkBackingFit::kExact, SkBudgeted::kYes, GrProtected::kNo);
 }
 
 // Test converting between RenderTargetProxies and TextureProxies for preinstantiated Proxies
@@ -138,7 +136,7 @@
                     GrColorType::kRGBA_8888);
     {
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                format, desc, GrRenderable::kYes, kBottomLeft_GrSurfaceOrigin,
+                format, desc, GrRenderable::kYes, 1, kBottomLeft_GrSurfaceOrigin,
                 SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
 
         // Both RenderTarget and Texture
@@ -152,7 +150,7 @@
 
     {
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                format, desc, GrRenderable::kYes, kBottomLeft_GrSurfaceOrigin,
+                format, desc, GrRenderable::kYes, 1, kBottomLeft_GrSurfaceOrigin,
                 SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
 
         // Both RenderTarget and Texture - but via GrTextureProxy
@@ -166,7 +164,7 @@
 
     {
         sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
+                format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
                 SkBudgeted::kYes, GrProtected::kNo);
         // Texture-only
         GrTextureProxy* tProxy = proxy->asTextureProxy();
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp
index 357fe3e..8123864 100644
--- a/tests/ProxyRefTest.cpp
+++ b/tests/ProxyRefTest.cpp
@@ -41,8 +41,9 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
     const GrBackendFormat format = caps->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
-    return proxyProvider->createProxy(format, desc, GrRenderable::kYes, kBottomLeft_GrSurfaceOrigin,
-                                      SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
+    return proxyProvider->createProxy(format, desc, GrRenderable::kYes, 1,
+                                      kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
+                                      SkBudgeted::kYes, GrProtected::kNo);
 }
 
 static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider, const GrCaps* caps) {
@@ -52,7 +53,7 @@
     desc.fConfig = kRGBA_8888_GrPixelConfig;
 
     return proxyProvider->testingOnly_createInstantiatedProxy(
-            desc, GrRenderable::kYes, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kExact,
+            desc, GrRenderable::kYes, 1, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kExact,
             SkBudgeted::kNo, GrProtected::kNo);
 }
 
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 1360f8b..bce4eb4 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -124,7 +124,6 @@
                             desc.fWidth = widthHeight;
                             desc.fHeight = widthHeight;
                             desc.fConfig = config;
-                            desc.fSampleCnt = numSamples;
 
                             const GrBackendFormat format = caps.getBackendFormatFromColorType(ct);
                             if (!format.isValid()) {
@@ -136,17 +135,18 @@
                                 sk_sp<GrTexture> tex;
                                 if (SkBackingFit::kApprox == fit) {
                                     tex = resourceProvider->createApproxTexture(
-                                            desc, GrRenderable::kYes, GrProtected::kNo,
+                                            desc, GrRenderable::kYes, numSamples, GrProtected::kNo,
                                             GrResourceProvider::Flags::kNoPendingIO);
                                 } else {
                                     tex = resourceProvider->createTexture(
-                                            desc, GrRenderable::kYes, budgeted, GrProtected::kNo,
+                                            desc, GrRenderable::kYes, numSamples, budgeted,
+                                            GrProtected::kNo,
                                             GrResourceProvider::Flags::kNoPendingIO);
                                 }
 
                                 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
-                                        format, desc, GrRenderable::kYes, origin, fit, budgeted,
-                                        GrProtected::kNo);
+                                        format, desc, GrRenderable::kYes, numSamples, origin, fit,
+                                        budgeted, GrProtected::kNo);
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     REPORTER_ASSERT(reporter, proxy->asRenderTargetProxy());
@@ -173,17 +173,18 @@
                                 sk_sp<GrTexture> tex;
                                 if (SkBackingFit::kApprox == fit) {
                                     tex = resourceProvider->createApproxTexture(
-                                            desc, GrRenderable::kNo, GrProtected::kNo,
+                                            desc, GrRenderable::kNo, numSamples, GrProtected::kNo,
                                             GrResourceProvider::Flags::kNoPendingIO);
                                 } else {
                                     tex = resourceProvider->createTexture(
-                                            desc, GrRenderable::kNo, budgeted, GrProtected::kNo,
+                                            desc, GrRenderable::kNo, numSamples, budgeted,
+                                            GrProtected::kNo,
                                             GrResourceProvider::Flags::kNoPendingIO);
                                 }
 
                                 sk_sp<GrTextureProxy> proxy(proxyProvider->createProxy(
-                                        format, desc, GrRenderable::kNo, origin, fit, budgeted,
-                                        GrProtected::kNo));
+                                        format, desc, GrRenderable::kNo, numSamples, origin, fit,
+                                        budgeted, GrProtected::kNo));
                                 REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
                                 if (proxy) {
                                     // This forces the proxy to compute and cache its
@@ -377,14 +378,13 @@
                     desc.fWidth = width;
                     desc.fHeight = height;
                     desc.fConfig = kRGBA_8888_GrPixelConfig;
-                    desc.fSampleCnt = 1;
 
                     const GrBackendFormat format =
                         ctxInfo.grContext()->priv().caps()->getBackendFormatFromColorType(
                                 GrColorType::kRGBA_8888);
 
                     sk_sp<GrTextureProxy> proxy = provider->createProxy(
-                            format, desc, renderable, kBottomLeft_GrSurfaceOrigin, fit,
+                            format, desc, renderable, 1, kBottomLeft_GrSurfaceOrigin, fit,
                             SkBudgeted::kNo, GrProtected::kNo);
                     REPORTER_ASSERT(reporter, !proxy);
                 }
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index 692e774..dee8de8 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -41,12 +41,11 @@
     desc.fWidth  = p.fSize;
     desc.fHeight = p.fSize;
     desc.fConfig = config;
-    desc.fSampleCnt = p.fSampleCnt;
 
     const GrBackendFormat format = caps->getBackendFormatFromColorType(grCT);
 
-    return proxyProvider->createProxy(format, desc, p.fRenderable, p.fOrigin, p.fFit, p.fBudgeted,
-                                      GrProtected::kNo);
+    return proxyProvider->createProxy(format, desc, p.fRenderable, p.fSampleCnt, p.fOrigin, p.fFit,
+                                      p.fBudgeted, GrProtected::kNo);
 }
 
 static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
@@ -163,9 +162,9 @@
         //----------------------------------------------------------------------------------------
         // Two proxies with overlapping intervals and compatible descriptors should never share
         // RT version
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, kDontShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, kDontShare },
         // non-RT version
-        { { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, kDontShare },
+        { { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, kDontShare },
     };
 
     for (auto test : gOverlappingTests) {
@@ -184,28 +183,28 @@
         //----------------------------------------------------------------------------------------
         // Two non-overlapping intervals w/ compatible proxies should share
         // both same size & approx
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, kShare },
-        { { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, kConditionallyShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, kShare },
+        { { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, kConditionallyShare },
         // diffs sizes but still approx
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 50,    kRT, kRGBA, kA, 0, kTL, kNotB }, kShare },
-        { { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, { 50, kNotRT, kRGBA, kA, 0, kTL, kNotB }, kConditionallyShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 50,    kRT, kRGBA, kA, 1, kTL, kNotB }, kShare },
+        { { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, { 50, kNotRT, kRGBA, kA, 1, kTL, kNotB }, kConditionallyShare },
         // sames sizes but exact
-        { { 64,    kRT, kRGBA, kE, 0, kTL, kNotB }, { 64,    kRT, kRGBA, kE, 0, kTL, kNotB }, kShare },
-        { { 64, kNotRT, kRGBA, kE, 0, kTL, kNotB }, { 64, kNotRT, kRGBA, kE, 0, kTL, kNotB }, kConditionallyShare },
+        { { 64,    kRT, kRGBA, kE, 1, kTL, kNotB }, { 64,    kRT, kRGBA, kE, 1, kTL, kNotB }, kShare },
+        { { 64, kNotRT, kRGBA, kE, 1, kTL, kNotB }, { 64, kNotRT, kRGBA, kE, 1, kTL, kNotB }, kConditionallyShare },
         //----------------------------------------------------------------------------------------
         // Two non-overlapping intervals w/ different exact sizes should not share
-        { { 56,    kRT, kRGBA, kE, 0, kTL, kNotB }, { 54,    kRT, kRGBA, kE, 0, kTL, kNotB }, kDontShare },
+        { { 56,    kRT, kRGBA, kE, 1, kTL, kNotB }, { 54,    kRT, kRGBA, kE, 1, kTL, kNotB }, kDontShare },
         // Two non-overlapping intervals w/ _very different_ approx sizes should not share
-        { { 255,   kRT, kRGBA, kA, 0, kTL, kNotB }, { 127,   kRT, kRGBA, kA, 0, kTL, kNotB }, kDontShare },
+        { { 255,   kRT, kRGBA, kA, 1, kTL, kNotB }, { 127,   kRT, kRGBA, kA, 1, kTL, kNotB }, kDontShare },
         // Two non-overlapping intervals w/ different MSAA sample counts should not share
         { { 64,    kRT, kRGBA, kA, k2, kTL, kNotB },{ 64,    kRT, kRGBA, kA, k4,kTL, kNotB}, k2 == k4 },
         // Two non-overlapping intervals w/ different configs should not share
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 64,    kRT, kBGRA, kA, 0, kTL, kNotB }, kDontShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 64,    kRT, kBGRA, kA, 1, kTL, kNotB }, kDontShare },
         // Two non-overlapping intervals w/ different RT classifications should never share
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, kDontShare },
-        { { 64, kNotRT, kRGBA, kA, 0, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, kDontShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, kDontShare },
+        { { 64, kNotRT, kRGBA, kA, 1, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, kDontShare },
         // Two non-overlapping intervals w/ different origins should share
-        { { 64,    kRT, kRGBA, kA, 0, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 0, kBL, kNotB }, kShare },
+        { { 64,    kRT, kRGBA, kA, 1, kTL, kNotB }, { 64,    kRT, kRGBA, kA, 1, kBL, kNotB }, kShare },
     };
 
     for (auto test : gNonOverlappingTests) {
@@ -223,7 +222,7 @@
     {
         // Wrapped backend textures should never be reused
         TestCase t[1] = {
-            { { 64, kNotRT, kRGBA, kE, 0, kTL, kNotB }, { 64, kNotRT, kRGBA, kE, 0, kTL, kNotB }, kDontShare }
+            { { 64, kNotRT, kRGBA, kE, 1, kTL, kNotB }, { 64, kNotRT, kRGBA, kE, 1, kTL, kNotB }, kDontShare }
         };
 
         GrBackendTexture backEndTex;
@@ -276,17 +275,17 @@
     desc.fWidth = p.fSize;
     desc.fHeight = p.fSize;
     desc.fConfig = config;
-    desc.fSampleCnt = p.fSampleCnt;
 
     SkBackingFit fit = p.fFit;
-    auto callback = [fit, desc, renderable = p.fRenderable](GrResourceProvider* resourceProvider) {
+    auto callback = [fit, desc, p](GrResourceProvider* resourceProvider) {
         sk_sp<GrTexture> texture;
         if (fit == SkBackingFit::kApprox) {
             texture = resourceProvider->createApproxTexture(
-                    desc, renderable, GrProtected::kNo, GrResourceProvider::Flags::kNoPendingIO);
+                    desc, p.fRenderable, p.fSampleCnt, GrProtected::kNo,
+                    GrResourceProvider::Flags::kNoPendingIO);
         } else {
-            texture = resourceProvider->createTexture(desc, renderable, SkBudgeted::kNo,
-                                                      GrProtected::kNo,
+            texture = resourceProvider->createTexture(desc, p.fRenderable, p.fSampleCnt,
+                                                      SkBudgeted::kNo, GrProtected::kNo,
                                                       GrResourceProvider::Flags::kNoPendingIO);
         }
         return GrSurfaceProxy::LazyInstantiationResult(std::move(texture));
@@ -295,8 +294,8 @@
     auto lazyType = deinstantiate ? GrSurfaceProxy::LazyInstantiationType ::kDeinstantiate
                                   : GrSurfaceProxy::LazyInstantiationType ::kSingleUse;
     GrInternalSurfaceFlags flags = GrInternalSurfaceFlags::kNone;
-    return proxyProvider->createLazyProxy(callback, format, desc, p.fRenderable, p.fOrigin,
-                                          GrMipMapped::kNo, flags, p.fFit, p.fBudgeted,
+    return proxyProvider->createLazyProxy(callback, format, desc, p.fRenderable, p.fSampleCnt,
+                                          p.fOrigin, GrMipMapped::kNo, flags, p.fFit, p.fBudgeted,
                                           GrProtected::kNo, lazyType);
 }
 
@@ -361,7 +360,7 @@
     context->setResourceCacheLimits(0, 0);
 
     const ProxyParams params  = { 64, GrRenderable::kNo, kRGBA_8888_SkColorType,
-                                  SkBackingFit::kExact, 0, kTopLeft_GrSurfaceOrigin,
+                                  SkBackingFit::kExact, 1, kTopLeft_GrSurfaceOrigin,
                                   SkBudgeted::kYes };
 
     {
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 9e67932..7eab755 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -95,9 +95,8 @@
     desc.fWidth = size;
     desc.fHeight = size;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = sampleCount;
 
-    sk_sp<GrTexture> tex(provider->createTexture(desc, GrRenderable::kYes, budgeted,
+    sk_sp<GrTexture> tex(provider->createTexture(desc, GrRenderable::kYes, sampleCount, budgeted,
                                                  GrProtected::kNo,
                                                  GrResourceProvider::Flags::kNoPendingIO));
     if (!tex || !tex->asRenderTarget()) {
@@ -1617,9 +1616,8 @@
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = sampleCnt;
 
-    return provider->createTexture(desc, renderable, SkBudgeted::kYes, GrProtected::kNo,
+    return provider->createTexture(desc, renderable, sampleCnt, SkBudgeted::kYes, GrProtected::kNo,
                                    GrResourceProvider::Flags::kNoPendingIO);
 }
 
@@ -1632,14 +1630,13 @@
     desc.fWidth = width;
     desc.fHeight = height;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = sampleCnt;
 
     const GrBackendFormat format = caps->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
     auto origin = renderable == GrRenderable::kYes ? kBottomLeft_GrSurfaceOrigin
                                                    : kTopLeft_GrSurfaceOrigin;
 
-    return proxyProvider->createMipMapProxy(format, desc, renderable, origin, SkBudgeted::kYes,
-                                            GrProtected::kNo);
+    return proxyProvider->createMipMapProxy(format, desc, renderable, sampleCnt, origin,
+                                            SkBudgeted::kYes, GrProtected::kNo);
 }
 
 // Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only,
diff --git a/tests/TextureBindingsResetTest.cpp b/tests/TextureBindingsResetTest.cpp
index 1a91657..3f34e9c 100644
--- a/tests/TextureBindingsResetTest.cpp
+++ b/tests/TextureBindingsResetTest.cpp
@@ -74,7 +74,7 @@
     GrSurfaceDesc desc;
     desc.fWidth = desc.fHeight = 10;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    auto tex = gpu->createTexture(desc, GrRenderable::kNo, SkBudgeted::kNo, GrProtected::kNo);
+    auto tex = gpu->createTexture(desc, GrRenderable::kNo, 1, SkBudgeted::kNo, GrProtected::kNo);
     REPORTER_ASSERT(reporter, tex);
     context->resetGLTextureBindings();
     checkBindings();
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index c241e22..9414c89 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -29,7 +29,6 @@
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = 1;
 
     return desc;
 }
@@ -43,9 +42,9 @@
     GrBackendFormat format =
             ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
 
-    sk_sp<GrTextureProxy> proxy =
-            proxyProvider->createProxy(format, desc, GrRenderable::kNo, kBottomLeft_GrSurfaceOrigin,
-                                       fit, SkBudgeted::kYes, GrProtected::kNo);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format, desc, GrRenderable::kNo, 1,
+                                                             kBottomLeft_GrSurfaceOrigin, fit,
+                                                             SkBudgeted::kYes, GrProtected::kNo);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
     return proxy;
@@ -57,7 +56,7 @@
     GrBackendFormat format =
             ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
 
-    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format, desc, GrRenderable::kYes,
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format, desc, GrRenderable::kYes, 1,
                                                              kBottomLeft_GrSurfaceOrigin, fit,
                                                              SkBudgeted::kYes, GrProtected::kNo);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
@@ -70,7 +69,7 @@
     const GrSurfaceDesc desc = make_desc();
 
     sk_sp<GrTextureProxy> proxy = proxyProvider->testingOnly_createInstantiatedProxy(
-            desc, GrRenderable::kNo, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
+            desc, GrRenderable::kNo, 1, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
             GrProtected::kNo);
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     REPORTER_ASSERT(reporter, !proxy->getUniqueKey().isValid());
@@ -92,7 +91,7 @@
 
     // Only budgeted & wrapped external proxies get to carry uniqueKeys
     sk_sp<GrTextureProxy> proxy = proxyProvider->testingOnly_createInstantiatedProxy(
-            desc, GrRenderable::kNo, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
+            desc, GrRenderable::kNo, 1, kBottomLeft_GrSurfaceOrigin, fit, SkBudgeted::kYes,
             GrProtected::kNo);
     SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get()));
     REPORTER_ASSERT(reporter, proxy->getUniqueKey().isValid());
@@ -106,7 +105,7 @@
 
     const GrSurfaceDesc desc = make_desc();
 
-    *backingSurface = resourceProvider->createTexture(desc, GrRenderable::kNo, SkBudgeted::kNo,
+    *backingSurface = resourceProvider->createTexture(desc, GrRenderable::kNo, 1, SkBudgeted::kNo,
                                                       GrProtected::kNo,
                                                       GrResourceProvider::Flags::kNoPendingIO);
     if (!(*backingSurface)) {
diff --git a/tests/TraceMemoryDumpTest.cpp b/tests/TraceMemoryDumpTest.cpp
index dcff954..167e8fe 100644
--- a/tests/TraceMemoryDumpTest.cpp
+++ b/tests/TraceMemoryDumpTest.cpp
@@ -89,7 +89,6 @@
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = 1;
 
     GrGLTextureInfo glInfo;
     glInfo.fTarget = GR_GL_TEXTURE_2D;
@@ -114,7 +113,6 @@
     desc.fWidth = 64;
     desc.fHeight = 64;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    desc.fSampleCnt = 1;
 
     GrGLTextureInfo glInfo;
     glInfo.fTarget = GR_GL_TEXTURE_2D;
@@ -149,7 +147,7 @@
     iddesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
     iddesc.fMSColorRenderbufferID = 22;
 
-    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, GR_GL_RGBA8, iddesc, 0);
+    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, 1, GR_GL_RGBA8, iddesc, 0);
 
     ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), true /* isOwned */);
 }
@@ -169,7 +167,7 @@
     iddesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
     iddesc.fMSColorRenderbufferID = 22;
 
-    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, GR_GL_RGBA8, iddesc, 0);
+    sk_sp<GrGLRenderTarget> rt = GrGLRenderTarget::MakeWrapped(gpu, sd, 1, GR_GL_RGBA8, iddesc, 0);
 
     ValidateMemoryDumps(reporter, context, rt->gpuMemorySize(), false /* isOwned */);
 }
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
index 8795522..5586097 100644
--- a/tests/TransferPixelsTest.cpp
+++ b/tests/TransferPixelsTest.cpp
@@ -99,10 +99,9 @@
     desc.fWidth = kTextureWidth;
     desc.fHeight = kTextureHeight;
     desc.fConfig = GrColorTypeToPixelConfig(colorType);
-    desc.fSampleCnt = 1;
 
     sk_sp<GrTexture> tex =
-            resourceProvider->createTexture(desc, renderable, SkBudgeted::kNo, GrProtected::kNo,
+            resourceProvider->createTexture(desc, renderable, 1, SkBudgeted::kNo, GrProtected::kNo,
                                             GrResourceProvider::Flags::kNoPendingIO);
     if (!tex) {
         ERRORF(reporter, "Could not create texture");
@@ -219,7 +218,6 @@
     desc.fWidth = kTextureWidth;
     desc.fHeight = kTextureHeight;
     desc.fConfig = GrColorTypeToPixelConfig(colorType);
-    desc.fSampleCnt = 1;
 
     if (!context->priv().caps()->isConfigTexturable(desc.fConfig) ||
         (renderable == GrRenderable::kYes &&
@@ -235,7 +233,7 @@
     GrMipLevel data;
     data.fPixels = textureData.get();
     data.fRowBytes = textureDataRowBytes;
-    sk_sp<GrTexture> tex = resourceProvider->createTexture(desc, renderable, SkBudgeted::kNo,
+    sk_sp<GrTexture> tex = resourceProvider->createTexture(desc, renderable, 1, SkBudgeted::kNo,
                                                            GrProtected::kNo, &data, 1);
     if (!tex) {
         return;
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index d049b8f..c34c6c2 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -531,7 +531,7 @@
             context->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
 
         sk_sp<GrTextureProxy> temp = proxyProvider->createProxy(
-                format, desc, GrRenderable::kNo, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
+                format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox,
                 SkBudgeted::kYes, GrProtected::kNo);
         temp->instantiate(context->priv().resourceProvider());
     }
diff --git a/tools/fiddle/fiddle_main.cpp b/tools/fiddle/fiddle_main.cpp
index b087a18..1f07430 100644
--- a/tools/fiddle/fiddle_main.cpp
+++ b/tools/fiddle/fiddle_main.cpp
@@ -131,7 +131,6 @@
     backingDesc.fHeight = bm.height();
     // This config must match the SkColorType used in draw.cpp in the SkImage and Surface factories
     backingDesc.fConfig = kRGBA_8888_GrPixelConfig;
-    backingDesc.fSampleCnt = 1;
 
     if (!bm.empty()) {
         SkPixmap originalPixmap;
@@ -164,7 +163,7 @@
         }
 
         backingTexture =
-                resourceProvider->createTexture(backingDesc, GrRenderable::kNo, SkBudgeted::kNo,
+                resourceProvider->createTexture(backingDesc, GrRenderable::kNo, 1, SkBudgeted::kNo,
                                                 GrProtected::kNo, texels.get(), mipLevelCount);
         if (!backingTexture) {
             return false;
@@ -178,7 +177,6 @@
 
     backingDesc.fWidth = options.fOffScreenWidth;
     backingDesc.fHeight = options.fOffScreenHeight;
-    backingDesc.fSampleCnt = options.fOffScreenSampleCount;
 
     SkAutoTMalloc<uint32_t> data(backingDesc.fWidth * backingDesc.fHeight);
     sk_memset32(data.get(), 0, backingDesc.fWidth * backingDesc.fHeight);
@@ -191,7 +189,8 @@
         GrMipLevel level0 = { data.get(), backingDesc.fWidth*sizeof(uint32_t) };
 
         sk_sp<GrTexture> tmp = resourceProvider->createTexture(
-                backingDesc, GrRenderable::kYes, SkBudgeted::kNo, GrProtected::kNo, &level0, 1);
+                backingDesc, GrRenderable::kYes, options.fOffScreenSampleCount, SkBudgeted::kNo,
+                GrProtected::kNo, &level0, 1);
         if (!tmp || !tmp->asRenderTarget()) {
             return false;
         }
@@ -219,8 +218,9 @@
         }
 
         backingTextureRenderTarget =
-                resourceProvider->createTexture(backingDesc, GrRenderable::kYes, SkBudgeted::kNo,
-                                                GrProtected::kNo, texels.get(), mipLevelCount);
+                resourceProvider->createTexture(backingDesc, GrRenderable::kYes,
+                        options.fOffScreenSampleCount, SkBudgeted::kNo, GrProtected::kNo,
+                        texels.get(), mipLevelCount);
         if (!backingTextureRenderTarget || !backingTextureRenderTarget->asRenderTarget()) {
             return false;
         }
diff --git a/tools/gpu/ProxyUtils.cpp b/tools/gpu/ProxyUtils.cpp
index aab245d..54a4038 100644
--- a/tools/gpu/ProxyUtils.cpp
+++ b/tools/gpu/ProxyUtils.cpp
@@ -68,7 +68,7 @@
         desc.fConfig = config;
         desc.fWidth = width;
         desc.fHeight = height;
-        proxy = context->priv().proxyProvider()->createProxy(format, desc, renderable, origin,
+        proxy = context->priv().proxyProvider()->createProxy(format, desc, renderable, 1, origin,
                                                              SkBackingFit::kExact, SkBudgeted::kYes,
                                                              GrProtected::kNo);
         if (!proxy) {