Vulkan: Store ImageHelper as a pointer in TextureVk and RenderbufferVk

Storing ImageHelper as a pointer allows the storage to be swapped or shared
with other objects.

BUG=angleproject:2668

Change-Id: I2e51f24737be59ffe9f472e9b0b592774a792cd1
Reviewed-on: https://chromium-review.googlesource.com/c/1409404
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index 9c63d44..9eb9445 100644
--- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -24,7 +24,7 @@
 }  // anonymous namespace
 
 RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
-    : RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, 0, nullptr)
+    : RenderbufferImpl(state), mImage(nullptr)
 {}
 
 RenderbufferVk::~RenderbufferVk() {}
@@ -34,8 +34,12 @@
     ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
 
-    mImage.releaseImage(renderer);
-    mImage.releaseStagingBuffer(renderer);
+    if (mImage)
+    {
+        mImage->releaseImage(renderer);
+        mImage->releaseStagingBuffer(renderer);
+        SafeDelete(mImage);
+    }
 
     renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
 }
@@ -49,20 +53,25 @@
     RendererVk *renderer       = contextVk->getRenderer();
     const vk::Format &vkFormat = renderer->getFormat(internalformat);
 
-    if (mImage.valid())
+    if (mImage != nullptr && mImage->valid())
     {
         // Check against the state if we need to recreate the storage.
         if (internalformat != mState.getFormat().info->internalFormat ||
             static_cast<GLsizei>(width) != mState.getWidth() ||
             static_cast<GLsizei>(height) != mState.getHeight())
         {
-            mImage.releaseImage(renderer);
+            mImage->releaseImage(renderer);
             renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
         }
     }
 
-    if (!mImage.valid() && (width != 0 && height != 0))
+    if ((mImage == nullptr || !mImage->valid()) && (width != 0 && height != 0))
     {
+        if (mImage == nullptr)
+        {
+            mImage = new vk::ImageHelper();
+        }
+
         const angle::Format &textureFormat = vkFormat.textureFormat();
         bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
         const VkImageUsageFlags usage =
@@ -72,30 +81,33 @@
             (isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
 
         gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
-        ANGLE_TRY(mImage.init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
+        ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
 
         VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
-        ANGLE_TRY(mImage.initMemory(contextVk, renderer->getMemoryProperties(), flags));
+        ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
 
         VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
 
         // Note that LUMA textures are not color-renderable, so a read-view with swizzle is not
         // needed.
-        ANGLE_TRY(mImage.initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
-                                       &mImageView, 1));
+        ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
+                                        &mImageView, 1));
 
         // TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
         vk::CommandBuffer *commandBuffer = nullptr;
-        ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
+        ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
 
         if (isDepthOrStencilFormat)
         {
-            mImage.clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue, commandBuffer);
+            mImage->clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue,
+                                      commandBuffer);
         }
         else
         {
-            mImage.clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
+            mImage->clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
         }
+
+        mRenderTarget.init(mImage, &mImageView, 0, nullptr);
     }
 
     return angle::Result::Continue;
@@ -123,7 +135,7 @@
                                                         const gl::ImageIndex &imageIndex,
                                                         FramebufferAttachmentRenderTarget **rtOut)
 {
-    ASSERT(mImage.valid());
+    ASSERT(mImage && mImage->valid());
     *rtOut = &mRenderTarget;
     return angle::Result::Continue;
 }