More sample count cleanup:

rename getSampleCount -> getRenderTargetSampleCount because it will return
0 when a config is not renderable but *is* supported as a texture format.
(Old name kept around until Chrome stops calling it)

Add virtual GrCaps::maxRenderTargetSampleCount(GrPixelConfig).

Devirtualize isConfigRenderable() and implement as maxRTSC != 0. Separate implementation for version with bool withMSAA param to be removed after Flutter is updated to no longer call.

Consolidate various file static GrSurfaceDesc validators fns into GrCaps::validateSurfaceDesc().


Bug: skia:
Change-Id: Ie30a291aa027e910df3bd90fac8518ccdb39e53f
Reviewed-on: https://skia-review.googlesource.com/102141
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index b9ecfa7..f7f0bff 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -428,7 +428,8 @@
         if (const GrContext* ctx = factory.get(ctxType, ctxOverrides)) {
             GrPixelConfig grPixConfig = SkImageInfo2GrPixelConfig(colorType, colorSpace,
                                                                   *ctx->caps());
-            int supportedSampleCount = ctx->caps()->getSampleCount(sampleCount, grPixConfig);
+            int supportedSampleCount =
+                    ctx->caps()->getRenderTargetSampleCount(sampleCount, grPixConfig);
             if (sampleCount != supportedSampleCount) {
                 SkDebugf("Configuration '%s' sample count %d is not a supported sample count.\n",
                          config->getTag().c_str(), sampleCount);
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index ab77c88..0f03f16 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -134,12 +134,6 @@
 
     int maxRasterSamples() const { return fMaxRasterSamples; }
 
-    // Find a sample count greater than or equal to the requested count which is supported for a
-    // color buffer of the given config or 0 if no such sample count is supported. If the requested
-    // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
-    // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
-    virtual int getSampleCount(int requestedCount, GrPixelConfig config) const = 0;
-
     int maxWindowRectangles() const { return fMaxWindowRectangles; }
 
     // A tuned, platform-specific value for the maximum number of analytic fragment processors we
@@ -147,9 +141,32 @@
     int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; }
 
     virtual bool isConfigTexturable(GrPixelConfig) const = 0;
-    virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
+
     // Returns whether a texture of the given config can be copied to a texture of the same config.
-    virtual bool isConfigCopyable(GrPixelConfig config) const = 0;
+    virtual bool isConfigCopyable(GrPixelConfig) const = 0;
+
+    // Returns the maximum supported sample count for a config. 0 means the config is not renderable
+    // 1 means the config is renderable but doesn't support MSAA.
+    virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0;
+
+    bool isConfigRenderable(GrPixelConfig config) const {
+        return this->maxRenderTargetSampleCount(config) > 0;
+    }
+
+    // TODO: Remove this after Flutter updated to no longer use it.
+    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
+        return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0);
+    }
+
+    // Find a sample count greater than or equal to the requested count which is supported for a
+    // color buffer of the given config or 0 if no such sample count is supported. If the requested
+    // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
+    // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
+    virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0;
+    // TODO: Remove. Legacy name used by Chrome.
+    int getSampleCount(int requestedCount, GrPixelConfig config) const {
+        return this->getRenderTargetSampleCount(requestedCount, config);
+    }
 
     bool suppressPrints() const { return fSuppressPrints; }
 
@@ -180,6 +197,8 @@
     virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                                     bool* rectsMustMatch, bool* disallowSubrect) const = 0;
 
+    bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const;
+
     /**
      * Returns true if the GrBackendTexutre can we used with the supplied SkColorType. If it is
      * compatible, the passed in GrPixelConfig will be set to a config that matches the backend
diff --git a/include/gpu/mock/GrMockTypes.h b/include/gpu/mock/GrMockTypes.h
index cf30a33..0954c5e 100644
--- a/include/gpu/mock/GrMockTypes.h
+++ b/include/gpu/mock/GrMockTypes.h
@@ -22,8 +22,9 @@
  */
 struct GrMockOptions {
     GrMockOptions() {
+        using Renderability = ConfigOptions::Renderability;
         // By default RGBA_8888 is textureable and renderable and A8 and RGB565 are texturable.
-        fConfigOptions[kRGBA_8888_GrPixelConfig].fRenderable[0] = true;
+        fConfigOptions[kRGBA_8888_GrPixelConfig].fRenderability = Renderability::kNonMSAA;
         fConfigOptions[kRGBA_8888_GrPixelConfig].fTexturable = true;
         fConfigOptions[kAlpha_8_GrPixelConfig].fTexturable = true;
         fConfigOptions[kAlpha_8_as_Alpha_GrPixelConfig].fTexturable = true;
@@ -32,8 +33,8 @@
     }
 
     struct ConfigOptions {
-        /** The first value is for non-MSAA rendering, the second for MSAA. */
-        bool fRenderable[2] = {false, false};
+        enum Renderability { kNo, kNonMSAA, kMSAA };
+        Renderability fRenderability;
         bool fTexturable = false;
     };
 
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 427b204..dd589b4 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -196,8 +196,7 @@
                          kBlendEquationSupportNames[fBlendEquationSupport]);
     writer->appendString("Map Buffer Support", map_flags_to_string(fMapBufferFlags).c_str());
 
-    SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false));
-    SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, true));
+    SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig));
     SkASSERT(!this->isConfigTexturable(kUnknown_GrPixelConfig));
 
     writer->beginArray("configs");
@@ -206,8 +205,7 @@
         GrPixelConfig config = static_cast<GrPixelConfig>(i);
         writer->beginObject(nullptr, false);
         writer->appendString("name", pixel_config_name(config));
-        writer->appendBool("renderable", this->isConfigRenderable(config, false));
-        writer->appendBool("renderableMSAA", this->isConfigRenderable(config, true));
+        writer->appendS32("max sample count", this->maxRenderTargetSampleCount(config));
         writer->appendBool("texturable", this->isConfigTexturable(config));
         writer->endObject();
     }
@@ -222,3 +220,39 @@
     writer->endObject();
 }
 
+bool GrCaps::validateSurfaceDesc(const GrSurfaceDesc& desc, GrMipMapped mipped) const {
+    if (!this->isConfigTexturable(desc.fConfig)) {
+        return false;
+    }
+
+    if (GrMipMapped::kYes == mipped) {
+        if (GrPixelConfigIsSint(desc.fConfig) || !this->mipMapSupport()) {
+            return false;
+        }
+    }
+
+    if (desc.fWidth < 1 || desc.fHeight < 1) {
+        return false;
+    }
+
+    if (SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
+        if (0 == this->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig)) {
+            return false;
+        }
+        int maxRTSize = this->maxRenderTargetSize();
+        if (desc.fWidth > maxRTSize || desc.fHeight > maxRTSize) {
+            return false;
+        }
+    } else {
+        // We currently do not support multisampled textures
+        if (desc.fSampleCnt > 1) {
+            return false;
+        }
+        int maxSize = this->maxTextureSize();
+        if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
+            return false;
+        }
+    }
+
+    return true;
+}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index baa5232..0d481ac 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -951,7 +951,7 @@
                                                                  const SkSurfaceProps* surfaceProps,
                                                                  SkBudgeted budgeted) {
     SkASSERT(sampleCnt > 0);
-    if (!this->caps()->isConfigRenderable(config, sampleCnt > 1)) {
+    if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
         config = GrPixelConfigFallback(config);
     }
 
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index bea6a60..955d57d 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -72,74 +72,19 @@
     return false;
 }
 
-/**
- * Prior to creating a texture, make sure the type of texture being created is
- * supported by calling check_texture_creation_params.
- *
- * @param caps          The capabilities of the GL device.
- * @param desc          The descriptor of the texture to create.
- * @param isRT          Indicates if the texture can be a render target.
- * @param texels        The texel data for the mipmap levels
- * @param mipLevelCount The number of GrMipLevels in 'texels'
- */
-static bool check_texture_creation_params(const GrCaps& caps, const GrSurfaceDesc& desc,
-                                          bool* isRT,
-                                          const GrMipLevel texels[], int mipLevelCount) {
-    if (!caps.isConfigTexturable(desc.fConfig)) {
-        return false;
-    }
-
-    if (GrPixelConfigIsSint(desc.fConfig) && mipLevelCount > 1) {
-        return false;
-    }
-
-    *isRT = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
-    if (*isRT && !caps.isConfigRenderable(desc.fConfig, desc.fSampleCnt > 1)) {
-        return false;
-    }
-
-    if (desc.fSampleCnt < 1) {
-        return false;
-    }
-
-    // We currently do not support multisampled textures
-    if (!*isRT && desc.fSampleCnt > 1) {
-        return false;
-    }
-
-    if (*isRT) {
-        int maxRTSize = caps.maxRenderTargetSize();
-        if (desc.fWidth > maxRTSize || desc.fHeight > maxRTSize) {
-            return false;
-        }
-    } else {
-        int maxSize = caps.maxTextureSize();
-        if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
 sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted,
                                       const GrMipLevel texels[], int mipLevelCount) {
     GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "createTexture", fContext);
     GrSurfaceDesc desc = origDesc;
 
-    const GrCaps* caps = this->caps();
-    bool isRT = false;
-    bool textureCreationParamsValid = check_texture_creation_params(*caps, desc, &isRT,
-                                                                    texels, mipLevelCount);
-    if (!textureCreationParamsValid) {
+    GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
+    if (!this->caps()->validateSurfaceDesc(desc, mipMapped)) {
         return nullptr;
     }
 
+    bool isRT = desc.fFlags & kRenderTarget_GrSurfaceFlag;
     if (isRT) {
-        desc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
-        if (!desc.fSampleCnt) {
-            return nullptr;
-        }
+        desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig);
     }
     // Attempt to catch un- or wrongly initialized sample counts.
     SkASSERT(desc.fSampleCnt > 0 && desc.fSampleCnt <= 64);
@@ -151,7 +96,7 @@
     this->handleDirtyContext();
     sk_sp<GrTexture> tex = this->onCreateTexture(desc, budgeted, texels, mipLevelCount);
     if (tex) {
-        if (!caps->reuseScratchTextures() && !isRT) {
+        if (!this->caps()->reuseScratchTextures() && !isRT) {
             tex->resourcePriv().removeScratchKey();
         }
         fStats.incTextureCreates();
@@ -192,7 +137,7 @@
         return nullptr;
     }
     if (!this->caps()->isConfigTexturable(backendTex.config()) ||
-        !this->caps()->isConfigRenderable(backendTex.config(), sampleCnt > 1)) {
+        !this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config())) {
         return nullptr;
     }
 
@@ -209,7 +154,7 @@
 }
 
 sk_sp<GrRenderTarget> GrGpu::wrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
-    if (!this->caps()->isConfigRenderable(backendRT.config(), backendRT.sampleCnt() > 1)) {
+    if (0 == this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config())) {
         return nullptr;
     }
     this->handleDirtyContext();
@@ -218,14 +163,14 @@
 
 sk_sp<GrRenderTarget> GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
                                                               int sampleCnt) {
-    this->handleDirtyContext();
-    if (!this->caps()->isConfigRenderable(tex.config(), sampleCnt > 1)) {
+    if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config())) {
         return nullptr;
     }
     int maxSize = this->caps()->maxTextureSize();
     if (tex.width() > maxSize || tex.height() > maxSize) {
         return nullptr;
     }
+    this->handleDirtyContext();
     return this->onWrapBackendTextureAsRenderTarget(tex, sampleCnt);
 }
 
@@ -274,7 +219,7 @@
 
     // Check to see if we're going to request that the caller draw when drawing is not possible.
     if (!srcSurface->asTexture() ||
-        !this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig, false)) {
+        !this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
         // If we don't have a fallback to a straight read then fail.
         if (kRequireDraw_DrawPreference == *drawPreference) {
             return false;
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 193b321..1a09914 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -313,41 +313,14 @@
                                                    uint32_t flags) {
     SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags);
 
-    const GrCaps* caps = this->caps();
-
-    // TODO: move this logic into GrResourceProvider!
-    // TODO: share this testing code with check_texture_creation_params
-    if (!caps->isConfigTexturable(desc.fConfig)) {
+    if (!this->caps()->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
         return nullptr;
     }
-
-    bool willBeRT = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
-    if (willBeRT && !caps->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 1)) {
-        return nullptr;
-    }
-
-    // We currently do not support multisampled textures
-    if (!willBeRT && desc.fSampleCnt > 1) {
-        return nullptr;
-    }
-
-    if (willBeRT && !caps->getSampleCount(desc.fSampleCnt, desc.fConfig)) {
-        return nullptr;
-    }
-
-    int maxSize;
-    if (willBeRT) {
-        maxSize = caps->maxRenderTargetSize();
-    } else {
-        maxSize = caps->maxTextureSize();
-    }
-
-    if (desc.fWidth > maxSize || desc.fHeight > maxSize || desc.fWidth <= 0 || desc.fHeight <= 0) {
-        return nullptr;
-    }
-
     GrSurfaceDesc copyDesc = desc;
-    copyDesc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
+    if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
+        copyDesc.fSampleCnt =
+                this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig);
+    }
 
 #ifdef SK_DISABLE_DEFERRED_PROXIES
     // Temporarily force instantiation for crbug.com/769760 and crbug.com/769898
@@ -365,11 +338,11 @@
 
     return GrSurfaceProxy::MakeWrapped(std::move(tex), copyDesc.fOrigin);
 #else
-    if (willBeRT) {
+    if (copyDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
         // We know anything we instantiate later from this deferred path will be
         // both texturable and renderable
-        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*caps, copyDesc, fit,
-                                                                    budgeted, flags));
+        return sk_sp<GrTextureProxy>(
+                new GrTextureRenderTargetProxy(*this->caps(), copyDesc, fit, budgeted, flags));
     }
 
     return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0, flags));
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 011ad6f..226a034 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -46,32 +46,6 @@
     fQuadIndexBufferKey = gQuadIndexBufferKey;
 }
 
-bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount = 0) {
-    if (desc.fSampleCnt < 1) {
-        return false;
-    }
-
-    if (desc.fWidth <= 0 || desc.fHeight <= 0) {
-        return false;
-    }
-    if (!caps.isConfigTexturable(desc.fConfig)) {
-        return false;
-    }
-    if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
-        if (!caps.isConfigRenderable(desc.fConfig, desc.fSampleCnt > 1)) {
-            return false;
-        }
-    } else {
-        if (desc.fSampleCnt > 1) {
-            return false;
-        }
-    }
-    if (levelCount > 1 && (GrPixelConfigIsSint(desc.fConfig) || !caps.mipMapSupport())) {
-        return false;
-    }
-    return true;
-}
-
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
                                                    const GrMipLevel texels[], int mipLevelCount,
                                                    SkDestinationSurfaceColorMode mipColorMode) {
@@ -83,7 +57,8 @@
         return nullptr;
     }
 
-    if (!validate_desc(desc, *fCaps, mipLevelCount)) {
+    GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
+    if (!fCaps->validateSurfaceDesc(desc, mipMapped)) {
         return nullptr;
     }
 
@@ -128,7 +103,7 @@
         return nullptr;
     }
 
-    if (!validate_desc(desc, *fCaps)) {
+    if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
         return nullptr;
     }
 
@@ -164,7 +139,7 @@
         return nullptr;
     }
 
-    if (!validate_desc(desc, *fCaps)) {
+    if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
         return nullptr;
     }
 
@@ -185,7 +160,7 @@
         return nullptr;
     }
 
-    if (!validate_desc(desc, *fCaps)) {
+    if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
         return nullptr;
     }
 
@@ -214,7 +189,7 @@
                                                        uint32_t flags) {
     ASSERT_SINGLE_OWNER
     SkASSERT(!this->isAbandoned());
-    SkASSERT(validate_desc(desc, *fCaps));
+    SkASSERT(fCaps->validateSurfaceDesc(desc, 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.
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index abe8880..da69917 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -42,7 +42,7 @@
     return shaderCaps.integerSupport() && shaderCaps.flatInterpolationSupport() &&
            caps.instanceAttribSupport() && GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
            caps.isConfigTexturable(kAlpha_half_GrPixelConfig) &&
-           caps.isConfigRenderable(kAlpha_half_GrPixelConfig, /*withMSAA=*/false) &&
+           caps.isConfigRenderable(kAlpha_half_GrPixelConfig) &&
            !caps.blacklistCoverageCounting();
 }
 
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 93a7e61..066bf03 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2046,7 +2046,7 @@
 
     // If the src is a texture, we can implement the blit as a draw assuming the config is
     // renderable.
-    if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) {
+    if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
         desc->fOrigin = kBottomLeft_GrSurfaceOrigin;
         desc->fFlags = kRenderTarget_GrSurfaceFlag;
         desc->fConfig = src->config();
@@ -2468,10 +2468,10 @@
     }
 }
 
-int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
+int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     requestedCount = SkTMax(1, requestedCount);
     int count = fConfigTable[config].fColorSampleCounts.count();
-    if (!count || !this->isConfigRenderable(config, requestedCount > 1)) {
+    if (!count) {
         return 0;
     }
 
@@ -2487,6 +2487,14 @@
     return 0;
 }
 
+int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
+    const auto& table = fConfigTable[config].fColorSampleCounts;
+    if (!table.count()) {
+        return 0;
+    }
+    return table[table.count() - 1];
+}
+
 bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config,
                            GrGLStandard standard) {
     *config = kUnknown_GrPixelConfig;
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index fd49a65..7a443e4 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -112,19 +112,12 @@
     GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
              const GrGLInterface* glInterface);
 
-    int getSampleCount(int requestedCount, GrPixelConfig config) const override;
-
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
     }
 
-    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
-        if (withMSAA) {
-            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
-        } else {
-            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
-        }
-    }
+    int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
+    int maxRenderTargetSampleCount(GrPixelConfig config) const override;
 
     bool isConfigCopyable(GrPixelConfig config) const override {
         // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e117488..7547803 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -581,7 +581,7 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
+    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
     if (surfDesc.fSampleCnt < 1) {
         return nullptr;
     }
@@ -619,7 +619,8 @@
     desc.fWidth = backendRT.width();
     desc.fHeight = backendRT.height();
     desc.fConfig = backendRT.config();
-    desc.fSampleCnt = this->caps()->getSampleCount(backendRT.sampleCnt(), backendRT.config());
+    desc.fSampleCnt =
+            this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config());
 
     return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, backendRT.stencilBits());
 }
@@ -648,7 +649,7 @@
     surfDesc.fWidth = tex.width();
     surfDesc.fHeight = tex.height();
     surfDesc.fConfig = tex.config();
-    surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
+    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
 
     GrGLRenderTarget::IDDesc rtIDDesc;
     if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) {
@@ -1527,7 +1528,7 @@
 
 int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
     static const int kSize = 16;
-    SkASSERT(this->caps()->isConfigRenderable(config, false));
+    SkASSERT(this->caps()->isConfigRenderable(config));
     if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) {
         // Default to unsupported, set this if we find a stencil format that works.
         int firstWorkingStencilFormatIndex = -1;
@@ -2136,7 +2137,7 @@
         GrSurfaceDesc desc;
         desc.fConfig = rtConfig;
         desc.fWidth = desc.fHeight = 16;
-        if (this->glCaps().isConfigRenderable(rtConfig, false)) {
+        if (this->glCaps().isConfigRenderable(rtConfig)) {
             desc.fFlags = kRenderTarget_GrSurfaceFlag;
             desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
             temp = this->createTexture(desc, SkBudgeted::kNo);
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 399517b..1e44851 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -33,19 +33,39 @@
 
         this->applyOptionsOverrides(contextOptions);
     }
-    int getSampleCount(int requestCount, GrPixelConfig /*config*/) const override {
-        return (requestCount > 0 && requestCount <= 16) ? GrNextPow2(requestCount) : 0;
-    }
     bool isConfigTexturable(GrPixelConfig config) const override {
         return fOptions.fConfigOptions[config].fTexturable;
     }
-    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
-        return fOptions.fConfigOptions[config].fRenderable[withMSAA];
-    }
+
     bool isConfigCopyable(GrPixelConfig config) const override {
         return false;
     }
 
+    int getRenderTargetSampleCount(int requestCount, GrPixelConfig config) const override {
+        requestCount = SkTMax(requestCount, 1);
+        switch (fOptions.fConfigOptions[config].fRenderability) {
+            case GrMockOptions::ConfigOptions::Renderability::kNo:
+                return 0;
+            case GrMockOptions::ConfigOptions::Renderability::kNonMSAA:
+                return requestCount > 1 ? 0 : 1;
+            case GrMockOptions::ConfigOptions::Renderability::kMSAA:
+                return requestCount > kMaxSampleCnt ? 0 : GrNextPow2(requestCount);
+        }
+        return 0;
+    }
+
+    int maxRenderTargetSampleCount(GrPixelConfig config) const override {
+        switch (fOptions.fConfigOptions[config].fRenderability) {
+            case GrMockOptions::ConfigOptions::Renderability::kNo:
+                return 0;
+            case GrMockOptions::ConfigOptions::Renderability::kNonMSAA:
+                return 1;
+            case GrMockOptions::ConfigOptions::Renderability::kMSAA:
+                return kMaxSampleCnt;
+        }
+        return 0;
+    }
+
     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                             bool* rectsMustMatch, bool* disallowSubrect) const override {
         return false;
@@ -62,6 +82,8 @@
     }
 
 private:
+    static const int kMaxSampleCnt = 16;
+
     GrMockOptions fOptions;
     typedef GrCaps INHERITED;
 };
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 6204eaa..935cb07 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -24,20 +24,12 @@
     GrMtlCaps(const GrContextOptions& contextOptions, id<MTLDevice> device,
               MTLFeatureSet featureSet);
 
-    int getSampleCount(int requestedCount, GrPixelConfig config) const override;
-
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
     }
 
-    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
-        if (withMSAA) {
-            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag) &&
-                   SkToBool(fConfigTable[config].fFlags & ConfigInfo::kMSAA_Flag);
-        } else {
-            return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
-        }
-    }
+    int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const override;
+    int maxRenderTargetSampleCount(GrPixelConfig) const override;
 
     bool isConfigCopyable(GrPixelConfig config) const override {
         return true;
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 2bce74a..0bb7530 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -121,7 +121,7 @@
     fMaxTextureSize = fMaxRenderTargetSize;
 
     // Init sample counts. All devices support 1 (i.e. 0 in skia).
-    fSampleCounts.push(0);
+    fSampleCounts.push(1);
     for (auto sampleCnt : {2, 4, 8}) {
         if ([device supportsTextureSampleCount:sampleCnt]) {
             fSampleCounts.push(sampleCnt);
@@ -164,19 +164,29 @@
     fCrossContextTextureSupport = false;
 }
 
-int GrMtlCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
-    int count = fSampleCounts.count();
-    SkASSERT(count > 0); // We always add 0 as a valid sample count
-    if (!this->isConfigRenderable(config, true)) {
-        return 0;
-    }
 
-    for (int i = 0; i < count; ++i) {
-        if (fSampleCounts[i] >= requestedCount) {
-            return fSampleCounts[i];
-        }
+int GrMtlCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
+    if (fConfigTable[config].fFlags & ConfigInfo::kMSAA_Flag) {
+        return fSampleCounts[fSampleCounts.count() - 1];
+    } else if (fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag) {
+        return 1;
     }
-    return fSampleCounts[count-1];
+    return 0;
+}
+
+int GrMtlCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
+    requestedCount = SkTMax(requestedCount, 1);
+    if (fConfigTable[config].fFlags & ConfigInfo::kMSAA_Flag) {
+        int count = fSampleCounts.count();
+        for (int i = 0; i < count; ++i) {
+            if (fSampleCounts[i] >= requestedCount) {
+                return fSampleCounts[i];
+            }
+        }
+    } else if (fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag) {
+        return 1 == requestedCount ? 1 : 0;
+    }
+    return 0;
 }
 
 void GrMtlCaps::initShaderCaps() {
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index e9f239c..8af8119 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -386,24 +386,11 @@
     }
 }
 
-bool GrVkCaps::isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
-    if (!SkToBool(ConfigInfo::kRenderable_Flag & fConfigTable[config].fOptimalFlags)) {
-        return false;
-    }
-    if (withMSAA && fConfigTable[config].fColorSampleCounts.count() < 2) {
-        // We expect any renderable config to support non-MSAA rendering.
-        SkASSERT(1 == fConfigTable[config].fColorSampleCounts.count());
-        SkASSERT(1 == fConfigTable[config].fColorSampleCounts[0]);
-        return false;
-    }
-    return true;
-}
-
-int GrVkCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
+int GrVkCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     requestedCount = SkTMax(1, requestedCount);
     int count = fConfigTable[config].fColorSampleCounts.count();
 
-    if (!count || !this->isConfigRenderable(config, requestedCount > 1)) {
+    if (!count) {
         return 0;
     }
 
@@ -421,6 +408,14 @@
     return 0;
 }
 
+int GrVkCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
+    const auto& table = fConfigTable[config].fColorSampleCounts;
+    if (!table.count()) {
+        return 0;
+    }
+    return table[table.count() - 1];
+}
+
 bool validate_image_info(const GrVkImageInfo* imageInfo, SkColorType ct, GrPixelConfig* config) {
     if (!imageInfo) {
         return false;
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 4468d89..3449dd2 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -29,18 +29,17 @@
     GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
              VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
 
-    int getSampleCount(int requestedCount, GrPixelConfig config) const override;
-
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
     }
 
-    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override;
-
     bool isConfigCopyable(GrPixelConfig config) const override {
         return true;
     }
 
+    int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
+    int maxRenderTargetSampleCount(GrPixelConfig config) const override;
+
     bool isConfigTexturableLinearly(GrPixelConfig config) const {
         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags);
     }
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 4550dfe..362ac1f 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -777,17 +777,7 @@
     bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
 
     VkFormat pixelFormat;
-    if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) {
-        return nullptr;
-    }
-
-    if (!fVkCaps->isConfigTexturable(desc.fConfig)) {
-        return nullptr;
-    }
-
-    if (renderTarget && !fVkCaps->isConfigRenderable(desc.fConfig, false)) {
-        return nullptr;
-    }
+    SkAssertResult(GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat));
 
     VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
     if (renderTarget) {
@@ -932,7 +922,7 @@
     surfDesc.fWidth = backendTex.width();
     surfDesc.fHeight = backendTex.height();
     surfDesc.fConfig = backendTex.config();
-    surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
+    surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
 
     return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership,
                                                                    backendTex.getVkImageInfo());
@@ -989,7 +979,7 @@
     desc.fWidth = tex.width();
     desc.fHeight = tex.height();
     desc.fConfig = tex.config();
-    desc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
+    desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
     if (!desc.fSampleCnt) {
         return nullptr;
     }
@@ -1191,7 +1181,7 @@
         return GrBackendTexture(); // invalid
     }
 
-    if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) {
+    if (isRenderTarget && !fVkCaps->isConfigRenderable(config)) {
         return GrBackendTexture(); // invalid
     }
 
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index ed46835..92d3a2f 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -267,9 +267,8 @@
 
 #if SK_SUPPORT_GPU
     bool supportsHalfFloat() const {
-        return !fCaps ||
-            (fCaps->isConfigTexturable(kRGBA_half_GrPixelConfig) &&
-             fCaps->isConfigRenderable(kRGBA_half_GrPixelConfig, false));
+        return !fCaps || (fCaps->isConfigTexturable(kRGBA_half_GrPixelConfig) &&
+                          fCaps->isConfigRenderable(kRGBA_half_GrPixelConfig));
     }
 
     bool supportsSRGB() const {
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index e811c3a..8d81665 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -334,11 +334,7 @@
         return false;
     }
 
-    if (!ctx->caps()->isConfigRenderable(*config, sampleCnt > 1)) {
-        return false;
-    }
-
-    if (ctx->caps()->getSampleCount(sampleCnt, *config) != sampleCnt) {
+    if (ctx->caps()->getRenderTargetSampleCount(sampleCnt, *config) != sampleCnt) {
         return false;
     }
 
@@ -411,7 +407,11 @@
         return false;
     }
 
-    if (!ctx->caps()->isConfigRenderable(*config, false)) {
+    if (rt.sampleCnt() > 1) {
+        if (ctx->caps()->maxRenderTargetSampleCount(*config) <= 1) {
+            return false;
+        }
+    } else if (ctx->caps()->isConfigRenderable(*config)) {
         return false;
     }
 
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index 9938d49..b3637cb 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -137,7 +137,7 @@
         if (SurfaceParameters::kSampleCount == i) {
             SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
 
-            int supportedSampleCount = context->caps()->getSampleCount(
+            int supportedSampleCount = context->caps()->getRenderTargetSampleCount(
                 params.sampleCount(),
                 gpuSurf->getDevice()->accessRenderTargetContext()->asRenderTargetProxy()->config());
             if (1 == supportedSampleCount) {
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index df35559..f625a77 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -150,7 +150,8 @@
                                                                  const GrCaps* caps) {
     GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
                                                 : kBottomLeft_GrSurfaceOrigin;
-    int sampleCnt = random->nextBool() ? caps->getSampleCount(2, kRGBA_8888_GrPixelConfig) : 1;
+    int sampleCnt =
+            random->nextBool() ? caps->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig) : 1;
     // Above could be 0 if msaa isn't supported.
     sampleCnt = SkTMax(1, sampleCnt);
 
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index 5530539..56764cf 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -113,7 +113,7 @@
     GrAlwaysAssert(testPatternSize > 1 && SkIsPow2(testPatternSize));
     int randSampCnt = rand->nextRangeU(1 + testPatternSize / 2, testPatternSize);
     do {
-        int cnt = caps->getSampleCount(randSampCnt, kRGBA_8888_GrPixelConfig);
+        int cnt = caps->getRenderTargetSampleCount(randSampCnt, kRGBA_8888_GrPixelConfig);
         if (cnt) {
             return cnt;
         }
@@ -203,7 +203,7 @@
     sk_sp<GrContext> ctx(GrContext::MakeGL(testInterface));
 
     // This test relies on at least 2 samples.
-    int supportedSample = ctx->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
+    int supportedSample = ctx->caps()->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig);
     if (supportedSample < 2) {
         return;
     }
diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp
index 9f770d6..cba94b4 100644
--- a/tests/GrCCPRTest.cpp
+++ b/tests/GrCCPRTest.cpp
@@ -119,7 +119,8 @@
         GrMockOptions mockOptions;
         mockOptions.fInstanceAttribSupport = true;
         mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
-        mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderable[0] = true;
+        mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderability =
+                GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
         mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
         mockOptions.fGeometryShaderSupport = true;
         mockOptions.fIntegerSupport = true;
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index 29f4f25..32ac0c7 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -143,17 +143,17 @@
 
             desc.fFlags = kRenderTarget_GrSurfaceFlag;
             tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
-            bool icr = caps->isConfigRenderable(config, false);
-            REPORTER_ASSERT(reporter, SkToBool(tex) == icr,
-                            "config:%d, tex:%d, isConfigRenderable(false):%d", config,
-                            SkToBool(tex), icr);
+            bool isRenderable = caps->isConfigRenderable(config);
+            REPORTER_ASSERT(reporter, SkToBool(tex) == isRenderable,
+                            "config:%d, tex:%d, isRenderable:%d", config, SkToBool(tex),
+                            isRenderable);
 
             desc.fSampleCnt = 2;
             tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
-            icr = caps->isConfigRenderable(config, true);
-            REPORTER_ASSERT(reporter, SkToBool(tex) == icr,
-                            "config:%d, tex:%d, isConfigRenderable(true):%d", config, SkToBool(tex),
-                            icr);
+            isRenderable = SkToBool(caps->getRenderTargetSampleCount(2, config));
+            REPORTER_ASSERT(reporter, SkToBool(tex) == isRenderable,
+                            "config:%d, tex:%d, isRenderable:%d", config, SkToBool(tex),
+                            isRenderable);
         }
     }
 }
@@ -178,7 +178,7 @@
         }
         desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
         for (bool rt : {false, true}) {
-            if (rt && !context->caps()->isConfigRenderable(desc.fConfig, false)) {
+            if (rt && !context->caps()->isConfigRenderable(desc.fConfig)) {
                 continue;
             }
             desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index f1bffa5..5c05327 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -179,7 +179,8 @@
 
 DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
     GrMockOptions mockOptions;
-    mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderable[0] = true;
+    mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderability =
+            GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
     mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
     sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
     GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 3bde3de..dff230c 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -149,7 +149,8 @@
 
                                     check_surface(reporter, proxy.get(), origin,
                                                   widthHeight, widthHeight, config, budgeted);
-                                    int supportedSamples = caps.getSampleCount(numSamples, config);
+                                    int supportedSamples =
+                                            caps.getRenderTargetSampleCount(numSamples, config);
                                     check_rendertarget(reporter, caps, resourceProvider,
                                                        proxy->asRenderTargetProxy(),
                                                        supportedSamples,
@@ -205,9 +206,7 @@
         for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) {
             for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) {
                 for (auto numSamples : {1, 4}) {
-                    int supportedNumSamples = caps.getSampleCount(numSamples, config);
-
-                    bool renderable = caps.isConfigRenderable(config, numSamples > 1);
+                    int supportedNumSamples = caps.getRenderTargetSampleCount(numSamples, config);
 
                     GrSurfaceDesc desc;
                     desc.fOrigin = origin;
@@ -217,7 +216,7 @@
                     desc.fSampleCnt = supportedNumSamples;
 
                     // External on-screen render target.
-                    if (renderable && kOpenGL_GrBackend == ctxInfo.backend()) {
+                    if (supportedNumSamples && kOpenGL_GrBackend == ctxInfo.backend()) {
                         GrGLFramebufferInfo fboInfo;
                         fboInfo.fFBOID = 0;
                         GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples, 8,
@@ -232,7 +231,7 @@
                                            supportedNumSamples, SkBackingFit::kExact, 0, true);
                     }
 
-                    if (renderable) {
+                    if (supportedNumSamples) {
                         // Internal offscreen render target.
                         desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
diff --git a/tests/ResourceAllocatorTest.cpp b/tests/ResourceAllocatorTest.cpp
index 7dcb0ee..173696b 100644
--- a/tests/ResourceAllocatorTest.cpp
+++ b/tests/ResourceAllocatorTest.cpp
@@ -148,8 +148,8 @@
                      std::move(p1), std::move(p2), test.fExpectation);
     }
 
-    int k2 = ctxInfo.grContext()->caps()->getSampleCount(2, kRGBA);
-    int k4 = ctxInfo.grContext()->caps()->getSampleCount(4, kRGBA);
+    int k2 = ctxInfo.grContext()->caps()->getRenderTargetSampleCount(2, kRGBA);
+    int k4 = ctxInfo.grContext()->caps()->getRenderTargetSampleCount(4, kRGBA);
 
     //--------------------------------------------------------------------------------------------
     TestCase gNonOverlappingTests[] = {
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index da2e278..3bd6c4b 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -156,7 +156,7 @@
         REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(bigRT.get()));
     }
 
-    int smallSampleCount = context->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
+    int smallSampleCount = context->caps()->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig);
     if (smallSampleCount > 1) {
         // An RT with a different sample count should not share.
         sk_sp<GrRenderTarget> smallMSAART0 = create_RT_with_SB(resourceProvider, 4,
@@ -184,7 +184,8 @@
 
         // But one with a larger sample count should not. (Also check that the two requests didn't
         // rounded up to the same actual sample count or else they could share.).
-        int bigSampleCount = context->caps()->getSampleCount(5, kRGBA_8888_GrPixelConfig);
+        int bigSampleCount =
+                context->caps()->getRenderTargetSampleCount(5, kRGBA_8888_GrPixelConfig);
         if (bigSampleCount > 0 && bigSampleCount != smallSampleCount) {
             sk_sp<GrRenderTarget> smallMSAART2 = create_RT_with_SB(resourceProvider, 4,
                                                                    bigSampleCount,
@@ -1710,7 +1711,8 @@
         size_t size = tex->gpuMemorySize();
         REPORTER_ASSERT(reporter, kSize*kSize*4 == size);
 
-        size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
+        size_t sampleCount =
+                (size_t)context->caps()->getRenderTargetSampleCount(4, kRGBA_8888_GrPixelConfig);
         if (sampleCount >= 4) {
             tex = make_normal_texture(resourceProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
                                       sampleCount);
@@ -1735,7 +1737,8 @@
         size_t size = proxy->gpuMemorySize();
         REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
 
-        size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
+        size_t sampleCount =
+                (size_t)context->caps()->getRenderTargetSampleCount(4, kRGBA_8888_GrPixelConfig);
         if (sampleCount >= 4) {
             proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
                                       sampleCount);
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index 7013971..bb7b77c 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -172,7 +172,7 @@
     desc.fWidth = kW;
     desc.fHeight = kH;
     desc.fConfig = kSRGBA_8888_GrPixelConfig;
-    if (context->caps()->isConfigRenderable(desc.fConfig, false) &&
+    if (context->caps()->isConfigRenderable(desc.fConfig) &&
         context->caps()->isConfigTexturable(desc.fConfig)) {
 
         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index af73473..7acd3eb 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -880,7 +880,7 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCreationWithColorSpace_Gpu, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
 
-    bool f16Support = context->caps()->isConfigRenderable(kRGBA_half_GrPixelConfig, false);
+    bool f16Support = context->caps()->isConfigRenderable(kRGBA_half_GrPixelConfig);
     auto surfaceMaker = [context](const SkImageInfo& info) {
         return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
     };
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index fcab2d3..6b89bc2 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -292,7 +292,8 @@
     GrPixelConfig grPixConfig = SkImageInfo2GrPixelConfig(config->getColorType(),
                                                           config->getColorSpace(),
                                                           *ctx->caps());
-    int supportedSampleCount = ctx->caps()->getSampleCount(config->getSamples(), grPixConfig);
+    int supportedSampleCount =
+            ctx->caps()->getRenderTargetSampleCount(config->getSamples(), grPixConfig);
     if (supportedSampleCount != config->getSamples()) {
         exitf(ExitErr::kUnavailable, "sample count %i not supported by platform",
                                      config->getSamples());