Make copy texture test more extensive

By doing the copy multiple times, we exercise both paths where the
destination is already initialized and when it's not.

This adds tests for all combinations of formats and flags.

Bug: angleproject:2958
Change-Id: I56afb44496acd1b4d5a8527f4dbee29afbac9c81
Reviewed-on: https://chromium-review.googlesource.com/c/1398643
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index c92f7c3..7893c6c 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -1101,6 +1101,8 @@
 {
     RendererVk *renderer = contextVk->getRenderer();
 
+    ANGLE_TRY(renderTarget->ensureImageInitialized(contextVk));
+
     vk::CommandBuffer *commandBuffer = nullptr;
     ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
 
diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
index e2ca46f..c6158a2 100644
--- a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
@@ -10,19 +10,26 @@
 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
 
 #include "libANGLE/renderer/vulkan/CommandGraph.h"
+#include "libANGLE/renderer/vulkan/TextureVk.h"
 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
 #include "libANGLE/renderer/vulkan/vk_helpers.h"
 
 namespace rx
 {
-RenderTargetVk::RenderTargetVk(vk::ImageHelper *image, vk::ImageView *imageView, size_t layerIndex)
-    : mImage(image), mImageView(imageView), mLayerIndex(layerIndex)
+RenderTargetVk::RenderTargetVk(vk::ImageHelper *image,
+                               vk::ImageView *imageView,
+                               size_t layerIndex,
+                               TextureVk *owner)
+    : mImage(image), mImageView(imageView), mLayerIndex(layerIndex), mOwner(owner)
 {}
 
 RenderTargetVk::~RenderTargetVk() {}
 
 RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
-    : mImage(other.mImage), mImageView(other.mImageView), mLayerIndex(other.mLayerIndex)
+    : mImage(other.mImage),
+      mImageView(other.mImageView),
+      mLayerIndex(other.mLayerIndex),
+      mOwner(other.mOwner)
 {}
 
 void RenderTargetVk::onColorDraw(vk::FramebufferHelper *framebufferVk,
@@ -107,6 +114,7 @@
     ASSERT(image && image->valid() && imageView && imageView->valid());
     mImage     = image;
     mImageView = imageView;
+    mOwner     = nullptr;
 }
 
 vk::ImageHelper *RenderTargetVk::getImageForRead(vk::RecordableGraphResource *readingResource,
@@ -133,4 +141,13 @@
     return mImage;
 }
 
+angle::Result RenderTargetVk::ensureImageInitialized(ContextVk *contextVk)
+{
+    if (mOwner)
+    {
+        return mOwner->ensureImageInitialized(contextVk);
+    }
+    return angle::Result::Continue;
+}
+
 }  // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.h b/src/libANGLE/renderer/vulkan/RenderTargetVk.h
index 2cacd24..97785e0 100644
--- a/src/libANGLE/renderer/vulkan/RenderTargetVk.h
+++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.h
@@ -28,13 +28,19 @@
 class RenderPassDesc;
 }  // namespace vk
 
+class ContextVk;
+class TextureVk;
+
 // This is a very light-weight class that does not own to the resources it points to.
 // It's meant only to copy across some information from a FramebufferAttachment to the
 // business rendering logic. It stores Images and ImageViews by pointer for performance.
 class RenderTargetVk final : public FramebufferAttachmentRenderTarget
 {
   public:
-    RenderTargetVk(vk::ImageHelper *image, vk::ImageView *imageView, size_t layerIndex);
+    RenderTargetVk(vk::ImageHelper *image,
+                   vk::ImageView *imageView,
+                   size_t layerIndex,
+                   TextureVk *ownwer);
     ~RenderTargetVk();
 
     // Used in std::vector initialization.
@@ -68,12 +74,18 @@
     // RenderTargetVk pointer.
     void updateSwapchainImage(vk::ImageHelper *image, vk::ImageView *imageView);
 
+    angle::Result ensureImageInitialized(ContextVk *contextVk);
+
   private:
     vk::ImageHelper *mImage;
     // Note that the draw and read image views are the same, given the requirements of a render
     // target.
     vk::ImageView *mImageView;
     size_t mLayerIndex;
+
+    // If owned by the texture, this will be non-nullptr, and is used to ensure texture changes
+    // are flushed.
+    TextureVk *mOwner;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index c6e8907..f92b34f 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)
+    : RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, 0, nullptr)
 {}
 
 RenderbufferVk::~RenderbufferVk() {}
diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
index 6f397d0..4f9e252 100644
--- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
@@ -74,7 +74,9 @@
 
 }  // namespace
 
-OffscreenSurfaceVk::AttachmentImage::AttachmentImage() : renderTarget(&image, &imageView, 0) {}
+OffscreenSurfaceVk::AttachmentImage::AttachmentImage()
+    : renderTarget(&image, &imageView, 0, nullptr)
+{}
 
 OffscreenSurfaceVk::AttachmentImage::~AttachmentImage() = default;
 
@@ -270,8 +272,8 @@
       mInstance(VK_NULL_HANDLE),
       mSwapchain(VK_NULL_HANDLE),
       mSwapchainPresentMode(VK_PRESENT_MODE_FIFO_KHR),
-      mColorRenderTarget(nullptr, nullptr, 0),
-      mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, 0),
+      mColorRenderTarget(nullptr, nullptr, 0, nullptr),
+      mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, 0, nullptr),
       mCurrentSwapchainImageIndex(0),
       mCurrentSwapSerialIndex(0)
 {}
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 450c52d..c78a2dc 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -383,7 +383,7 @@
 // TextureVk implementation.
 TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer)
     : TextureImpl(state),
-      mRenderTarget(&mImage, &mDrawBaseLevelImageView, 0),
+      mRenderTarget(&mImage, &mDrawBaseLevelImageView, 0, this),
       mPixelBuffer(renderer)
 {}
 
@@ -996,7 +996,7 @@
     {
         vk::ImageView *imageView;
         ANGLE_TRY(getLayerLevelDrawImageView(contextVk, cubeMapFaceIndex, 0, &imageView));
-        mCubeMapRenderTargets.emplace_back(&mImage, imageView, cubeMapFaceIndex);
+        mCubeMapRenderTargets.emplace_back(&mImage, imageView, cubeMapFaceIndex, this);
     }
     return angle::Result::Continue;
 }