Reland "Remove GrBackendFormat's textureType use from isFormatTexturable call."

This reverts commit d90777ada391dffa9a19101fe7917d0c13a606b3.

Reason for revert: relanding with fix to GrBackendTexture

Original change's description:
> Revert "Remove GrBackendFormat's textureType use from isFormatTexturable call."
>
> This reverts commit 832c817bc8a9567aa379181e71e7c602d2480de8.
>
> Reason for revert: uninitialized value in GrBackendTexture
>
> Original change's description:
> > Remove GrBackendFormat's textureType use from isFormatTexturable call.
> >
> > The goal of this change was to remove the use of GrBackendFormat::textureType()
> > from GrCaps::isFormatTexturable call. Instead we will always pass in a
> > GrTextureType into this call.
> >
> > To do this a lot of plumbing of GrTextureType was added to various call
> > sites. However, this CL halts the plubming up at the proxy level where we
> > get it from the GrBackendFormat still. Future CLs will continue removing
> > these call sites and others that use GrBackendFormat::textureType().
> >
> > Bug: skia:12342
> > Change-Id: Ic0f02b9c7f7402405623b8aa31aa32a9a7c22297
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/439277
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
>
> TBR=egdaniel@google.com,bsalomon@google.com,skcq-be@skia-corp.google.com.iam.gserviceaccount.com
>
> Change-Id: I354bbbf00be7a86c480009f3e7b36a8777a6bf3a
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:12342
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/439338
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>

# Not skipping CQ checks because this is a reland.

Bug: skia:12342
Change-Id: I151196f149f9e191d2975b8fe81334f4f8720744
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/439339
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index fbbcf9e..883626a 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -82,27 +82,27 @@
 }
 
 #ifdef SK_GL
+
+static GrTextureType gl_target_to_gr_target(GrGLenum target) {
+    switch (target) {
+        case GR_GL_TEXTURE_NONE:
+            return GrTextureType::kNone;
+        case GR_GL_TEXTURE_2D:
+            return  GrTextureType::k2D;
+        case GR_GL_TEXTURE_RECTANGLE:
+            return GrTextureType::kRectangle;
+        case GR_GL_TEXTURE_EXTERNAL:
+            return GrTextureType::kExternal;
+        default:
+            SkUNREACHABLE;
+    }
+}
+
 GrBackendFormat::GrBackendFormat(GrGLenum format, GrGLenum target)
         : fBackend(GrBackendApi::kOpenGL)
         , fValid(true)
-        , fGLFormat(format) {
-    switch (target) {
-        case GR_GL_TEXTURE_NONE:
-            fTextureType = GrTextureType::kNone;
-            break;
-        case GR_GL_TEXTURE_2D:
-            fTextureType = GrTextureType::k2D;
-            break;
-        case GR_GL_TEXTURE_RECTANGLE:
-            fTextureType = GrTextureType::kRectangle;
-            break;
-        case GR_GL_TEXTURE_EXTERNAL:
-            fTextureType = GrTextureType::kExternal;
-            break;
-        default:
-            SK_ABORT("Unexpected texture target");
-    }
-}
+        , fGLFormat(format)
+        , fTextureType(gl_target_to_gr_target(target)) {}
 #endif
 
 GrGLFormat GrBackendFormat::asGLFormat() const {
@@ -455,6 +455,7 @@
         , fHeight(height)
         , fMipmapped(GrMipmapped(dawnInfo.fLevelCount > 1))
         , fBackend(GrBackendApi::kDawn)
+        , fTextureType(GrTextureType::k2D)
         , fDawnInfo(dawnInfo) {}
 #endif
 
@@ -483,6 +484,13 @@
     return info;
 }
 
+static GrTextureType vk_image_info_to_texture_type(const GrVkImageInfo& info) {
+    if (info.fYcbcrConversionInfo.isValid() && info.fYcbcrConversionInfo.fExternalFormat != 0) {
+        return GrTextureType::kExternal;
+    }
+    return GrTextureType::k2D;
+}
+
 GrBackendTexture::GrBackendTexture(int width,
                                    int height,
                                    const GrVkImageInfo& vkInfo,
@@ -492,6 +500,7 @@
         , fHeight(height)
         , fMipmapped(GrMipmapped(vkInfo.fLevelCount > 1))
         , fBackend(GrBackendApi::kVulkan)
+        , fTextureType(vk_image_info_to_texture_type(vkInfo))
         , fVkInfo(apply_default_usage_flags(vkInfo, kDefaultTexRTUsageFlags))
         , fMutableState(std::move(mutableState)) {}
 #endif
@@ -507,6 +516,7 @@
         , fHeight(height)
         , fMipmapped(mipmapped)
         , fBackend(GrBackendApi::kOpenGL)
+        , fTextureType(gl_target_to_gr_target(glInfo.fTarget))
         , fGLInfo(glInfo, params.release()) {}
 
 sk_sp<GrGLTextureParameters> GrBackendTexture::getGLTextureParams() const {
@@ -527,6 +537,7 @@
         , fHeight(height)
         , fMipmapped(mipmapped)
         , fBackend(GrBackendApi::kMetal)
+        , fTextureType(GrTextureType::k2D)
         , fMtlInfo(mtlInfo) {}
 #endif
 
@@ -546,6 +557,7 @@
         , fHeight(height)
         , fMipmapped(GrMipmapped(d3dInfo.fLevelCount > 1))
         , fBackend(GrBackendApi::kDirect3D)
+        , fTextureType(GrTextureType::k2D)
         , fD3DInfo(d3dInfo, state.release()) {}
 #endif
 
@@ -569,6 +581,7 @@
         , fHeight(height)
         , fMipmapped(mipmapped)
         , fBackend(GrBackendApi::kMock)
+        , fTextureType(GrTextureType::k2D)
         , fMockInfo(mockInfo) {}
 
 GrBackendTexture::~GrBackendTexture() {
@@ -610,6 +623,7 @@
     fHeight = that.fHeight;
     fMipmapped = that.fMipmapped;
     fBackend = that.fBackend;
+    fTextureType = that.fTextureType;
 
     switch (that.fBackend) {
 #ifdef SK_GL
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 47368bd..5c64eb6 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -309,9 +309,11 @@
 
 bool GrCaps::validateSurfaceParams(const SkISize& dimensions, const GrBackendFormat& format,
                                    GrRenderable renderable, int renderTargetSampleCnt,
-                                   GrMipmapped mipped) const {
-    if (!this->isFormatTexturable(format)) {
-        return false;
+                                   GrMipmapped mipped, GrTextureType textureType) const {
+    if (textureType != GrTextureType::kNone) {
+        if (!this->isFormatTexturable(format, textureType)) {
+            return false;
+        }
     }
 
     if (GrMipmapped::kYes == mipped && !this->mipmapSupport()) {
@@ -386,7 +388,7 @@
     }
 
     auto format = this->onGetDefaultBackendFormat(colorType);
-    if (!this->isFormatTexturable(format)) {
+    if (!this->isFormatTexturable(format, GrTextureType::k2D)) {
         return {};
     }
     if (!this->areColorTypeAndFormatCompatible(colorType, format)) {
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 8baa825..25404d6 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -221,8 +221,9 @@
 
     bool isFormatCompressed(const GrBackendFormat& format) const;
 
-    // Can a texture be made with the GrBackendFormat, and then be bound and sampled in a shader.
-    virtual bool isFormatTexturable(const GrBackendFormat&) const = 0;
+    // Can a texture be made with the GrBackendFormat and texture type, and then be bound and
+    // sampled in a shader.
+    virtual bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const = 0;
 
     // Returns whether a texture of the given format can be copied to a texture of the same format.
     virtual bool isFormatCopyable(const GrBackendFormat&) const = 0;
@@ -420,7 +421,7 @@
     }
 
     bool validateSurfaceParams(const SkISize&, const GrBackendFormat&, GrRenderable renderable,
-                               int renderTargetSampleCnt, GrMipmapped) const;
+                               int renderTargetSampleCnt, GrMipmapped, GrTextureType) const;
 
     bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat& format) const;
 
diff --git a/src/gpu/GrContextThreadSafeProxy.cpp b/src/gpu/GrContextThreadSafeProxy.cpp
index cbdcaa0..573fa6e 100644
--- a/src/gpu/GrContextThreadSafeProxy.cpp
+++ b/src/gpu/GrContextThreadSafeProxy.cpp
@@ -99,7 +99,7 @@
         return {};
     }
 
-    if (isTextureable && !fCaps->isFormatTexturable(backendFormat)) {
+    if (isTextureable && !fCaps->isFormatTexturable(backendFormat, backendFormat.textureType())) {
         // Skia doesn't agree that this is textureable.
         return {};
     }
@@ -158,7 +158,7 @@
 
     GrBackendFormat format = fCaps->getBackendFormatFromCompressionType(c);
 
-    SkASSERT(!format.isValid() || fCaps->isFormatTexturable(format));
+    SkASSERT(!format.isValid() || fCaps->isFormatTexturable(format, GrTextureType::k2D));
     return format;
 }
 
diff --git a/src/gpu/GrDynamicAtlas.cpp b/src/gpu/GrDynamicAtlas.cpp
index 7fe35a0..b1e5bb1 100644
--- a/src/gpu/GrDynamicAtlas.cpp
+++ b/src/gpu/GrDynamicAtlas.cpp
@@ -94,8 +94,14 @@
             [this](GrResourceProvider* resourceProvider, const LazyAtlasDesc& desc) {
                 if (!fBackingTexture) {
                     fBackingTexture = resourceProvider->createTexture(
-                            fTextureProxy->backingStoreDimensions(), desc.fFormat, desc.fRenderable,
-                            desc.fSampleCnt, desc.fMipmapped, desc.fBudgeted, desc.fProtected);
+                            fTextureProxy->backingStoreDimensions(),
+                            desc.fFormat,
+                            desc.fFormat.textureType(),
+                            desc.fRenderable,
+                            desc.fSampleCnt,
+                            desc.fMipmapped,
+                            desc.fBudgeted,
+                            desc.fProtected);
                 }
                 return GrSurfaceProxy::LazyCallbackResult(fBackingTexture);
             },
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index e8f33ae..023d510 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -98,6 +98,7 @@
 
 sk_sp<GrTexture> GrGpu::createTextureCommon(SkISize dimensions,
                                             const GrBackendFormat& format,
+                                            GrTextureType textureType,
                                             GrRenderable renderable,
                                             int renderTargetSampleCnt,
                                             SkBudgeted budgeted,
@@ -110,8 +111,12 @@
     }
 
     GrMipmapped mipMapped = mipLevelCount > 1 ? GrMipmapped::kYes : GrMipmapped::kNo;
-    if (!this->caps()->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                             mipMapped)) {
+    if (!this->caps()->validateSurfaceParams(dimensions,
+                                             format,
+                                             renderable,
+                                             renderTargetSampleCnt,
+                                             mipMapped,
+                                             textureType)) {
         return nullptr;
     }
 
@@ -147,6 +152,7 @@
 
 sk_sp<GrTexture> GrGpu::createTexture(SkISize dimensions,
                                       const GrBackendFormat& format,
+                                      GrTextureType textureType,
                                       GrRenderable renderable,
                                       int renderTargetSampleCnt,
                                       GrMipmapped mipMapped,
@@ -159,8 +165,15 @@
     }
     uint32_t levelClearMask =
             this->caps()->shouldInitializeTextures() ? (1 << mipLevelCount) - 1 : 0;
-    auto tex = this->createTextureCommon(dimensions, format, renderable, renderTargetSampleCnt,
-                                         budgeted, isProtected, mipLevelCount, levelClearMask);
+    auto tex = this->createTextureCommon(dimensions,
+                                         format,
+                                         textureType,
+                                         renderable,
+                                         renderTargetSampleCnt,
+                                         budgeted,
+                                         isProtected,
+                                         mipLevelCount,
+                                         levelClearMask);
     if (tex && mipMapped == GrMipmapped::kYes && levelClearMask) {
         tex->markMipmapsClean();
     }
@@ -169,6 +182,7 @@
 
 sk_sp<GrTexture> GrGpu::createTexture(SkISize dimensions,
                                       const GrBackendFormat& format,
+                                      GrTextureType textureType,
                                       GrRenderable renderable,
                                       int renderTargetSampleCnt,
                                       SkBudgeted budgeted,
@@ -199,8 +213,15 @@
         }
     }
 
-    auto tex = this->createTextureCommon(dimensions, format, renderable, renderTargetSampleCnt,
-                                         budgeted, isProtected, texelLevelCount, levelClearMask);
+    auto tex = this->createTextureCommon(dimensions,
+                                         format,
+                                         textureType,
+                                         renderable,
+                                         renderTargetSampleCnt,
+                                         budgeted,
+                                         isProtected,
+                                         texelLevelCount,
+                                         levelClearMask);
     if (tex) {
         bool markMipLevelsClean = false;
         // Currently if level 0 does not have pixels then no other level may, as enforced by
@@ -245,12 +266,16 @@
     if (!data) {
         return nullptr;
     }
-    if (!this->caps()->isFormatTexturable(format)) {
-        return nullptr;
-    }
 
     // TODO: expand CompressedDataIsCorrect to work here too
     SkImage::CompressionType compressionType = GrBackendFormatToCompressionType(format);
+    if (compressionType == SkImage::CompressionType::kNone) {
+        return nullptr;
+    }
+
+    if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
+        return nullptr;
+    }
 
     if (dataSize < SkCompressedDataSize(compressionType, dimensions, nullptr,
                                         mipMapped == GrMipmapped::kYes)) {
@@ -270,7 +295,7 @@
     const GrCaps* caps = this->caps();
     SkASSERT(caps);
 
-    if (!caps->isFormatTexturable(backendTex.getBackendFormat())) {
+    if (!caps->isFormatTexturable(backendTex.getBackendFormat(), backendTex.textureType())) {
         return nullptr;
     }
     if (backendTex.width() > caps->maxTextureSize() ||
@@ -289,7 +314,7 @@
     const GrCaps* caps = this->caps();
     SkASSERT(caps);
 
-    if (!caps->isFormatTexturable(backendTex.getBackendFormat())) {
+    if (!caps->isFormatTexturable(backendTex.getBackendFormat(), backendTex.textureType())) {
         return nullptr;
     }
     if (backendTex.width() > caps->maxTextureSize() ||
@@ -311,7 +336,7 @@
 
     const GrCaps* caps = this->caps();
 
-    if (!caps->isFormatTexturable(backendTex.getBackendFormat()) ||
+    if (!caps->isFormatTexturable(backendTex.getBackendFormat(), backendTex.textureType()) ||
         !caps->isFormatRenderable(backendTex.getBackendFormat(), sampleCnt)) {
         return nullptr;
     }
@@ -391,7 +416,8 @@
     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
     SkASSERT(surface);
     SkASSERT(!surface->framebufferOnly());
-    SkASSERT(this->caps()->isFormatTexturable(surface->backendFormat()));
+    SkASSERT(this->caps()->areColorTypeAndFormatCompatible(surfaceColorType,
+                                                           surface->backendFormat()));
 
     if (!SkIRect::MakeSize(surface->dimensions()).contains(rect)) {
         return false;
@@ -523,7 +549,8 @@
     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
     SkASSERT(surface);
     SkASSERT(transferBuffer);
-    SkASSERT(this->caps()->isFormatTexturable(surface->backendFormat()));
+    SkASSERT(this->caps()->areColorTypeAndFormatCompatible(surfaceColorType,
+                                                           surface->backendFormat()));
 
 #ifdef SK_DEBUG
     auto supportedRead = this->caps()->supportedReadPixelsColorType(
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index e0f93aa..a6b330e 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -130,6 +130,7 @@
      */
     sk_sp<GrTexture> createTexture(SkISize dimensions,
                                    const GrBackendFormat& format,
+                                   GrTextureType textureType,
                                    GrRenderable renderable,
                                    int renderTargetSampleCnt,
                                    SkBudgeted budgeted,
@@ -144,6 +145,7 @@
      */
     sk_sp<GrTexture> createTexture(SkISize dimensions,
                                    const GrBackendFormat& format,
+                                   GrTextureType textureType,
                                    GrRenderable renderable,
                                    int renderTargetSampleCnt,
                                    GrMipmapped mipMapped,
@@ -798,6 +800,7 @@
 
     sk_sp<GrTexture> createTextureCommon(SkISize,
                                          const GrBackendFormat&,
+                                         GrTextureType textureType,
                                          GrRenderable,
                                          int renderTargetSampleCnt,
                                          SkBudgeted,
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 8eb66f2..a05e84a 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -142,11 +142,21 @@
     sk_sp<GrTexture> tex;
 
     if (SkBackingFit::kApprox == fit) {
-        tex = resourceProvider->createApproxTexture(dimensions, format, renderable,
-                                                    renderTargetSampleCnt, isProtected);
+        tex = resourceProvider->createApproxTexture(dimensions,
+                                                    format,
+                                                    format.textureType(),
+                                                    renderable,
+                                                    renderTargetSampleCnt,
+                                                    isProtected);
     } else {
-        tex = resourceProvider->createTexture(dimensions, format, renderable, renderTargetSampleCnt,
-                                              GrMipmapped::kNo, budgeted, isProtected);
+        tex = resourceProvider->createTexture(dimensions,
+                                              format,
+                                              format.textureType(),
+                                              renderable,
+                                              renderTargetSampleCnt,
+                                              GrMipmapped::kNo,
+                                              budgeted,
+                                              isProtected);
     }
     if (!tex) {
         return nullptr;
@@ -327,8 +337,16 @@
                 GrMipLevel mipLevel = {bitmap.getPixels(), bitmap.rowBytes(), nullptr};
                 auto colorType = SkColorTypeToGrColorType(bitmap.colorType());
                 return LazyCallbackResult(resourceProvider->createTexture(
-                        desc.fDimensions, desc.fFormat, colorType, desc.fRenderable,
-                        desc.fSampleCnt, desc.fBudgeted, desc.fFit, desc.fProtected, mipLevel));
+                        desc.fDimensions,
+                        desc.fFormat,
+                        desc.fFormat.textureType(),
+                        colorType,
+                        desc.fRenderable,
+                        desc.fSampleCnt,
+                        desc.fBudgeted,
+                        desc.fFit,
+                        desc.fProtected,
+                        mipLevel));
             },
             format, dims, GrMipmapped::kNo, GrMipmapStatus::kNotAllocated,
             GrInternalSurfaceFlags::kNone, fit, budgeted, GrProtected::kNo, UseAllocator::kYes);
@@ -375,8 +393,16 @@
                     SkASSERT(generatedMipLevel.fPixmap.colorType() == bitmap.colorType());
                 }
                 return LazyCallbackResult(resourceProvider->createTexture(
-                        desc.fDimensions, desc.fFormat, colorType, GrRenderable::kNo, 1,
-                        desc.fBudgeted, GrMipMapped::kYes, GrProtected::kNo, texels.get()));
+                        desc.fDimensions,
+                        desc.fFormat,
+                        desc.fFormat.textureType(),
+                        colorType,
+                        GrRenderable::kNo,
+                        1,
+                        desc.fBudgeted,
+                        GrMipMapped::kYes,
+                        GrProtected::kNo,
+                        texels.get()));
             },
             format, dims, GrMipmapped::kYes, GrMipmapStatus::kValid, GrInternalSurfaceFlags::kNone,
             SkBackingFit::kExact, budgeted, GrProtected::kNo, UseAllocator::kYes);
@@ -420,8 +446,12 @@
         }
     }
 
-    if (!caps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                     mipMapped)) {
+    if (!caps->validateSurfaceParams(dimensions,
+                                     format,
+                                     renderable,
+                                     renderTargetSampleCnt,
+                                     mipMapped,
+                                     GrTextureType::k2D)) {
         return nullptr;
     }
     GrMipmapStatus mipmapStatus = (GrMipmapped::kYes == mipMapped)
@@ -454,7 +484,7 @@
 
     GrBackendFormat format = this->caps()->getBackendFormatFromCompressionType(compressionType);
 
-    if (!this->caps()->isFormatTexturable(format)) {
+    if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
         return nullptr;
     }
 
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index bfd5a72..a85b5f1 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -43,6 +43,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(SkISize dimensions,
                                                    const GrBackendFormat& format,
+                                                   GrTextureType textureType,
                                                    GrColorType colorType,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt,
@@ -61,14 +62,24 @@
         numMipLevels = SkMipmap::ComputeLevelCount(dimensions.fWidth, dimensions.fHeight) + 1;
     }
 
-    if (!fCaps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                      mipmapped)) {
+    if (!fCaps->validateSurfaceParams(dimensions,
+                                      format,
+                                      renderable,
+                                      renderTargetSampleCnt,
+                                      mipmapped,
+                                      textureType)) {
         return nullptr;
     }
     // Current rule is that you can provide no level data, just the base, or all the levels.
     bool hasPixels = texels[0].fPixels;
-    auto scratch = this->getExactScratch(dimensions, format, renderable, renderTargetSampleCnt,
-                                         budgeted, mipmapped, isProtected);
+    auto scratch = this->getExactScratch(dimensions,
+                                         format,
+                                         textureType,
+                                         renderable,
+                                         renderTargetSampleCnt,
+                                         budgeted,
+                                         mipmapped,
+                                         isProtected);
     if (scratch) {
         if (!hasPixels) {
             return scratch;
@@ -85,20 +96,33 @@
             return nullptr;
         }
     }
-    return fGpu->createTexture(dimensions, format, renderable, renderTargetSampleCnt, budgeted,
-                               isProtected, colorType, tempColorType, tmpTexels.get(),
+    return fGpu->createTexture(dimensions,
+                               format,
+                               textureType,
+                               renderable,
+                               renderTargetSampleCnt,
+                               budgeted,
+                               isProtected,
+                               colorType,
+                               tempColorType,
+                               tmpTexels.get(),
                                numMipLevels);
 }
 
 sk_sp<GrTexture> GrResourceProvider::getExactScratch(SkISize dimensions,
                                                      const GrBackendFormat& format,
+                                                     GrTextureType textureType,
                                                      GrRenderable renderable,
                                                      int renderTargetSampleCnt,
                                                      SkBudgeted budgeted,
                                                      GrMipmapped mipmapped,
                                                      GrProtected isProtected) {
-    sk_sp<GrTexture> tex(this->findAndRefScratchTexture(dimensions, format, renderable,
-                                                        renderTargetSampleCnt, mipmapped,
+    sk_sp<GrTexture> tex(this->findAndRefScratchTexture(dimensions,
+                                                        format,
+                                                        textureType,
+                                                        renderable,
+                                                        renderTargetSampleCnt,
+                                                        mipmapped,
                                                         isProtected));
     if (tex && SkBudgeted::kNo == budgeted) {
         tex->resourcePriv().makeUnbudgeted();
@@ -109,6 +133,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(SkISize dimensions,
                                                    const GrBackendFormat& format,
+                                                   GrTextureType textureType,
                                                    GrColorType colorType,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt,
@@ -127,19 +152,27 @@
             return nullptr;
         }
         if (!fCaps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                          GrMipmapped::kNo)) {
+                                          GrMipmapped::kNo, textureType)) {
             return nullptr;
         }
 
-        auto tex = this->createApproxTexture(dimensions, format, renderable, renderTargetSampleCnt,
-                                             isProtected);
+        auto tex = this->createApproxTexture(dimensions, format, textureType, renderable,
+                                             renderTargetSampleCnt, isProtected);
         if (!tex) {
             return nullptr;
         }
         return this->writePixels(std::move(tex), colorType, dimensions, &mipLevel, 1);
     } else {
-        return this->createTexture(dimensions, format, colorType, renderable, renderTargetSampleCnt,
-                                   budgeted, GrMipmapped::kNo, isProtected, &mipLevel);
+        return this->createTexture(dimensions,
+                                   format,
+                                   textureType,
+                                   colorType,
+                                   renderable,
+                                   renderTargetSampleCnt,
+                                   budgeted,
+                                   GrMipmapped::kNo,
+                                   isProtected,
+                                   &mipLevel);
     }
 }
 
@@ -159,6 +192,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(SkISize dimensions,
                                                    const GrBackendFormat& format,
+                                                   GrTextureType textureType,
                                                    GrRenderable renderable,
                                                    int renderTargetSampleCnt,
                                                    GrMipmapped mipmapped,
@@ -170,7 +204,7 @@
     }
 
     if (!fCaps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                      mipmapped)) {
+                                      mipmapped, textureType)) {
         return nullptr;
     }
 
@@ -180,14 +214,26 @@
 
     // TODO: Support GrMipmapped::kYes in scratch texture lookup here.
     sk_sp<GrTexture> tex =
-            this->getExactScratch(dimensions, format, renderable, renderTargetSampleCnt, budgeted,
-                                  mipmapped, isProtected);
+            this->getExactScratch(dimensions,
+                                  format,
+                                  textureType,
+                                  renderable,
+                                  renderTargetSampleCnt,
+                                  budgeted,
+                                  mipmapped,
+                                  isProtected);
     if (tex) {
         return tex;
     }
 
-    return fGpu->createTexture(dimensions, format, renderable, renderTargetSampleCnt, mipmapped,
-                               budgeted, isProtected);
+    return fGpu->createTexture(dimensions,
+                               format,
+                               textureType,
+                               renderable,
+                               renderTargetSampleCnt,
+                               mipmapped,
+                               budgeted,
+                               isProtected);
 }
 
 // Map 'value' to a larger multiple of 2. Values <= 'kMagicTol' will pop up to
@@ -221,6 +267,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::createApproxTexture(SkISize dimensions,
                                                          const GrBackendFormat& format,
+                                                         GrTextureType textureType,
                                                          GrRenderable renderable,
                                                          int renderTargetSampleCnt,
                                                          GrProtected isProtected) {
@@ -235,20 +282,26 @@
     SkASSERT(!this->caps()->isFormatCompressed(format));
 
     if (!fCaps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                      GrMipmapped::kNo)) {
+                                      GrMipmapped::kNo, textureType)) {
         return nullptr;
     }
 
     auto copyDimensions = MakeApprox(dimensions);
 
-    if (auto tex = this->findAndRefScratchTexture(copyDimensions, format, renderable,
+    if (auto tex = this->findAndRefScratchTexture(copyDimensions, format, textureType, renderable,
                                                   renderTargetSampleCnt, GrMipmapped::kNo,
                                                   isProtected)) {
         return tex;
     }
 
-    return fGpu->createTexture(copyDimensions, format, renderable, renderTargetSampleCnt,
-                               GrMipmapped::kNo, SkBudgeted::kYes, isProtected);
+    return fGpu->createTexture(copyDimensions,
+                               format,
+                               textureType,
+                               renderable,
+                               renderTargetSampleCnt,
+                               GrMipmapped::kNo,
+                               SkBudgeted::kYes,
+                               isProtected);
 }
 
 sk_sp<GrTexture> GrResourceProvider::findAndRefScratchTexture(const GrScratchKey& key) {
@@ -266,6 +319,7 @@
 
 sk_sp<GrTexture> GrResourceProvider::findAndRefScratchTexture(SkISize dimensions,
                                                               const GrBackendFormat& format,
+                                                              GrTextureType textureType,
                                                               GrRenderable renderable,
                                                               int renderTargetSampleCnt,
                                                               GrMipmapped mipmapped,
@@ -274,7 +328,7 @@
     SkASSERT(!this->isAbandoned());
     SkASSERT(!this->caps()->isFormatCompressed(format));
     SkASSERT(fCaps->validateSurfaceParams(dimensions, format, renderable, renderTargetSampleCnt,
-                                          GrMipmapped::kNo));
+                                          GrMipmapped::kNo, textureType));
 
     // 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.
@@ -596,8 +650,12 @@
         return nullptr;
     }
 
-    if (!fCaps->validateSurfaceParams(
-                dimensions, format, GrRenderable::kYes, sampleCnt, GrMipmapped::kNo)) {
+    if (!fCaps->validateSurfaceParams(dimensions,
+                                      format,
+                                      GrRenderable::kYes,
+                                      sampleCnt,
+                                      GrMipmapped::kNo,
+                                      GrTextureType::kNone)) {
         return nullptr;
     }
 
@@ -633,8 +691,12 @@
         return nullptr;
     }
 
-    if (!fCaps->validateSurfaceParams(dimensions, format, GrRenderable::kYes, sampleCnt,
-                                      GrMipmapped::kNo)) {
+    if (!fCaps->validateSurfaceParams(dimensions,
+                                      format,
+                                      GrRenderable::kYes,
+                                      sampleCnt,
+                                      GrMipmapped::kNo,
+                                      GrTextureType::kNone)) {
         return nullptr;
     }
 
@@ -653,8 +715,12 @@
     ASSERT_SINGLE_OWNER
     SkASSERT(!this->isAbandoned());
     SkASSERT(!this->caps()->isFormatCompressed(format));
-    SkASSERT(fCaps->validateSurfaceParams(dimensions, format, GrRenderable::kYes, sampleCnt,
-                                          GrMipmapped::kNo));
+    SkASSERT(fCaps->validateSurfaceParams(dimensions,
+                                          format,
+                                          GrRenderable::kYes,
+                                          sampleCnt,
+                                          GrMipmapped::kNo,
+                                          GrTextureType::kNone));
 
     GrScratchKey key;
     GrAttachment::ComputeScratchKey(*this->caps(), format, dimensions,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index c1f46fd..bde5ffa 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -62,6 +62,7 @@
      */
     sk_sp<GrTexture> createApproxTexture(SkISize dimensions,
                                          const GrBackendFormat& format,
+                                         GrTextureType textureType,
                                          GrRenderable renderable,
                                          int renderTargetSampleCnt,
                                          GrProtected isProtected);
@@ -69,6 +70,7 @@
     /** Create an exact fit texture with no initial data to upload. */
     sk_sp<GrTexture> createTexture(SkISize dimensions,
                                    const GrBackendFormat& format,
+                                   GrTextureType textureType,
                                    GrRenderable renderable,
                                    int renderTargetSampleCnt,
                                    GrMipmapped mipMapped,
@@ -82,6 +84,7 @@
      */
     sk_sp<GrTexture> createTexture(SkISize dimensions,
                                    const GrBackendFormat& format,
+                                   GrTextureType textureType,
                                    GrColorType colorType,
                                    GrRenderable renderable,
                                    int renderTargetSampleCnt,
@@ -97,6 +100,7 @@
      */
     sk_sp<GrTexture> createTexture(SkISize dimensions,
                                    const GrBackendFormat&,
+                                   GrTextureType textureType,
                                    GrColorType srcColorType,
                                    GrRenderable,
                                    int renderTargetSampleCnt,
@@ -112,6 +116,7 @@
     sk_sp<GrTexture> findAndRefScratchTexture(const GrScratchKey&);
     sk_sp<GrTexture> findAndRefScratchTexture(SkISize dimensions,
                                               const GrBackendFormat&,
+                                              GrTextureType textureType,
                                               GrRenderable,
                                               int renderTargetSampleCnt,
                                               GrMipmapped,
@@ -338,6 +343,7 @@
      */
     sk_sp<GrTexture> getExactScratch(SkISize dimensions,
                                      const GrBackendFormat&,
+                                     GrTextureType,
                                      GrRenderable,
                                      int renderTargetSampleCnt,
                                      SkBudgeted,
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index e4a3e77..44713fe 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -112,11 +112,21 @@
 
     sk_sp<GrSurface> surface;
     if (SkBackingFit::kApprox == fFit) {
-        surface = resourceProvider->createApproxTexture(fDimensions, fFormat, renderable, sampleCnt,
+        surface = resourceProvider->createApproxTexture(fDimensions,
+                                                        fFormat,
+                                                        fFormat.textureType(),
+                                                        renderable,
+                                                        sampleCnt,
                                                         fIsProtected);
     } else {
-        surface = resourceProvider->createTexture(fDimensions, fFormat, renderable, sampleCnt,
-                                                  mipMapped, fBudgeted, fIsProtected);
+        surface = resourceProvider->createTexture(fDimensions,
+                                                  fFormat,
+                                                  fFormat.textureType(),
+                                                  renderable,
+                                                  sampleCnt,
+                                                  mipMapped,
+                                                  fBudgeted,
+                                                  fIsProtected);
     }
     if (!surface) {
         return nullptr;
diff --git a/src/gpu/d3d/GrD3DCaps.cpp b/src/gpu/d3d/GrD3DCaps.cpp
index 5398f2a..fa814b1 100644
--- a/src/gpu/d3d/GrD3DCaps.cpp
+++ b/src/gpu/d3d/GrD3DCaps.cpp
@@ -783,7 +783,7 @@
     }
 }
 
-bool GrD3DCaps::isFormatTexturable(const GrBackendFormat& format) const {
+bool GrD3DCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
     DXGI_FORMAT dxgiFormat;
     if (!format.asDxgiFormat(&dxgiFormat)) {
         return false;
diff --git a/src/gpu/d3d/GrD3DCaps.h b/src/gpu/d3d/GrD3DCaps.h
index 879bb2e..efa68b7 100644
--- a/src/gpu/d3d/GrD3DCaps.h
+++ b/src/gpu/d3d/GrD3DCaps.h
@@ -28,7 +28,7 @@
 
     bool isFormatSRGB(const GrBackendFormat&) const override;
 
-    bool isFormatTexturable(const GrBackendFormat&) const override;
+    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
     bool isFormatTexturable(DXGI_FORMAT) const;
 
     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index 958a482..b48b687 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -687,7 +687,7 @@
                                GrColorType colorType,
                                const GrMipLevel* texels,
                                int mipLevelCount) {
-    SkASSERT(this->caps()->isFormatTexturable(tex->backendFormat()));
+    SkASSERT(this->d3dCaps().isFormatTexturable(tex->dxgiFormat()));
     // The assumption is either that we have no mipmaps, or that our rect is the entire texture
     SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(tex->dimensions()));
 
diff --git a/src/gpu/dawn/GrDawnCaps.cpp b/src/gpu/dawn/GrDawnCaps.cpp
index 978d18e..ed8387d 100644
--- a/src/gpu/dawn/GrDawnCaps.cpp
+++ b/src/gpu/dawn/GrDawnCaps.cpp
@@ -37,7 +37,7 @@
     return false;
 }
 
-bool GrDawnCaps::isFormatTexturable(const GrBackendFormat& format) const {
+bool GrDawnCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
     // Currently, all the formats in GrDawnFormatToPixelConfig are texturable.
     wgpu::TextureFormat dawnFormat;
     return format.asDawnFormat(&dawnFormat);
diff --git a/src/gpu/dawn/GrDawnCaps.h b/src/gpu/dawn/GrDawnCaps.h
index c52dd45..0002c3d 100644
--- a/src/gpu/dawn/GrDawnCaps.h
+++ b/src/gpu/dawn/GrDawnCaps.h
@@ -27,7 +27,7 @@
 
     bool isFormatCopyable(const GrBackendFormat& format) const override { return true; }
 
-    bool isFormatTexturable(const GrBackendFormat& format) const override;
+    bool isFormatTexturable(const GrBackendFormat& format, GrTextureType) const override;
 
     SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
                                                  const GrBackendFormat& surfaceFormat,
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 809823b..5c7fb18 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -4450,8 +4450,8 @@
     return format.asGLFormat() == GrGLFormat::kSRGB8_ALPHA8;
 }
 
-bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format) const {
-    if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
+bool GrGLCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType textureType) const {
+    if (textureType == GrTextureType::kRectangle && !this->rectangleTextureSupport()) {
         return false;
     }
     return this->isFormatTexturable(format.asGLFormat());
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index e98b23f..c02193f 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -120,7 +120,7 @@
 
     bool isFormatSRGB(const GrBackendFormat&) const override;
 
-    bool isFormatTexturable(const GrBackendFormat&) const override;
+    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
     bool isFormatTexturable(GrGLFormat) const;
 
     bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 309f161..ad0a15b 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -51,7 +51,7 @@
         return GrGetColorTypeDesc(ct).encoding() == GrColorTypeEncoding::kSRGBUnorm;
     }
 
-    bool isFormatTexturable(const GrBackendFormat& format) const override {
+    bool isFormatTexturable(const GrBackendFormat& format, GrTextureType) const override {
         SkImage::CompressionType compression = format.asMockCompressionType();
         if (compression != SkImage::CompressionType::kNone) {
             return fOptions.fCompressedOptions[(int)compression].fTexturable;
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 69a9544..24177ef 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -229,7 +229,7 @@
     }
 
     auto colorType = format.asMockColorType();
-    if (!this->caps()->isFormatTexturable(format)) {
+    if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
         return GrBackendTexture();  // invalid
     }
 
@@ -247,7 +247,7 @@
         return {}; // should go through onCreateBackendTexture
     }
 
-    if (!this->caps()->isFormatTexturable(format)) {
+    if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
         return {};
     }
 
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 46698c2..1a92fbe 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -26,7 +26,7 @@
 
     bool isFormatSRGB(const GrBackendFormat&) const override;
 
-    bool isFormatTexturable(const GrBackendFormat&) const override;
+    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
     bool isFormatTexturable(MTLPixelFormat) const;
 
     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 178c8af..fc18bfe 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -373,7 +373,7 @@
     return format_is_srgb(GrBackendFormatAsMTLPixelFormat(format));
 }
 
-bool GrMtlCaps::isFormatTexturable(const GrBackendFormat& format) const {
+bool GrMtlCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
     MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
     return this->isFormatTexturable(mtlFormat);
 }
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index dcd4b47..457af45 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -366,7 +366,7 @@
                                GrColorType dataColorType,
                                const GrMipLevel texels[],
                                int mipLevelCount) {
-    SkASSERT(this->caps()->isFormatTexturable(tex->backendFormat()));
+    SkASSERT(this->mtlCaps().isFormatTexturable(tex->mtlTexture().pixelFormat));
     // The assumption is either that we have no mipmaps, or that our rect is the entire texture
     SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(tex->dimensions()));
 
@@ -475,7 +475,7 @@
 }
 
 bool GrMtlGpu::clearTexture(GrMtlTexture* tex, size_t bpp, uint32_t levelMask) {
-    SkASSERT(this->mtlCaps().isFormatTexturable(tex->backendFormat()));
+    SkASSERT(this->mtlCaps().isFormatTexturable(tex->mtlTexture().pixelFormat));
 
     if (!levelMask) {
         return true;
@@ -645,7 +645,7 @@
         return nullptr;
     }
 
-    SkASSERT(this->caps()->isFormatTexturable(format));
+    SkASSERT(this->caps()->isFormatTexturable(format, GrTextureType::k2D));
     SkASSERT(data);
 
     if (!check_max_blit_width(dimensions.width())) {
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 33f4f67..d689cb1 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -1411,7 +1411,7 @@
     return format_is_srgb(vkFormat);
 }
 
-bool GrVkCaps::isFormatTexturable(const GrBackendFormat& format) const {
+bool GrVkCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
     VkFormat vkFormat;
     if (!format.asVkFormat(&vkFormat)) {
         return false;
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 1edaa54..f781a9a 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -36,7 +36,7 @@
 
     bool isFormatSRGB(const GrBackendFormat&) const override;
 
-    bool isFormatTexturable(const GrBackendFormat&) const override;
+    bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override;
     bool isVkFormatTexturable(VkFormat) const;
 
     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 104032f..873b431 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -442,7 +442,7 @@
         return false;
     }
 
-    if (texturable && !caps->isFormatTexturable(backendFormat)) {
+    if (texturable && !caps->isFormatTexturable(backendFormat, tex.textureType())) {
         return false;
     }