Have GrVkRenderTarget only use GrVkAttachments and not derive from GrVkImage.

This change moves the color and resolve attachments used in a
GrVkRenderTarget to be a GrVkAttachment. These along with the msaa
attachment now mean that GrVkRenderTarget no longer needs to derive from
a GrVkImage.

There are a couple ugly things in this CL since GrVkTexture still is a
GrVkImage since we can't share attachments between GrVkRT and GrVkTex.
But when that gets updated in the follow on CL things will look much nicer.

Bug: skia:10727
Change-Id: I2f12674d7517c6d6dea389e2d1fb7296028bcc85
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/379576
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrAttachment.cpp b/src/gpu/GrAttachment.cpp
index 6db517d..04edf57 100644
--- a/src/gpu/GrAttachment.cpp
+++ b/src/gpu/GrAttachment.cpp
@@ -14,13 +14,28 @@
 #include "src/gpu/GrGpu.h"
 
 size_t GrAttachment::onGpuMemorySize() const {
-    GrBackendFormat format = this->backendFormat();
-    SkImage::CompressionType compression = GrBackendFormatToCompressionType(format);
+    // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
+    // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
+    // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
+    // attachment to give its own size since we don't have GrGpuResources owning other
+    // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
+    // the msaa and stencil attachments track their own size because they do get cached separately.
+    // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
+    // the owned attachments will have no size and be uncached.
+    // TODO: Once we start using texture attachments this check really should be !texture. However,
+    // until then in GrVkTextureRenderTarget we make a wrapped attachment to use for the render
+    // target which duplicates the GrTexture. These will be merged once we use texture attachments.
+    if ((fSupportedUsages & UsageFlags::kStencilAttachment) ||
+        ((fSupportedUsages & UsageFlags::kColorAttachment) && fSampleCnt > 1)) {
+        GrBackendFormat format = this->backendFormat();
+        SkImage::CompressionType compression = GrBackendFormatToCompressionType(format);
 
-    uint64_t size = GrNumBlocks(compression, this->dimensions());
-    size *= GrBackendFormatBytesPerBlock(this->backendFormat());
-    size *= this->numSamples();
-    return size;
+        uint64_t size = GrNumBlocks(compression, this->dimensions());
+        size *= GrBackendFormatBytesPerBlock(this->backendFormat());
+        size *= this->numSamples();
+        return size;
+    }
+    return 0;
 }
 
 static void build_key(GrResourceKey::Builder* builder,
diff --git a/src/gpu/vk/GrVkAttachment.cpp b/src/gpu/vk/GrVkAttachment.cpp
index abf13e9..71c1808 100644
--- a/src/gpu/vk/GrVkAttachment.cpp
+++ b/src/gpu/vk/GrVkAttachment.cpp
@@ -19,12 +19,14 @@
                                UsageFlags supportedUsages,
                                const GrVkImageInfo& info,
                                sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                               sk_sp<const GrVkImageView> view,
+                               sk_sp<const GrVkImageView> framebufferView,
+                               sk_sp<const GrVkImageView> textureView,
                                SkBudgeted budgeted)
         : GrAttachment(gpu, dimensions, supportedUsages, info.fSampleCount, GrMipmapped::kNo,
                        info.fProtected)
         , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kOwned)
-        , fView(std::move(view)) {
+        , fFramebufferView(std::move(framebufferView))
+        , fTextureView(std::move(textureView)) {
     this->registerWithCache(budgeted);
 }
 
@@ -33,13 +35,16 @@
                                UsageFlags supportedUsages,
                                const GrVkImageInfo& info,
                                sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                               sk_sp<const GrVkImageView> view,
+                               sk_sp<const GrVkImageView> framebufferView,
+                               sk_sp<const GrVkImageView> textureView,
                                GrBackendObjectOwnership ownership,
-                               GrWrapCacheable cacheable)
+                               GrWrapCacheable cacheable,
+                               bool forSecondaryCB)
         : GrAttachment(gpu, dimensions, supportedUsages, info.fSampleCount, GrMipmapped::kNo,
                        info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), ownership)
-        , fView(std::move(view)) {
+        , GrVkImage(gpu, info, std::move(mutableState), ownership, forSecondaryCB)
+        , fFramebufferView(std::move(framebufferView))
+        , fTextureView(std::move(textureView)) {
     this->registerWithCacheWrapped(cacheable);
 }
 
@@ -90,6 +95,38 @@
                                 vkUsageFlags, isProtected, budgeted);
 }
 
+static bool make_views(GrVkGpu* gpu, const GrVkImageInfo& info,
+                       GrAttachment::UsageFlags attachmentUsages,
+                       sk_sp<const GrVkImageView>* framebufferView,
+                       sk_sp<const GrVkImageView>* textureView) {
+    GrVkImageView::Type viewType;
+    if (attachmentUsages & GrAttachment::UsageFlags::kStencilAttachment) {
+        // If we have stencil usage then we shouldn't have any other usages
+        SkASSERT(attachmentUsages == GrAttachment::UsageFlags::kStencilAttachment);
+        viewType = GrVkImageView::kStencil_Type;
+    } else {
+        viewType = GrVkImageView::kColor_Type;
+    }
+
+    if (SkToBool(attachmentUsages & GrAttachment::UsageFlags::kStencilAttachment) ||
+        SkToBool(attachmentUsages & GrAttachment::UsageFlags::kColorAttachment)) {
+        // Attachments can only have a mip level of 1
+        *framebufferView = GrVkImageView::Make(gpu, info.fImage, info.fFormat, viewType, 1,
+                                               info.fYcbcrConversionInfo);
+        if (!*framebufferView) {
+            return false;
+        }
+    }
+
+    if (attachmentUsages & GrAttachment::UsageFlags::kTexture) {
+        *textureView = GrVkImageView::Make(gpu, info.fImage, info.fFormat, viewType,
+                                           info.fLevelCount, info.fYcbcrConversionInfo);
+        if (!*textureView) {
+            return false;
+        }
+    }
+    return true;
+}
 
 sk_sp<GrVkAttachment> GrVkAttachment::Make(GrVkGpu* gpu,
                                            SkISize dimensions,
@@ -116,18 +153,9 @@
         return nullptr;
     }
 
-    GrVkImageView::Type viewType;
-    if (attachmentUsages & UsageFlags::kStencilAttachment) {
-        // If we have stencil usage than we should have any other usages
-        SkASSERT(attachmentUsages == UsageFlags::kStencilAttachment);
-        viewType = GrVkImageView::kStencil_Type;
-    } else {
-        viewType = GrVkImageView::kColor_Type;
-    }
-
-    sk_sp<const GrVkImageView> imageView = GrVkImageView::Make(
-            gpu, info.fImage, format, viewType, info.fLevelCount, info.fYcbcrConversionInfo);
-    if (!imageView) {
+    sk_sp<const GrVkImageView> framebufferView;
+    sk_sp<const GrVkImageView> textureView;
+    if (!make_views(gpu, info, attachmentUsages, &framebufferView, &textureView)) {
         GrVkImage::DestroyImageInfo(gpu, &info);
         return nullptr;
     }
@@ -135,56 +163,57 @@
     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(
             new GrBackendSurfaceMutableStateImpl(info.fImageLayout, info.fCurrentQueueFamily));
     return sk_sp<GrVkAttachment>(new GrVkAttachment(gpu, dimensions, attachmentUsages, info,
-                                                    std::move(mutableState), std::move(imageView),
+                                                    std::move(mutableState),
+                                                    std::move(framebufferView),
+                                                    std::move(textureView),
                                                     budgeted));
 }
 
-sk_sp<GrAttachment> GrVkAttachment::MakeWrapped(
+sk_sp<GrVkAttachment> GrVkAttachment::MakeWrapped(
         GrVkGpu* gpu,
         SkISize dimensions,
         const GrVkImageInfo& info,
         sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
         UsageFlags attachmentUsages,
         GrWrapOwnership ownership,
-        GrWrapCacheable cacheable) {
-    GrVkImageView::Type viewType;
-    if (attachmentUsages & UsageFlags::kStencilAttachment) {
-        // If we have stencil usage than we should not have any other usages
-        SkASSERT(attachmentUsages == UsageFlags::kStencilAttachment);
-        viewType = GrVkImageView::kStencil_Type;
-    } else {
-        viewType = GrVkImageView::kColor_Type;
-    }
-
-    sk_sp<const GrVkImageView> imageView = GrVkImageView::Make(
-            gpu, info.fImage, info.fFormat, viewType, info.fLevelCount, info.fYcbcrConversionInfo);
-    if (!imageView) {
-        return nullptr;
+        GrWrapCacheable cacheable,
+        bool forSecondaryCB) {
+    sk_sp<const GrVkImageView> framebufferView;
+    sk_sp<const GrVkImageView> textureView;
+    if (!forSecondaryCB) {
+        if (!make_views(gpu, info, attachmentUsages, &framebufferView, &textureView)) {
+            return nullptr;
+        }
     }
 
      GrBackendObjectOwnership backendOwnership = kBorrow_GrWrapOwnership == ownership
             ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
 
     return sk_sp<GrVkAttachment>(new GrVkAttachment(gpu, dimensions, attachmentUsages, info,
-                                                    std::move(mutableState), std::move(imageView),
-                                                    backendOwnership, cacheable));
+                                                    std::move(mutableState),
+                                                    std::move(framebufferView),
+                                                    std::move(textureView),
+                                                    backendOwnership, cacheable, forSecondaryCB));
 }
 
 GrVkAttachment::~GrVkAttachment() {
     // should have been released or abandoned first
-    SkASSERT(!fView);
+    SkASSERT(!fFramebufferView);
+    SkASSERT(!fTextureView);
 }
 
 void GrVkAttachment::onRelease() {
     this->releaseImage();
-    fView.reset();
+    fFramebufferView.reset();
+    fTextureView.reset();
 
     GrAttachment::onRelease();
 }
 
 void GrVkAttachment::onAbandon() {
     this->releaseImage();
-    fView.reset();
+    fFramebufferView.reset();
+    fTextureView.reset();
 
     GrAttachment::onAbandon();
 }
diff --git a/src/gpu/vk/GrVkAttachment.h b/src/gpu/vk/GrVkAttachment.h
index b36f2ae..bbe09ac 100644
--- a/src/gpu/vk/GrVkAttachment.h
+++ b/src/gpu/vk/GrVkAttachment.h
@@ -37,20 +37,22 @@
                                              SkBudgeted budgeted,
                                              GrProtected isProtected);
 
-    static sk_sp<GrAttachment> MakeWrapped(GrVkGpu* gpu,
-                                           SkISize dimensions,
-                                           const GrVkImageInfo&,
-                                           sk_sp<GrBackendSurfaceMutableStateImpl>,
-                                           UsageFlags attachmentUsages,
-                                           GrWrapOwnership,
-                                           GrWrapCacheable);
+    static sk_sp<GrVkAttachment> MakeWrapped(GrVkGpu* gpu,
+                                             SkISize dimensions,
+                                             const GrVkImageInfo&,
+                                             sk_sp<GrBackendSurfaceMutableStateImpl>,
+                                             UsageFlags attachmentUsages,
+                                             GrWrapOwnership,
+                                             GrWrapCacheable,
+                                             bool forSecondaryCB = false);
 
     ~GrVkAttachment() override;
 
     GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
 
     const GrManagedResource* imageResource() const { return this->resource(); }
-    const GrVkImageView* view() const { return fView.get(); }
+    const GrVkImageView* framebufferView() const { return fFramebufferView.get(); }
+    const GrVkImageView* textureView() const { return fTextureView.get(); }
 
 protected:
     void onRelease() override;
@@ -72,7 +74,8 @@
                    UsageFlags supportedUsages,
                    const GrVkImageInfo&,
                    sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                   sk_sp<const GrVkImageView> view,
+                   sk_sp<const GrVkImageView> framebufferView,
+                   sk_sp<const GrVkImageView> textureView,
                    SkBudgeted);
 
     GrVkAttachment(GrVkGpu* gpu,
@@ -80,13 +83,16 @@
                    UsageFlags supportedUsages,
                    const GrVkImageInfo&,
                    sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                   sk_sp<const GrVkImageView> view,
+                   sk_sp<const GrVkImageView> framebufferView,
+                   sk_sp<const GrVkImageView> textureView,
                    GrBackendObjectOwnership,
-                   GrWrapCacheable);
+                   GrWrapCacheable,
+                   bool forSecondaryCB);
 
     GrVkGpu* getVkGpu() const;
 
-    sk_sp<const GrVkImageView> fView;
+    sk_sp<const GrVkImageView> fFramebufferView;
+    sk_sp<const GrVkImageView> fTextureView;
 };
 
 #endif
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index ff0082d..69c1c7e 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -1811,8 +1811,8 @@
     if (rt) {
         GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
 
-        SkASSERT(!needsResolve ||
-                 (vkRT->resolveAttachmentView() && vkRT->supportsInputAttachmentUsage()));
+        SkASSERT(!needsResolve || (vkRT->resolveAttachment() &&
+                                   vkRT->resolveAttachment()->supportsInputAttachmentUsage()));
 
         bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
         // TODO: support failure in getSimpleRenderPass
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 47de405..639c070 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -563,7 +563,10 @@
         if (rt->wrapsSecondaryCommandBuffer()) {
             return false;
         }
-        srcImage = rt;
+        if (!rt->nonMSAAAttachment()) {
+            return false;
+        }
+        srcImage = rt->nonMSAAAttachment();
     } else {
         srcImage = static_cast<GrVkTexture*>(surface->asTexture());
     }
@@ -610,7 +613,7 @@
     }
 
     SkASSERT(dst);
-    SkASSERT(src && src->numSamples() > 1 && src->msaaImage());
+    SkASSERT(src && src->colorAttachment() && src->colorAttachment()->numSamples() > 1);
 
     VkImageResolve resolveInfo;
     resolveInfo.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
@@ -621,36 +624,39 @@
 
     GrVkImage* dstImage;
     GrRenderTarget* dstRT = dst->asRenderTarget();
-    if (dstRT) {
-        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT);
-        dstImage = vkRT;
+    GrTexture* dstTex = dst->asTexture();
+    if (dstTex) {
+        dstImage = static_cast<GrVkTexture*>(dstTex);
     } else {
-        SkASSERT(dst->asTexture());
-        dstImage = static_cast<GrVkTexture*>(dst->asTexture());
+        SkASSERT(dst->asRenderTarget());
+        dstImage = static_cast<GrVkRenderTarget*>(dstRT)->nonMSAAAttachment();
+        SkASSERT(dstImage);
     }
+
     dstImage->setImageLayout(this,
                              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                              VK_ACCESS_TRANSFER_WRITE_BIT,
                              VK_PIPELINE_STAGE_TRANSFER_BIT,
                              false);
 
-    src->msaaImage()->setImageLayout(this,
-                                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                     VK_ACCESS_TRANSFER_READ_BIT,
-                                     VK_PIPELINE_STAGE_TRANSFER_BIT,
-                                     false);
-    this->currentCommandBuffer()->addGrSurface(sk_ref_sp<const GrSurface>(src));
+    src->colorAttachment()->setImageLayout(this,
+                                           VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                           VK_ACCESS_TRANSFER_READ_BIT,
+                                           VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                           false);
+    this->currentCommandBuffer()->addGrSurface(sk_ref_sp<const GrSurface>(src->colorAttachment()));
     this->currentCommandBuffer()->addGrSurface(sk_ref_sp<const GrSurface>(dst));
-    this->currentCommandBuffer()->resolveImage(this, *src->msaaImage(), *dstImage, 1, &resolveInfo);
+    this->currentCommandBuffer()->resolveImage(this, *src->colorAttachment(), *dstImage, 1,
+                                               &resolveInfo);
 }
 
 void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) {
     SkASSERT(target->numSamples() > 1);
     GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target);
-    SkASSERT(rt->msaaImage());
     SkASSERT(rt->colorAttachmentView() && rt->resolveAttachmentView());
 
-    if (this->vkCaps().preferDiscardableMSAAAttachment() && rt->supportsInputAttachmentUsage()) {
+    if (this->vkCaps().preferDiscardableMSAAAttachment() && rt->resolveAttachment() &&
+        rt->resolveAttachment()->supportsInputAttachmentUsage()) {
         // We would have resolved the RT during the render pass;
         return;
     }
@@ -1936,18 +1942,20 @@
         dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
         dstAccess = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
     }
+    GrVkAttachment* colorAttachment = vkRT->colorAttachment();
     VkImageMemoryBarrier barrier;
     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
     barrier.pNext = nullptr;
     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
     barrier.dstAccessMask = dstAccess;
-    barrier.oldLayout = vkRT->currentLayout();
-    barrier.newLayout = vkRT->currentLayout();
+    barrier.oldLayout = colorAttachment->currentLayout();
+    barrier.newLayout = barrier.oldLayout;
     barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
     barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-    barrier.image = vkRT->image();
-    barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, vkRT->mipLevels(), 0, 1};
-    this->addImageMemoryBarrier(vkRT->resource(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+    barrier.image = colorAttachment->image();
+    barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, colorAttachment->mipLevels(), 0, 1};
+    this->addImageMemoryBarrier(colorAttachment->resource(),
+                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                 dstStage, true, &barrier);
 }
 
@@ -2132,7 +2140,8 @@
             } else {
                 GrRenderTarget* rt = proxy->peekRenderTarget();
                 SkASSERT(rt);
-                image = static_cast<GrVkRenderTarget*>(rt);
+                GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
+                image = vkRT->externalAttachment();
             }
             if (newState) {
                 const GrVkSharedImageInfo& newInfo = newState->fVkState;
@@ -2192,8 +2201,8 @@
 static int get_surface_sample_cnt(GrSurface* surf, const GrVkCaps& caps) {
     if (const GrRenderTarget* rt = surf->asRenderTarget()) {
         auto vkRT = static_cast<const GrVkRenderTarget*>(rt);
-        if (caps.preferDiscardableMSAAAttachment() && vkRT->resolveAttachmentView() &&
-            vkRT->supportsInputAttachmentUsage()) {
+        if (caps.preferDiscardableMSAAAttachment() && vkRT->resolveAttachment() &&
+            vkRT->resolveAttachment()->supportsInputAttachmentUsage()) {
             return 1;
         }
         return rt->numSamples();
@@ -2367,11 +2376,11 @@
         if (vkRT->wrapsSecondaryCommandBuffer()) {
             return false;
         }
-        if (useDiscardableMSAA && vkRT->resolveAttachmentView() &&
-            vkRT->supportsInputAttachmentUsage()) {
-            dstImage = vkRT;
+        if (useDiscardableMSAA && vkRT->resolveAttachment() &&
+            vkRT->resolveAttachment()->supportsInputAttachmentUsage()) {
+            dstImage = vkRT->resolveAttachment();
         } else {
-            dstImage = vkRT->colorAttachmentImage();
+            dstImage = vkRT->colorAttachment();
         }
     } else {
         SkASSERT(dst->asTexture());
@@ -2380,11 +2389,11 @@
     GrRenderTarget* srcRT = src->asRenderTarget();
     if (srcRT) {
         GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT);
-        if (useDiscardableMSAA && vkRT->resolveAttachmentView() &&
-            vkRT->supportsInputAttachmentUsage()) {
-            srcImage = vkRT;
+        if (useDiscardableMSAA && vkRT->resolveAttachment() &&
+            vkRT->resolveAttachment()->supportsInputAttachmentUsage()) {
+            srcImage = vkRT->resolveAttachment();
         } else {
-            srcImage = vkRT->colorAttachmentImage();
+            srcImage = vkRT->colorAttachment();
         }
     } else {
         SkASSERT(src->asTexture());
@@ -2443,7 +2452,7 @@
         if (rt->wrapsSecondaryCommandBuffer()) {
             return false;
         }
-        image = rt;
+        image = rt->nonMSAAAttachment();
     } else {
         image = static_cast<GrVkTexture*>(surface->asTexture());
     }
diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h
index 2d6a220..cd99b0e 100644
--- a/src/gpu/vk/GrVkImage.h
+++ b/src/gpu/vk/GrVkImage.h
@@ -45,6 +45,7 @@
         SkASSERT(fResource);
         return fInfo.fAlloc;
     }
+    const GrVkImageInfo& vkImageInfo() const { return fInfo; }
     VkFormat imageFormat() const { return fInfo.fFormat; }
     GrBackendFormat getBackendFormat() const {
         if (fResource && this->ycbcrConversionInfo().isValid()) {
@@ -61,6 +62,7 @@
         SkASSERT(fResource);
         return fInfo.fYcbcrConversionInfo;
     }
+    VkImageUsageFlags vkUsageFlags() { return fInfo.fImageUsageFlags; }
     bool supportsInputAttachmentUsage() const {
         return fInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
     }
diff --git a/src/gpu/vk/GrVkMSAALoadManager.cpp b/src/gpu/vk/GrVkMSAALoadManager.cpp
index 0e4097b..03c421c 100644
--- a/src/gpu/vk/GrVkMSAALoadManager.cpp
+++ b/src/gpu/vk/GrVkMSAALoadManager.cpp
@@ -134,7 +134,8 @@
         return false;
     }
 
-    if (!srcRT->supportsInputAttachmentUsage()) {
+    if (!srcRT->resolveAttachment() ||
+        !srcRT->resolveAttachment()->supportsInputAttachmentUsage()) {
         return false;
     }
 
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index 50fd74e..f461994 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -67,7 +67,7 @@
     bool withResolve = fCurrentRenderPass->hasResolveAttachment();
 
     GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
-    GrVkImage* targetImage = vkRT->colorAttachmentImage();
+    GrVkImage* targetImage = vkRT->colorAttachment();
 
     if (fSelfDependencyFlags == SelfDependencyFlags::kForInputAttachment) {
         // We need to use the GENERAL layout in this case since we'll be using texture barriers
@@ -91,15 +91,16 @@
     }
 
     if (withResolve) {
-        GrVkImage* resolveImage = vkRT;
+        GrVkAttachment* resolveAttachment = vkRT->resolveAttachment();
+        SkASSERT(resolveAttachment);
         if (loadFromResolve == LoadFromResolve::kLoad) {
-            resolveImage->setImageLayout(fGpu,
-                                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
-                                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
-                                         false);
+            resolveAttachment->setImageLayout(fGpu,
+                                              VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+                                              VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
+                                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+                                              false);
         } else {
-            resolveImage->setImageLayout(
+            resolveAttachment->setImageLayout(
                     fGpu,
                     VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                     VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
@@ -326,7 +327,7 @@
     // internally to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. Thus we need to update our tracking
     // of the layout to match the new layout.
     GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
-    vkRT->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+    vkRT->resolveAttachment()->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
 }
 
 void GrVkOpsRenderPass::submit() {
@@ -410,7 +411,7 @@
     bool withResolve = false;
     GrOpsRenderPass::LoadAndStoreInfo resolveInfo{GrLoadOp::kLoad, GrStoreOp::kStore, {}};
     if (fRenderTarget->numSamples() > 1 && fGpu->vkCaps().preferDiscardableMSAAAttachment() &&
-        vkRT->resolveAttachmentView() && vkRT->supportsInputAttachmentUsage()) {
+        vkRT->resolveAttachment() && vkRT->resolveAttachment()->supportsInputAttachmentUsage()) {
         withResolve = true;
         localColorInfo.fStoreOp = GrStoreOp::kDiscard;
         if (colorInfo.fLoadOp == GrLoadOp::kLoad) {
@@ -868,7 +869,7 @@
     }
     GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(fRenderTarget);
 
-    GrVkImage* targetImage = target->colorAttachmentImage();
+    GrVkImage* targetImage = target->colorAttachment();
 
     VkRect2D bounds;
     bounds.offset = { 0, 0 };
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 36132ef..807f8e4 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -221,8 +221,9 @@
 bool GrVkPipelineState::setAndBindInputAttachment(GrVkGpu* gpu,
                                                   GrVkRenderTarget* renderTarget,
                                                   GrVkCommandBuffer* commandBuffer) {
-    SkASSERT(renderTarget->supportsInputAttachmentUsage());
+    SkASSERT(renderTarget->colorAttachment()->supportsInputAttachmentUsage());
     const GrVkDescriptorSet* descriptorSet = renderTarget->inputDescSet(gpu, /*forResolve=*/false);
+
     if (!descriptorSet) {
         return false;
     }
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index e19f669..c76347b 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -51,106 +51,46 @@
 // constructor must be explicitly called.
 GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
                                    SkISize dimensions,
-                                   int sampleCnt,
-                                   const GrVkImageInfo& info,
-                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                                   sk_sp<GrVkAttachment> msaaAttachment,
-                                   sk_sp<const GrVkImageView> colorAttachmentView,
-                                   sk_sp<const GrVkImageView> resolveAttachmentView)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kBorrowed)
+                                   sk_sp<GrVkAttachment> colorAttachment,
+                                   sk_sp<GrVkAttachment> resolveAttachment,
+                                   CreateType createType)
+        : GrSurface(gpu, dimensions,
+                    colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
         // for the moment we only support 1:1 color to stencil
-        , GrRenderTarget(gpu, dimensions, sampleCnt, info.fProtected)
-        , fColorAttachmentView(std::move(colorAttachmentView))
-        , fMSAAAttachment(std::move(msaaAttachment))
-        , fResolveAttachmentView(std::move(resolveAttachmentView))
+        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(),
+                         colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
+        , fColorAttachment(std::move(colorAttachment))
+        , fResolveAttachment(std::move(resolveAttachment))
         , fCachedFramebuffers()
         , fCachedRenderPasses() {
-    SkASSERT((info.fProtected == GrProtected::kYes) == fMSAAAttachment->isProtected());
-    SkASSERT(sampleCnt > 1 && sampleCnt == fMSAAAttachment->numSamples());
-    SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
-    this->setFlags(info);
-    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
-}
-
-// We're virtually derived from GrSurface (via GrRenderTarget) so its
-// constructor must be explicitly called.
-GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
-                                   SkISize dimensions,
-                                   int sampleCnt,
-                                   const GrVkImageInfo& info,
-                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                                   sk_sp<GrVkAttachment> msaaAttachment,
-                                   sk_sp<const GrVkImageView> colorAttachmentView,
-                                   sk_sp<const GrVkImageView> resolveAttachmentView,
-                                   GrBackendObjectOwnership ownership)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), ownership)
-        // for the moment we only support 1:1 color to stencil
-        , GrRenderTarget(gpu, dimensions, sampleCnt, info.fProtected)
-        , fColorAttachmentView(std::move(colorAttachmentView))
-        , fMSAAAttachment(std::move(msaaAttachment))
-        , fResolveAttachmentView(std::move(resolveAttachmentView))
-        , fCachedFramebuffers()
-        , fCachedRenderPasses() {
-    SkASSERT((info.fProtected == GrProtected::kYes) == fMSAAAttachment->isProtected());
-    SkASSERT(sampleCnt > 1 && sampleCnt == fMSAAAttachment->numSamples());
-    SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
-    this->setFlags(info);
-}
-
-// We're virtually derived from GrSurface (via GrRenderTarget) so its
-// constructor must be explicitly called.
-GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
-                                   SkISize dimensions,
-                                   const GrVkImageInfo& info,
-                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                                   sk_sp<const GrVkImageView> colorAttachmentView)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kBorrowed)
-        , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected)
-        , fColorAttachmentView(std::move(colorAttachmentView))
-        , fCachedFramebuffers()
-        , fCachedRenderPasses() {
-    SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
-    this->setFlags(info);
-    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
-}
-
-// We're virtually derived from GrSurface (via GrRenderTarget) so its
-// constructor must be explicitly called.
-GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
-                                   SkISize dimensions,
-                                   const GrVkImageInfo& info,
-                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                                   sk_sp<const GrVkImageView> colorAttachmentView,
-                                   GrBackendObjectOwnership ownership)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), ownership)
-        , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected)
-        , fColorAttachmentView(std::move(colorAttachmentView))
-        , fCachedFramebuffers()
-        , fCachedRenderPasses() {
-    SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
-    this->setFlags(info);
+    SkASSERT(fColorAttachment);
+    SkASSERT(!resolveAttachment ||
+             (fResolveAttachment->isProtected() == fColorAttachment->isProtected()));
+    SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
+    this->setFlags();
+    if (createType == CreateType::kDirectlyWrapped) {
+        this->registerWithCacheWrapped(GrWrapCacheable::kNo);
+    }
 }
 
 GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
                                    SkISize dimensions,
-                                   const GrVkImageInfo& info,
-                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
+                                   sk_sp<GrVkAttachment> colorAttachment,
                                    const GrVkRenderPass* renderPass,
                                    VkCommandBuffer secondaryCommandBuffer)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kBorrowed, true)
-        , GrRenderTarget(gpu, dimensions, 1, info.fProtected)
+        : GrSurface(gpu, dimensions,
+                    colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
+        , GrRenderTarget(gpu, dimensions, 1,
+                         colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
+        , fColorAttachment(std::move(colorAttachment))
         , fCachedFramebuffers()
         , fCachedRenderPasses()
         , fSecondaryCommandBuffer(secondaryCommandBuffer) {
-    SkASSERT(info.fSampleCount == 1);
+    SkASSERT(fColorAttachment->numSamples() == 1);
     SkASSERT(fSecondaryCommandBuffer != VK_NULL_HANDLE);
-    SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
-    this->setFlags(info);
+    SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
+    SkASSERT(!SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT));
+    this->setFlags();
     this->registerWithCacheWrapped(GrWrapCacheable::kNo);
     // We use the cached renderpass with no stencil and no extra dependencies to hold the external
     // render pass.
@@ -159,8 +99,9 @@
     fCachedRenderPasses[exteralRPIndex] = renderPass;
 }
 
-void GrVkRenderTarget::setFlags(const GrVkImageInfo& info) {
-    if (info.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
+void GrVkRenderTarget::setFlags() {
+    GrVkAttachment* nonMSAAAttachment = this->nonMSAAAttachment();
+    if (nonMSAAAttachment && nonMSAAAttachment->supportsInputAttachmentUsage()) {
         this->setVkRTSupportsInputAttachment();
     }
 }
@@ -180,54 +121,23 @@
         return nullptr;
     }
 
-    VkFormat pixelFormat = info.fFormat;
-
-    // create msaa surface if necessary
-    sk_sp<GrVkAttachment> vkMSAAAttachment;
-    sk_sp<const GrVkImageView> colorAttachmentView;
-    sk_sp<const GrVkImageView> resolveAttachmentView;
-    if (sampleCnt != wrappedImageSampleCnt) {
-        auto rp = gpu->getContext()->priv().resourceProvider();
-        sk_sp<GrAttachment> msaaAttachment =
-                rp->makeMSAAAttachment(dimensions, GrBackendFormat::MakeVk(info.fFormat),
-                                         sampleCnt, info.fProtected);
-        if (!msaaAttachment) {
-            return nullptr;
-        }
-        vkMSAAAttachment = sk_sp<GrVkAttachment>(
-                static_cast<GrVkAttachment*>(msaaAttachment.release()));
-
-        colorAttachmentView = sk_ref_sp<const GrVkImageView>(vkMSAAAttachment->view());
-
-        // Create Resolve attachment view. Attachment views on framebuffers must have a single mip
-        // level.
-        resolveAttachmentView =
-                GrVkImageView::Make(gpu, info.fImage, pixelFormat, GrVkImageView::kColor_Type,
-                                    /*miplevels=*/1, GrVkYcbcrConversionInfo());
-        if (!resolveAttachmentView) {
-            return nullptr;
-        }
-    } else {
-        // Attachment views on framebuffers must have a single mip level.
-        colorAttachmentView = GrVkImageView::Make(gpu, info.fImage, pixelFormat,
-                                                  GrVkImageView::kColor_Type, /*miplevels=*/1,
-                                                  GrVkYcbcrConversionInfo());
-    }
-
-    if (!colorAttachmentView) {
+    sk_sp<GrVkAttachment> wrappedAttachment =
+            GrVkAttachment::MakeWrapped(gpu, dimensions, info, std::move(mutableState),
+                                        GrAttachment::UsageFlags::kColorAttachment,
+                                        kBorrow_GrWrapOwnership, GrWrapCacheable::kNo);
+    if (!wrappedAttachment) {
         return nullptr;
     }
 
-    GrVkRenderTarget* vkRT;
-    if (resolveAttachmentView) {
-        vkRT = new GrVkRenderTarget(gpu, dimensions, sampleCnt, info, std::move(mutableState),
-                                    std::move(vkMSAAAttachment), std::move(colorAttachmentView),
-                                    std::move(resolveAttachmentView));
-    } else {
-        vkRT = new GrVkRenderTarget(gpu, dimensions, info, std::move(mutableState),
-                                    std::move(colorAttachmentView));
+    sk_sp<GrVkAttachment> colorAttachment;
+    colorAttachment = std::move(wrappedAttachment);
+
+     if (!colorAttachment) {
+        return nullptr;
     }
 
+    GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
+                                                  nullptr, CreateType::kDirectlyWrapped);
     return sk_sp<GrVkRenderTarget>(vkRT);
 }
 
@@ -254,12 +164,25 @@
     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(new GrBackendSurfaceMutableStateImpl(
             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_IGNORED));
 
-    GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, info, std::move(mutableState),
+    sk_sp<GrVkAttachment> scbAttachment =
+        GrVkAttachment::MakeWrapped(gpu, dimensions, info, std::move(mutableState),
+                                    GrAttachment::UsageFlags::kColorAttachment,
+                                    kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, true);
+
+    GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(scbAttachment),
                                                   rp, vkInfo.fSecondaryCommandBuffer);
 
     return sk_sp<GrVkRenderTarget>(vkRT);
 }
 
+GrVkAttachment* GrVkRenderTarget::nonMSAAAttachment() const {
+    if (fColorAttachment->numSamples() == 1) {
+        return fColorAttachment.get();
+    } else {
+        return fResolveAttachment.get();
+    }
+}
+
 bool GrVkRenderTarget::completeStencilAttachment() {
     SkASSERT(!this->wrapsSecondaryCommandBuffer());
     return true;
@@ -371,7 +294,7 @@
     const GrVkImageView* stencilView = withStencil ? this->stencilAttachmentView() : nullptr;
     fCachedFramebuffers[cacheIndex] =
             GrVkFramebuffer::Create(gpu, this->width(), this->height(), renderPass,
-                                    fColorAttachmentView.get(), resolveView, stencilView);
+                                    this->colorAttachmentView(), resolveView, stencilView);
 
     return fCachedFramebuffers[cacheIndex];
 }
@@ -381,8 +304,8 @@
                                                 bool withResolve,
                                                 bool withStencil) const {
     SkASSERT(!this->wrapsSecondaryCommandBuffer());
-    desc->fColor.fFormat = this->imageFormat();
-    desc->fColor.fSamples = this->numSamples();
+    desc->fColor.fFormat = fColorAttachment->imageFormat();
+    desc->fColor.fSamples = fColorAttachment->numSamples();
     *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
     uint32_t attachmentCount = 1;
 
@@ -450,8 +373,10 @@
 }
 
 const GrVkDescriptorSet* GrVkRenderTarget::inputDescSet(GrVkGpu* gpu, bool forResolve) {
-    SkASSERT(this->supportsInputAttachmentUsage());
+    // This needs to be fixed since we may want the resolve or color attachment here. Right??
+    SkASSERT(fColorAttachment->supportsInputAttachmentUsage());
     SkASSERT(this->numSamples() <= 1 || forResolve);
+
     if (fCachedInputDescriptorSet) {
         return fCachedInputDescriptorSet;
     }
@@ -489,8 +414,8 @@
 
 GrVkRenderTarget::~GrVkRenderTarget() {
     // either release or abandon should have been called by the owner of this object.
-    SkASSERT(!fResolveAttachmentView);
-    SkASSERT(!fColorAttachmentView);
+    SkASSERT(!fColorAttachment);
+    SkASSERT(!fResolveAttachment);
 
     for (int i = 0; i < kNumCachedRenderPasses; ++i) {
         SkASSERT(!fCachedFramebuffers[i]);
@@ -505,28 +430,22 @@
     commandBuffer.addGrSurface(sk_ref_sp<const GrSurface>(this));
     commandBuffer.addResource(this->getFramebuffer(renderPass));
     commandBuffer.addResource(this->colorAttachmentView());
-    commandBuffer.addResource(fMSAAAttachment ? fMSAAAttachment->resource() : this->resource());
+    commandBuffer.addResource(fColorAttachment->resource());
+
     if (this->stencilImageResource()) {
         commandBuffer.addResource(this->stencilImageResource());
         commandBuffer.addResource(this->stencilAttachmentView());
     }
     if (renderPass.hasResolveAttachment()) {
-        commandBuffer.addResource(this->resource());
+        SkASSERT(fResolveAttachment);
+        commandBuffer.addResource(fResolveAttachment->resource());
         commandBuffer.addResource(this->resolveAttachmentView());
     }
 }
 
 void GrVkRenderTarget::releaseInternalObjects() {
-    if (fMSAAAttachment) {
-        fMSAAAttachment.reset();
-    }
-
-    if (fResolveAttachmentView) {
-        fResolveAttachmentView.reset();
-    }
-    if (fColorAttachmentView) {
-        fColorAttachmentView.reset();
-    }
+    fColorAttachment.reset();
+    fResolveAttachment.reset();
 
     for (int i = 0; i < kNumCachedRenderPasses; ++i) {
         if (fCachedFramebuffers[i]) {
@@ -553,33 +472,20 @@
 
 void GrVkRenderTarget::onRelease() {
     this->releaseInternalObjects();
-    this->releaseImage();
     GrRenderTarget::onRelease();
 }
 
 void GrVkRenderTarget::onAbandon() {
     this->releaseInternalObjects();
-    this->releaseImage();
     GrRenderTarget::onAbandon();
 }
 
 GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
     SkASSERT(!this->wrapsSecondaryCommandBuffer());
-    return GrBackendRenderTarget(this->width(), this->height(), fInfo, this->getMutableState());
-}
-
-GrVkImage* GrVkRenderTarget::msaaImage() {
-    if (this->numSamples() == 1) {
-        SkASSERT(fColorAttachmentView && !fMSAAAttachment && !fResolveAttachmentView);
-        return nullptr;
-    }
-    if (!fMSAAAttachment) {
-        // In this case *this* object is MSAA (there is not a separate color and resolve buffer)
-        SkASSERT(!fResolveAttachmentView);
-        return this;
-    }
-    SkASSERT(fMSAAAttachment);
-    return fMSAAAttachment.get();
+    // If we have a resolve attachment that is what we return for the backend render target
+    const GrVkAttachment* beAttachment = this->externalAttachment();
+    return GrBackendRenderTarget(beAttachment->width(), beAttachment->height(),
+                                 beAttachment->vkImageInfo(), beAttachment->getMutableState());
 }
 
 const GrManagedResource* GrVkRenderTarget::stencilImageResource() const {
@@ -598,19 +504,12 @@
     const GrAttachment* stencil = this->getStencilAttachment();
     if (stencil) {
         const GrVkAttachment* vkStencil = static_cast<const GrVkAttachment*>(stencil);
-        return vkStencil->view();
+        return vkStencil->framebufferView();
     }
 
     return nullptr;
 }
 
-GrVkImage* GrVkRenderTarget::colorAttachmentImage() {
-    if (fMSAAAttachment) {
-        return fMSAAAttachment.get();
-    }
-    return this;
-}
-
 GrVkGpu* GrVkRenderTarget::getVkGpu() const {
     SkASSERT(!this->wasDestroyed());
     return static_cast<GrVkGpu*>(this->getGpu());
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index 9be2b57..6d6905b 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -24,7 +24,7 @@
 
 struct GrVkImageInfo;
 
-class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage {
+class GrVkRenderTarget: public GrRenderTarget {
 public:
     static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*, SkISize, int sampleCnt,
                                                            const GrVkImageInfo&,
@@ -35,7 +35,7 @@
 
     ~GrVkRenderTarget() override;
 
-    GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
+    GrBackendFormat backendFormat() const override { return fColorAttachment->getBackendFormat(); }
 
     using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
     using LoadFromResolve = GrVkRenderPass::LoadFromResolve;
@@ -51,22 +51,28 @@
                                     renderPass.loadFromResolve());
     }
 
-    const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView.get(); }
+    GrVkAttachment* colorAttachment() const { return fColorAttachment.get(); }
+    const GrVkImageView* colorAttachmentView() const { return fColorAttachment->framebufferView(); }
 
-    /**
-     * If this render target is multisampled, this returns the MSAA image for rendering. This
-     * will be different than *this* when we have separate render/resolve images. If not
-     * multisampled returns nullptr.
-     */
-    GrVkImage* msaaImage();
+    GrVkAttachment* resolveAttachment() const { return fResolveAttachment.get(); }
+    const GrVkImageView* resolveAttachmentView() const {
+        return fResolveAttachment->framebufferView();
+    }
 
-    const GrVkImageView* resolveAttachmentView() const { return fResolveAttachmentView.get(); }
     const GrManagedResource* stencilImageResource() const;
     const GrVkImageView* stencilAttachmentView() const;
 
-    // Returns the main target for draws. If using MSAA and we have a resolve target, it will be the
-    // msaa attachment. Otherwise it will be this object.
-    GrVkImage* colorAttachmentImage();
+    // Returns the GrVkAttachment of the non-msaa attachment. If the color attachment has 1 sample,
+    // then the color attachment will be returned. Otherwise, the resolve attachment is returned.
+    // Note that in this second case the resolve attachment may be null if this was created by
+    // wrapping an msaa VkImage.
+    GrVkAttachment* nonMSAAAttachment() const;
+
+    // Returns the attachment that is used for all external client facing operations. This will be
+    // either a wrapped color attachment or the resolve attachment for created VkImages.
+    GrVkAttachment* externalAttachment() const {
+        return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
+    }
 
     const GrVkRenderPass* getSimpleRenderPass(bool withResolve,
                                               bool withStencil,
@@ -118,71 +124,31 @@
     }
 
 protected:
-    GrVkRenderTarget(GrVkGpu* gpu,
-                     SkISize dimensions,
-                     int sampleCnt,
-                     const GrVkImageInfo& info,
-                     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                     sk_sp<GrVkAttachment> msaaAttachment,
-                     sk_sp<const GrVkImageView> colorAttachmentView,
-                     sk_sp<const GrVkImageView> resolveAttachmentView,
-                     GrBackendObjectOwnership);
+    enum class CreateType {
+        kDirectlyWrapped, // We need to register this in the ctor
+        kFromTextureRT,   // Skip registering this to cache since TexRT will handle it
+    };
 
     GrVkRenderTarget(GrVkGpu* gpu,
                      SkISize dimensions,
-                     const GrVkImageInfo& info,
-                     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                     sk_sp<const GrVkImageView> colorAttachmentView,
-                     GrBackendObjectOwnership);
+                     sk_sp<GrVkAttachment> colorAttachment,
+                     sk_sp<GrVkAttachment> resolveAttachment,
+                     CreateType createType);
 
     void onAbandon() override;
     void onRelease() override;
 
-    // This accounts for the texture's memory and any MSAA renderbuffer's memory.
-    size_t onGpuMemorySize() const override {
-        int numColorSamples = 0;
-        if (this->numSamples() > 1) {
-            // If we have an msaa attachment then its size will be handled by the attachment itself.
-            if (!fMSAAAttachment) {
-                numColorSamples += this->numSamples();
-            }
-            if (fResolveAttachmentView) {
-                // Add one to account for the resolved VkImage.
-                numColorSamples += 1;
-            }
-        } else {
-            SkASSERT(!fResolveAttachmentView);
-            numColorSamples = 1;
-        }
-
-        return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
-                                      numColorSamples, GrMipmapped::kNo);
-    }
+    // This returns zero since the memory should all be handled by the attachments
+    size_t onGpuMemorySize() const override { return 0; }
 
 private:
     GrVkRenderTarget(GrVkGpu* gpu,
                      SkISize dimensions,
-                     int sampleCnt,
-                     const GrVkImageInfo& info,
-                     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                     sk_sp<GrVkAttachment> msaaAttachment,
-                     sk_sp<const GrVkImageView> colorAttachmentView,
-                     sk_sp<const GrVkImageView> resolveAttachmentView);
-
-    GrVkRenderTarget(GrVkGpu* gpu,
-                     SkISize dimensions,
-                     const GrVkImageInfo& info,
-                     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                     sk_sp<const GrVkImageView> colorAttachmentView);
-
-    GrVkRenderTarget(GrVkGpu* gpu,
-                     SkISize dimensions,
-                     const GrVkImageInfo& info,
-                     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
+                     sk_sp<GrVkAttachment> colorAttachment,
                      const GrVkRenderPass* renderPass,
                      VkCommandBuffer secondaryCommandBuffer);
 
-    void setFlags(const GrVkImageInfo& info);
+    void setFlags();
 
     GrVkGpu* getVkGpu() const;
 
@@ -200,15 +166,17 @@
     // In Vulkan we call the release proc after we are finished with the underlying
     // GrVkImage::Resource object (which occurs after the GPU has finished all work on it).
     void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override {
-        // Forward the release proc on to GrVkImage
-        this->setResourceRelease(std::move(releaseHelper));
+        // Forward the release proc on to the GrVkImage of the release attachment if we have one,
+        // otherwise the color attachment.
+        GrVkAttachment* attachment =
+                fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
+        attachment->setResourceRelease(std::move(releaseHelper));
     }
 
     void releaseInternalObjects();
 
-    sk_sp<const GrVkImageView> fColorAttachmentView;
-    sk_sp<GrVkAttachment>      fMSAAAttachment;
-    sk_sp<const GrVkImageView> fResolveAttachmentView;
+    sk_sp<GrVkAttachment> fColorAttachment;
+    sk_sp<GrVkAttachment> fResolveAttachment;
 
     // We can have a renderpass with and without resolve attachment, stencil attachment,
     // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of
diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp
index 6feb677..f26e6c7 100644
--- a/src/gpu/vk/GrVkTexture.cpp
+++ b/src/gpu/vk/GrVkTexture.cpp
@@ -27,8 +27,8 @@
                          sk_sp<const GrVkImageView> view,
                          GrMipmapStatus mipmapStatus)
         : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kOwned)
         , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus)
+        , GrVkImage(gpu, info, std::move(mutableState), GrBackendObjectOwnership::kOwned)
         , fTextureView(std::move(view))
         , fDescSetCache(kMaxCachedDescSets) {
     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
@@ -47,9 +47,9 @@
                          GrMipmapStatus mipmapStatus, GrBackendObjectOwnership ownership,
                          GrWrapCacheable cacheable, GrIOType ioType, bool isExternal)
         : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), ownership)
         , INHERITED(gpu, dimensions, info.fProtected,
                     isExternal ? GrTextureType::kExternal : GrTextureType::k2D, mipmapStatus)
+        , GrVkImage(gpu, info, std::move(mutableState), ownership)
         , fTextureView(std::move(view))
         , fDescSetCache(kMaxCachedDescSets) {
     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
@@ -69,8 +69,8 @@
                          GrMipmapStatus mipmapStatus,
                          GrBackendObjectOwnership ownership)
         : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, std::move(mutableState), ownership)
         , INHERITED(gpu, dimensions, info.fProtected, GrTextureType::k2D, mipmapStatus)
+        , GrVkImage(gpu, info, std::move(mutableState), ownership)
         , fTextureView(std::move(view))
         , fDescSetCache(kMaxCachedDescSets) {
     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == info.fLevelCount));
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index 23950a7..138cc22 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -19,7 +19,7 @@
 class GrVkImageView;
 struct GrVkImageInfo;
 
-class GrVkTexture : public GrTexture, public virtual GrVkImage {
+class GrVkTexture : public GrTexture, public GrVkImage {
 public:
     static sk_sp<GrVkTexture> MakeNewTexture(GrVkGpu*,
                                              SkBudgeted budgeted,
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index de5828b..13c9145 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -25,137 +25,95 @@
         GrVkGpu* gpu,
         SkBudgeted budgeted,
         SkISize dimensions,
-        int sampleCnt,
         const GrVkImageInfo& info,
         sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
         sk_sp<const GrVkImageView> texView,
-        sk_sp<GrVkAttachment> msaaAttachment,
-        sk_sp<const GrVkImageView> colorAttachmentView,
-        sk_sp<const GrVkImageView> resolveAttachmentView,
+        sk_sp<GrVkAttachment> colorAttachment,
+        sk_sp<GrVkAttachment> resolveAttachment,
         GrMipmapStatus mipmapStatus)
         : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, mutableState, GrBackendObjectOwnership::kOwned)
         , GrVkTexture(gpu, dimensions, info, mutableState, std::move(texView), mipmapStatus,
                       GrBackendObjectOwnership::kOwned)
-        , GrVkRenderTarget(gpu, dimensions, sampleCnt, info, std::move(mutableState),
-                           std::move(msaaAttachment), std::move(colorAttachmentView),
-                           std::move(resolveAttachmentView), GrBackendObjectOwnership::kOwned) {
-    this->registerWithCache(budgeted);
-}
-
-GrVkTextureRenderTarget::GrVkTextureRenderTarget(
-        GrVkGpu* gpu,
-        SkBudgeted budgeted,
-        SkISize dimensions,
-        const GrVkImageInfo& info,
-        sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-        sk_sp<const GrVkImageView> texView,
-        sk_sp<const GrVkImageView> colorAttachmentView,
-        GrMipmapStatus mipmapStatus)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, mutableState, GrBackendObjectOwnership::kOwned)
-        , GrVkTexture(gpu, dimensions, info, mutableState, std::move(texView), mipmapStatus,
-                      GrBackendObjectOwnership::kOwned)
-        , GrVkRenderTarget(gpu, dimensions, info, std::move(mutableState),
-                           std::move(colorAttachmentView), GrBackendObjectOwnership::kOwned) {
+        , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
+                           std::move(resolveAttachment), CreateType::kFromTextureRT) {
     this->registerWithCache(budgeted);
 }
 
 GrVkTextureRenderTarget::GrVkTextureRenderTarget(
         GrVkGpu* gpu,
         SkISize dimensions,
-        int sampleCnt,
         const GrVkImageInfo& info,
         sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
         sk_sp<const GrVkImageView> texView,
-        sk_sp<GrVkAttachment> msaaAttachment,
-        sk_sp<const GrVkImageView> colorAttachmentView,
-        sk_sp<const GrVkImageView> resolveAttachmentView,
+        sk_sp<GrVkAttachment> colorAttachment,
+        sk_sp<GrVkAttachment> resolveAttachment,
         GrMipmapStatus mipmapStatus,
         GrBackendObjectOwnership ownership,
         GrWrapCacheable cacheable)
         : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, mutableState, ownership)
         , GrVkTexture(gpu, dimensions, info, mutableState, std::move(texView), mipmapStatus,
                       ownership)
-        , GrVkRenderTarget(gpu, dimensions, sampleCnt, info, std::move(mutableState),
-                           std::move(msaaAttachment), std::move(colorAttachmentView),
-                           std::move(resolveAttachmentView), ownership) {
-    this->registerWithCacheWrapped(cacheable);
-}
-
-GrVkTextureRenderTarget::GrVkTextureRenderTarget(
-        GrVkGpu* gpu,
-        SkISize dimensions,
-        const GrVkImageInfo& info,
-        sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-        sk_sp<const GrVkImageView> texView,
-        sk_sp<const GrVkImageView> colorAttachmentView,
-        GrMipmapStatus mipmapStatus,
-        GrBackendObjectOwnership ownership,
-        GrWrapCacheable cacheable)
-        : GrSurface(gpu, dimensions, info.fProtected)
-        , GrVkImage(gpu, info, mutableState, ownership)
-        , GrVkTexture(gpu, dimensions, info, mutableState, std::move(texView), mipmapStatus,
-                      ownership)
-        , GrVkRenderTarget(gpu, dimensions, info, std::move(mutableState),
-                           std::move(colorAttachmentView), ownership) {
+        , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
+                           std::move(resolveAttachment), CreateType::kFromTextureRT) {
     this->registerWithCacheWrapped(cacheable);
 }
 
 namespace {
 struct Views {
-    sk_sp<const GrVkImageView> imageView;
-    sk_sp<const GrVkImageView> colorAttachmentView;
-    sk_sp<const GrVkImageView> resolveAttachmentView;
-    sk_sp<GrVkAttachment> msaaAttachment;
+    sk_sp<const GrVkImageView> textureView;
+    sk_sp<GrVkAttachment> colorAttachment;
+    sk_sp<GrVkAttachment> resolveAttachment;
 };
 }  // anonymous namespace
 
-static Views create_views(GrVkGpu* gpu, SkISize dimensions, int sampleCnt,
-                          const GrVkImageInfo& info) {
+static Views create_attachments(GrVkGpu* gpu, SkISize dimensions, int sampleCnt,
+                                const GrVkImageInfo& info,
+                                sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) {
     VkImage image = info.fImage;
     // Create the texture ImageView
     Views views;
-    views.imageView = GrVkImageView::Make(gpu, image, info.fFormat, GrVkImageView::kColor_Type,
-                                          info.fLevelCount, info.fYcbcrConversionInfo);
-    if (!views.imageView) {
+    views.textureView = GrVkImageView::Make(gpu, image, info.fFormat, GrVkImageView::kColor_Type,
+                                            info.fLevelCount, info.fYcbcrConversionInfo);
+    if (!views.textureView) {
         return {};
     }
 
-    VkFormat pixelFormat = info.fFormat;
+    // Make the non-msaa attachment which may end up as either the color or resolve view depending
+    // on if sampleCnt > 1 or not. The info and mutableState passed in here will always represent
+    // the non-msaa image.
+    SkASSERT(info.fSampleCount == 1);
+    // TODO: Fix this weird wrapping once GrVkTexture and GrVkAttachment merge.
+    // Regardless of whether the actual TextureRenderTarget is wrapped or created, we always make a
+    // wrapped attachment here. The GrVkTexture will manage the lifetime and possible destruction
+    // of the GrVkImage object. So we want the attachment on the GrVkRenderTarget to always be
+    // borrowed. In the current system that can lead to overcounting of memory usage when we are
+    // including both owned and borrowed memory.
+    sk_sp<GrVkAttachment> nonMSAAAttachment =
+            GrVkAttachment::MakeWrapped(gpu, dimensions, info, std::move(mutableState),
+                                        GrAttachment::UsageFlags::kColorAttachment,
+                                        kBorrow_GrWrapOwnership, GrWrapCacheable::kNo);
+
+    if (!nonMSAAAttachment) {
+        return {};
+    }
 
     // create msaa surface if necessary
     if (sampleCnt > 1) {
         auto rp = gpu->getContext()->priv().resourceProvider();
-        sk_sp<GrAttachment> msaaAttachment =
-                rp->makeMSAAAttachment(dimensions, GrBackendFormat::MakeVk(info.fFormat),
-                                       sampleCnt, info.fProtected);
+        sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment(
+                dimensions, GrBackendFormat::MakeVk(info.fFormat), sampleCnt, info.fProtected);
         if (!msaaAttachment) {
             return {};
         }
 
-        views.msaaAttachment = sk_sp<GrVkAttachment>(
-                static_cast<GrVkAttachment*>(msaaAttachment.release()));
-
-        views.colorAttachmentView = sk_ref_sp<const GrVkImageView>(views.msaaAttachment->view());
-
-        // Create resolve attachment view. Attachment views on framebuffers must have a single mip
-        // level.
-        views.resolveAttachmentView =
-                GrVkImageView::Make(gpu, image, pixelFormat, GrVkImageView::kColor_Type,
-                                    /*miplevels=*/1, GrVkYcbcrConversionInfo());
-        if (!views.resolveAttachmentView) {
-            return {};
-        }
+        views.colorAttachment =
+                sk_sp<GrVkAttachment>(static_cast<GrVkAttachment*>(msaaAttachment.release()));
+        views.resolveAttachment = std::move(nonMSAAAttachment);
     } else {
-        //Attachment views on framebuffers must have a single mip level.
-        views.colorAttachmentView = GrVkImageView::Make(
-                gpu, info.fImage, pixelFormat, GrVkImageView::kColor_Type, /*miplevels=*/1,
-                GrVkYcbcrConversionInfo());
+        views.colorAttachment = std::move(nonMSAAAttachment);
     }
 
-    if (!views.colorAttachmentView) {
+    if (!views.colorAttachment) {
         return {};
     }
     return views;
@@ -178,22 +136,14 @@
     sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(
             new GrBackendSurfaceMutableStateImpl(info.fImageLayout, info.fCurrentQueueFamily));
 
-    Views views = create_views(gpu, dimensions, sampleCnt, info);
-    if (!views.colorAttachmentView) {
+    Views views = create_attachments(gpu, dimensions, sampleCnt, info, mutableState);
+    if (!views.colorAttachment) {
         GrVkImage::DestroyImageInfo(gpu, &info);
         return nullptr;
     }
-    if (sampleCnt > 1) {
-        return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, budgeted, dimensions, sampleCnt, info, std::move(mutableState),
-                std::move(views.imageView), std::move(views.msaaAttachment),
-                std::move(views.colorAttachmentView), std::move(views.resolveAttachmentView),
-                mipmapStatus));
-    } else {
-        return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, budgeted, dimensions, info, std::move(mutableState),
-                std::move(views.imageView), std::move(views.colorAttachmentView), mipmapStatus));
-    }
+    return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
+            gpu, budgeted, dimensions, info, std::move(mutableState), std::move(views.textureView),
+            std::move(views.colorAttachment), std::move(views.resolveAttachment), mipmapStatus));
 }
 
 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
@@ -213,30 +163,36 @@
 
     GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
             ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
-    Views views = create_views(gpu, dimensions, sampleCnt, info);
-    if (!views.colorAttachmentView) {
+    Views views = create_attachments(gpu, dimensions, sampleCnt, info, mutableState);
+    if (!views.colorAttachment) {
         return nullptr;
     }
-    if (sampleCnt > 1) {
-        return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, dimensions, sampleCnt, info, std::move(mutableState),
-                std::move(views.imageView), std::move(views.msaaAttachment),
-                std::move(views.colorAttachmentView), std::move(views.resolveAttachmentView),
-                mipmapStatus, ownership, cacheable));
-    } else {
-        return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
-                gpu, dimensions, info, std::move(mutableState), std::move(views.imageView),
-                std::move(views.colorAttachmentView), mipmapStatus, ownership, cacheable));
-    }
+    return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
+            gpu, dimensions, info, std::move(mutableState), std::move(views.textureView),
+            std::move(views.colorAttachment), std::move(views.resolveAttachment),
+            mipmapStatus, ownership, cacheable));
 }
 
 size_t GrVkTextureRenderTarget::onGpuMemorySize() const {
-    int numColorSamples = this->numSamples();
-    if (numColorSamples > 1) {
-        // Add one to account for the resolve VkImage.
-        ++numColorSamples;
+    // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
+    // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
+    // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
+    // attachment to give its own size since we don't have GrGpuResources owning other
+    // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
+    // the msaa and stencil attachments track their own size because they do get cached separately.
+    // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
+    // the owned attachments will have no size and be uncached.
+#ifdef SK_DEBUG
+    // The nonMSAA attachment (either color or resolve depending on numSamples should have size of
+    // zero since it is a texture attachment.
+    SkASSERT(this->nonMSAAAttachment()->gpuMemorySize() == 0);
+    if (this->numSamples() > 1) {
+        // Msaa attachment should have a valid size
+        SkASSERT(this->colorAttachment()->gpuMemorySize() ==
+                 GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
+                                        this->numSamples(), GrMipMapped::kNo));
     }
+#endif
     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
-                                  numColorSamples,  // TODO: this still correct?
-                                  this->mipmapped());
+                                  1 /*colorSamplesPerPixel*/, this->mipmapped());
 }
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index 39f6a40..44b12f9 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -61,46 +61,21 @@
     GrVkTextureRenderTarget(GrVkGpu* gpu,
                             SkBudgeted budgeted,
                             SkISize dimensions,
-                            int sampleCnt,
                             const GrVkImageInfo& info,
                             sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
                             sk_sp<const GrVkImageView> texView,
-                            sk_sp<GrVkAttachment> msaaAttachment,
-                            sk_sp<const GrVkImageView> colorAttachmentView,
-                            sk_sp<const GrVkImageView> resolveAttachmentView,
-                            GrMipmapStatus);
-
-    // non-MSAA, not-wrapped
-    GrVkTextureRenderTarget(GrVkGpu* gpu,
-                            SkBudgeted budgeted,
-                            SkISize dimensions,
-                            const GrVkImageInfo& info,
-                            sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                            sk_sp<const GrVkImageView> texView,
-                            sk_sp<const GrVkImageView> colorAttachmentView,
+                            sk_sp<GrVkAttachment> colorAttachment,
+                            sk_sp<GrVkAttachment> resolveAttachment,
                             GrMipmapStatus);
 
     // MSAA, wrapped
     GrVkTextureRenderTarget(GrVkGpu* gpu,
                             SkISize dimensions,
-                            int sampleCnt,
                             const GrVkImageInfo& info,
                             sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
                             sk_sp<const GrVkImageView> texView,
-                            sk_sp<GrVkAttachment> msaaAttachment,
-                            sk_sp<const GrVkImageView> colorAttachmentView,
-                            sk_sp<const GrVkImageView> resolveAttachmentView,
-                            GrMipmapStatus,
-                            GrBackendObjectOwnership,
-                            GrWrapCacheable);
-
-    // non-MSAA, wrapped
-    GrVkTextureRenderTarget(GrVkGpu* gpu,
-                            SkISize dimensions,
-                            const GrVkImageInfo& info,
-                            sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
-                            sk_sp<const GrVkImageView> texView,
-                            sk_sp<const GrVkImageView> colorAttachmentView,
+                            sk_sp<GrVkAttachment> colorAttachment,
+                            sk_sp<GrVkAttachment> resolveAttachment,
                             GrMipmapStatus,
                             GrBackendObjectOwnership,
                             GrWrapCacheable);
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 60594a7..90d1dca 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -743,10 +743,10 @@
     }
 
     GrSwizzle swizzle = dContext->priv().caps()->getReadSwizzle(backendFormat, grColorType);
-    GrSurfaceProxyView view(std::move(proxy), surfaceOrigin, swizzle);
+    GrSurfaceProxyView framebufferView(std::move(proxy), surfaceOrigin, swizzle);
     sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
                                                    kNeedNewImageUniqueID,
-                                                   view,
+                                                   framebufferView,
                                                    colorType,
                                                    pixmap.alphaType(),
                                                    pixmap.refColorSpace());
@@ -759,7 +759,8 @@
         return nullptr;
     }
 
-    GrSurfaceContext surfaceContext(dContext, std::move(view), image->imageInfo().colorInfo());
+    GrSurfaceContext surfaceContext(
+            dContext, std::move(framebufferView),image->imageInfo().colorInfo());
 
     surfaceContext.writePixels(dContext, pixmap, {0, 0});