Update RT views and framebuffer in vulkan after mipmaping

I've also changed it so all attachment views (texture, color, and resolve) are created separately and not shared with each other. This just added a lot more complexity than we were probably even saving in time.

A quick fix to make sure we don't reuse keys in resource tracking also
got merged into this change.

BUG=skia:5223
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2146103002

Review-Url: https://codereview.chromium.org/2146103002
diff --git a/src/gpu/vk/GrVkBuffer.h b/src/gpu/vk/GrVkBuffer.h
index 966b810..232de17 100644
--- a/src/gpu/vk/GrVkBuffer.h
+++ b/src/gpu/vk/GrVkBuffer.h
@@ -68,7 +68,7 @@
         Type               fType;
 
     private:
-        void freeGPUData(const GrVkGpu* gpu) const;
+        void freeGPUData(const GrVkGpu* gpu) const override;
 
         typedef GrVkResource INHERITED;
     };
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index b995ed9..76d50b0 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -770,7 +770,7 @@
     return tgt;
 }
 
-void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
+void GrVkGpu::generateMipmap(GrVkTexture* tex) {
     // don't do anything for linearly tiled textures (can't have mipmaps)
     if (tex->isLinearTiled()) {
         SkDebugf("Trying to create mipmap for linear tiled texture");
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index a0530f4..37d4e4f 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -136,7 +136,7 @@
 
     void finishDrawTarget() override;
 
-    void generateMipmap(GrVkTexture* tex) const;
+    void generateMipmap(GrVkTexture* tex);
 
     bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size);
 
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index 351fbbf..b233649 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -337,7 +337,7 @@
 }
 
 static void append_sampled_images(const GrProcessor& processor,
-                                  const GrVkGpu* gpu,
+                                  GrVkGpu* gpu,
                                   SkTArray<GrVkImage*>* sampledImages) {
     if (int numTextures = processor.numTextures()) {
         GrVkImage** images = sampledImages->push_back_n(numTextures);
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index 708af79..83a4b44 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -33,10 +33,10 @@
     , GrVkImage(info, wrapped)
     // for the moment we only support 1:1 color to stencil
     , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
-    , fFramebuffer(nullptr)
     , fColorAttachmentView(colorAttachmentView)
     , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
     , fResolveAttachmentView(resolveAttachmentView)
+    , fFramebuffer(nullptr)
     , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(desc.fSampleCnt);
     // The plus 1 is to account for the resolve texture.
@@ -58,10 +58,10 @@
     , GrVkImage(info, wrapped)
     // for the moment we only support 1:1 color to stencil
     , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
-    , fFramebuffer(nullptr)
     , fColorAttachmentView(colorAttachmentView)
     , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
     , fResolveAttachmentView(resolveAttachmentView)
+    , fFramebuffer(nullptr)
     , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(desc.fSampleCnt);
     // The plus 1 is to account for the resolve texture.
@@ -80,10 +80,10 @@
     : GrSurface(gpu, desc)
     , GrVkImage(info, wrapped)
     , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
-    , fFramebuffer(nullptr)
     , fColorAttachmentView(colorAttachmentView)
     , fMSAAImage(nullptr)
     , fResolveAttachmentView(nullptr)
+    , fFramebuffer(nullptr)
     , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(!desc.fSampleCnt);
     fColorValuesPerPixel = 1;
@@ -101,10 +101,10 @@
     : GrSurface(gpu, desc)
     , GrVkImage(info, wrapped)
     , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
-    , fFramebuffer(nullptr)
     , fColorAttachmentView(colorAttachmentView)
     , fMSAAImage(nullptr)
     , fResolveAttachmentView(nullptr)
+    , fFramebuffer(nullptr)
     , fCachedSimpleRenderPass(nullptr) {
     SkASSERT(!desc.fSampleCnt);
     fColorValuesPerPixel = 1;
@@ -117,6 +117,7 @@
                          const GrSurfaceDesc& desc,
                          const GrVkImageInfo& info,
                          GrVkImage::Wrapped wrapped) {
+    SkASSERT(1 == info.fLevelCount);
     VkFormat pixelFormat;
     GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
 
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index 9628e3b..019f567 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -103,6 +103,12 @@
         return fColorValuesPerPixel * fDesc.fWidth * fDesc.fHeight * colorBytes;
     }
 
+    void createFramebuffer(GrVkGpu* gpu);
+
+    const GrVkImageView*       fColorAttachmentView;
+    GrVkImage*                 fMSAAImage;
+    const GrVkImageView*       fResolveAttachmentView;
+
 private:
     GrVkRenderTarget(GrVkGpu* gpu,
                      SkBudgeted,
@@ -125,15 +131,10 @@
 
     bool completeStencilAttachment() override;
 
-    void createFramebuffer(GrVkGpu* gpu);
-
     void releaseInternalObjects();
     void abandonInternalObjects();
 
     const GrVkFramebuffer*     fFramebuffer;
-    const GrVkImageView*       fColorAttachmentView;
-    GrVkImage*                 fMSAAImage;
-    const GrVkImageView*       fResolveAttachmentView;
     int                        fColorValuesPerPixel;
 
     // This is a cached pointer to a simple render pass. The render target should unref it
diff --git a/src/gpu/vk/GrVkResource.h b/src/gpu/vk/GrVkResource.h
index 3999749..83e82fb 100644
--- a/src/gpu/vk/GrVkResource.h
+++ b/src/gpu/vk/GrVkResource.h
@@ -60,14 +60,14 @@
     };
     static Trace  fTrace;
 
-    static SkRandom fRandom;
+    static uint32_t fKeyCounter;
 #endif
 
     /** Default construct, initializing the reference count to 1.
      */
     GrVkResource() : fRefCnt(1) {
 #ifdef SK_TRACE_VK_RESOURCES
-        fKey = fRandom.nextU();
+        fKey = sk_atomic_fetch_add(&fKeyCounter, 1u, sk_memory_order_relaxed);
         fTrace.add(this);
 #endif
     }
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index c83c6a4..e3c19d6 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -16,7 +16,7 @@
 
 #ifdef SK_TRACE_VK_RESOURCES
 GrVkResource::Trace GrVkResource::fTrace;
-SkRandom GrVkResource::fRandom;
+uint32_t GrVkResource::fKeyCounter = 0;
 #endif
 
 GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp
index b0dd107..bf399a8 100644
--- a/src/gpu/vk/GrVkTexture.cpp
+++ b/src/gpu/vk/GrVkTexture.cpp
@@ -9,6 +9,7 @@
 #include "GrVkGpu.h"
 #include "GrVkImageView.h"
 #include "GrTexturePriv.h"
+#include "GrVkTextureRenderTarget.h"
 #include "GrVkUtil.h"
 
 #include "vk/GrVkTypes.h"
@@ -161,7 +162,7 @@
     return fLinearTextureView;
 }
 
-bool GrVkTexture::reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels) {
+bool GrVkTexture::reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels) {
     if (mipLevels == 1) {
         // don't need to do anything for a 1x1 texture
         return false;
@@ -174,7 +175,6 @@
         return false;
     }
 
-    // Does this even make sense for rendertargets?
     bool renderTarget = SkToBool(fDesc.fFlags & kRenderTarget_GrSurfaceFlag);
 
     VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
@@ -209,6 +209,14 @@
         return false;
     }
 
+    if (renderTarget) {
+        GrVkTextureRenderTarget* texRT = static_cast<GrVkTextureRenderTarget*>(this);
+        if (!texRT->updateForMipmap(gpu, info)) {
+            GrVkImage::DestroyImageInfo(gpu, &info);
+            return false;
+        }
+    }
+
     oldResource->unref(gpu);
     oldView->unref(gpu);
     if (fLinearTextureView) {
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index de10a32..06d1475 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -32,7 +32,7 @@
 
     const GrVkImageView* textureView(bool allowSRGB);
 
-    bool reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels);
+    bool reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels);
 
 protected:
     GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, const GrVkImageView*,
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index df2ad69..bee6a04 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -25,13 +25,9 @@
                                                          GrVkImage::Wrapped wrapped) {
     VkImage image = info.fImage;
     // Create the texture ImageView
-    uint32_t mipLevels = 1;
-    //TODO: does a mipmapped textureRenderTarget make sense?
-    //if (desc.fIsMipMapped) {
-    //    mipLevels = SkMipMap::ComputeLevelCount(this->width(), this->height()) + 1;
-    //}
     const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
-                                                           GrVkImageView::kColor_Type, mipLevels);
+                                                           GrVkImageView::kColor_Type,
+                                                           info.fLevelCount);
     if (!imageView) {
         return nullptr;
     }
@@ -63,44 +59,31 @@
         // Set color attachment image
         colorImage = msInfo.fImage;
 
-        // Create resolve attachment view if necessary.
-        // If the format matches, this is the same as the texture imageView.
-        if (pixelFormat == info.fFormat) {
-            resolveAttachmentView = imageView;
-            resolveAttachmentView->ref();
-        } else {
-            resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
-                                                          GrVkImageView::kColor_Type, 1);
-            if (!resolveAttachmentView) {
-                GrVkImage::DestroyImageInfo(gpu, &msInfo);
-                imageView->unref(gpu);
-                return nullptr;
-            }
+        // Create resolve attachment view.
+        resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
+                                                      GrVkImageView::kColor_Type,
+                                                      info.fLevelCount);
+        if (!resolveAttachmentView) {
+            GrVkImage::DestroyImageInfo(gpu, &msInfo);
+            imageView->unref(gpu);
+            return nullptr;
         }
     } else {
         // Set color attachment image
         colorImage = info.fImage;
     }
 
-    const GrVkImageView* colorAttachmentView;
-    // Get color attachment view.
-    // If the format matches and there's no multisampling,
-    // this is the same as the texture imageView
-    if (pixelFormat == info.fFormat && !resolveAttachmentView) {
-        colorAttachmentView = imageView;
-        colorAttachmentView->ref();
-    } else {
-        colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
-                                                    GrVkImageView::kColor_Type, 1);
-        if (!colorAttachmentView) {
-            if (desc.fSampleCnt) {
-                resolveAttachmentView->unref(gpu);
-                GrVkImage::DestroyImageInfo(gpu, &msInfo);
-            }
-            imageView->unref(gpu);
-            return nullptr;
+    const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
+                                                                     GrVkImageView::kColor_Type, 1);
+    if (!colorAttachmentView) {
+        if (desc.fSampleCnt) {
+            resolveAttachmentView->unref(gpu);
+            GrVkImage::DestroyImageInfo(gpu, &msInfo);
         }
+        imageView->unref(gpu);
+        return nullptr;
     }
+
     GrVkTextureRenderTarget* texRT;
     if (desc.fSampleCnt) {
         if (GrVkImage::kNot_Wrapped == wrapped) {
@@ -165,3 +148,36 @@
 
     return trt;
 }
+
+bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) {
+    VkFormat pixelFormat;
+    GrPixelConfigToVkFormat(fDesc.fConfig, &pixelFormat);
+    if (fDesc.fSampleCnt) {
+        const GrVkImageView* resolveAttachmentView =
+                GrVkImageView::Create(gpu,
+                                      newInfo.fImage,
+                                      pixelFormat,
+                                      GrVkImageView::kColor_Type,
+                                      newInfo.fLevelCount);
+        if (!resolveAttachmentView) {
+            return false;
+        }
+        fResolveAttachmentView->unref(gpu);
+        fResolveAttachmentView = resolveAttachmentView;
+    } else {
+        const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu,
+                                                                         newInfo.fImage,
+                                                                         pixelFormat,
+                                                                         GrVkImageView::kColor_Type,
+                                                                         1);
+        if (!colorAttachmentView) {
+            return false;
+        }
+        fColorAttachmentView->unref(gpu);
+        fColorAttachmentView = colorAttachmentView;
+    }
+
+    this->createFramebuffer(gpu);
+    return true;
+}
+
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index 6ea332a..2259511 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -33,6 +33,8 @@
                                                                      GrWrapOwnership,
                                                                      const GrVkImageInfo*);
 
+    bool updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo);
+
 protected:
     void onAbandon() override {
         GrVkRenderTarget::onAbandon();