Vulkan: Make vk::FramebufferHelper the graph resource.

It seems conceptually easier to understand that a vk::Framebuffer is
the resource used in graph. Rather than making the GraphResource be
integrated into the FramebufferVk class itself. This means that the
only objects that are graph resources are Vulkan objects: Images,
Buffers, and Framebuffers.

Refactoring change only.

Bug: angleproject:2828
Change-Id: I59d60643182287d4b1fcf9730a3c3a0da5b65973
Reviewed-on: https://chromium-review.googlesource.com/1249561
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 23b68ce..fcf4d48 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -397,7 +397,7 @@
         // Ensure any writes to the textures are flushed before we read from them.
         TextureVk *textureVk = mActiveTextures[textureIndex];
         ANGLE_TRY(textureVk->ensureImageInitialized(this));
-        textureVk->getImage().addReadDependency(mDrawFramebuffer);
+        textureVk->getImage().addReadDependency(mDrawFramebuffer->getFramebuffer());
     }
 
     if (mProgram->hasTextures())
@@ -421,7 +421,8 @@
     for (size_t attribIndex : context->getStateCache().getActiveBufferedAttribsMask())
     {
         if (arrayBufferResources[attribIndex])
-            arrayBufferResources[attribIndex]->addReadDependency(mDrawFramebuffer);
+            arrayBufferResources[attribIndex]->addReadDependency(
+                mDrawFramebuffer->getFramebuffer());
     }
     return angle::Result::Continue();
 }
@@ -438,7 +439,7 @@
         mVertexArray->getCurrentElementArrayBufferResource();
     if (elementArrayBufferResource)
     {
-        elementArrayBufferResource->addReadDependency(mDrawFramebuffer);
+        elementArrayBufferResource->addReadDependency(mDrawFramebuffer->getFramebuffer());
     }
     return angle::Result::Continue();
 }
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index c45a9e9..34e3cca 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -136,7 +136,7 @@
 {
     ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
-    renderer->releaseObject(getStoredQueueSerial(), &mFramebuffer);
+    mFramebuffer.release(renderer);
 
     mReadPixelBuffer.destroy(contextVk->getDevice());
     mBlitPixelBuffer.destroy(contextVk->getDevice());
@@ -232,7 +232,7 @@
     // Standard Depth/stencil clear without scissor.
     if (clearDepth || clearStencil)
     {
-        ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
+        ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
 
         const VkClearDepthStencilValue &clearDepthStencilValue =
             contextVk->getClearDepthStencilValue().depthStencil;
@@ -241,7 +241,7 @@
         const angle::Format &format          = renderTarget->getImageFormat().textureFormat();
         const VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
 
-        vk::ImageHelper *image = renderTarget->getImageForWrite(this);
+        vk::ImageHelper *image = renderTarget->getImageForWrite(&mFramebuffer);
         image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
     }
 
@@ -255,7 +255,7 @@
 
     if (!commandBuffer)
     {
-        ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
+        ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
     }
 
     // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
@@ -275,7 +275,7 @@
         }
 
         ASSERT(colorRenderTarget);
-        vk::ImageHelper *image = colorRenderTarget->getImageForWrite(this);
+        vk::ImageHelper *image = colorRenderTarget->getImageForWrite(&mFramebuffer);
         GLint mipLevelToClear  = (attachment->type() == GL_TEXTURE) ? attachment->mipLevel() : 0;
 
         // If we're clearing a cube map face ensure we only clear the selected layer.
@@ -404,8 +404,8 @@
     VkFlags aspectFlags =
         vk::GetDepthStencilAspectFlags(readRenderTarget->getImageFormat().textureFormat());
     vk::ImageHelper *readImage = readRenderTarget->getImageForRead(
-        this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
-    vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(this);
+        &mFramebuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
+    vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(&mFramebuffer);
     // Requirement of the copyImageToBuffer, the dst image must be in
     // VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL layout.
     writeImage->changeLayoutWithStages(aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@@ -482,11 +482,11 @@
 
     // Reinitialize the commandBuffer after a read pixels because it calls
     // renderer->finish which makes command buffers obsolete.
-    ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
+    ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
 
     // We read the bytes of the image in a buffer, now we have to copy them into the
     // destination target.
-    vk::ImageHelper *imageForWrite = drawRenderTarget->getImageForWrite(this);
+    vk::ImageHelper *imageForWrite = drawRenderTarget->getImageForWrite(&mFramebuffer);
 
     imageForWrite->changeLayoutWithStages(
         imageForWrite->getAspectFlags(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@@ -516,7 +516,7 @@
     bool blitStencilBuffer                   = (mask & GL_STENCIL_BUFFER_BIT) != 0;
 
     vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
+    ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
     FramebufferVk *sourceFramebufferVk = vk::GetImpl(sourceFramebuffer);
     bool flipSource                    = contextVk->isViewportFlipEnabledForReadFBO();
     bool flipDest                      = contextVk->isViewportFlipEnabledForDrawFBO();
@@ -649,7 +649,7 @@
         colorBlit ? VK_IMAGE_ASPECT_COLOR_BIT
                   : vk::GetDepthStencilAspectFlags(readImageFormat.textureFormat());
     vk::ImageHelper *srcImage = readRenderTarget->getImageForRead(
-        this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
+        &mFramebuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
 
     const gl::Extents sourceFrameBufferExtents = readRenderTarget->getImageExtents();
     gl::Rectangle readRect                     = readRectIn;
@@ -682,7 +682,7 @@
     blit.dstOffsets[0] = {drawRect.x0(), flipDest ? drawRect.y1() : drawRect.y0(), 0};
     blit.dstOffsets[1] = {drawRect.x1(), flipDest ? drawRect.y0() : drawRect.y1(), 1};
 
-    vk::ImageHelper *dstImage = drawRenderTarget->getImageForWrite(this);
+    vk::ImageHelper *dstImage = drawRenderTarget->getImageForWrite(&mFramebuffer);
 
     // Requirement of the copyImageToBuffer, the dst image must be in
     // VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL layout.
@@ -768,11 +768,11 @@
         mActiveColorComponentMasksForClear[2].any(), mActiveColorComponentMasksForClear[3].any());
 
     mRenderPassDesc.reset();
-    renderer->releaseObject(getStoredQueueSerial(), &mFramebuffer);
+    mFramebuffer.release(renderer);
 
     // Will freeze the current set of dependencies on this FBO. The next time we render we will
     // create a new entry in the command graph.
-    finishCurrentCommands(renderer);
+    mFramebuffer.finishCurrentCommands(renderer);
 
     contextVk->invalidateCurrentPipeline();
 
@@ -812,7 +812,7 @@
     // If we've already created our cached Framebuffer, return it.
     if (mFramebuffer.valid())
     {
-        *framebufferOut = &mFramebuffer;
+        *framebufferOut = &mFramebuffer.getFramebuffer();
         return angle::Result::Continue();
     }
 
@@ -869,7 +869,7 @@
 
     ANGLE_TRY(mFramebuffer.init(contextVk, framebufferInfo));
 
-    *framebufferOut = &mFramebuffer;
+    *framebufferOut = &mFramebuffer.getFramebuffer();
     return angle::Result::Continue();
 }
 
@@ -879,7 +879,7 @@
                                                        bool clearStencil)
 {
     // Trigger a new command node to ensure overlapping writes happen sequentially.
-    finishCurrentCommands(contextVk->getRenderer());
+    mFramebuffer.finishCurrentCommands(contextVk->getRenderer());
 
     // This command can only happen inside a render pass, so obtain one if its already happening
     // or create a new one if not.
@@ -895,8 +895,8 @@
     // When clearing, the scissor region must be clipped to the renderArea per the validation rules
     // in Vulkan.
     gl::Rectangle intersection;
-    if (!gl::ClipRectangle(contextVk->getGLState().getScissor(), getRenderPassRenderArea(),
-                           &intersection))
+    if (!gl::ClipRectangle(contextVk->getGLState().getScissor(),
+                           mFramebuffer.getRenderPassRenderArea(), &intersection))
     {
         // There is nothing to clear since the scissor is outside of the render area.
         return angle::Result::Continue();
@@ -906,8 +906,8 @@
 
     if (contextVk->isViewportFlipEnabledForDrawFBO())
     {
-        clearRect.rect.offset.y = getRenderPassRenderArea().height - clearRect.rect.offset.y -
-                                  clearRect.rect.extent.height;
+        clearRect.rect.offset.y = mFramebuffer.getRenderPassRenderArea().height -
+                                  clearRect.rect.offset.y - clearRect.rect.extent.height;
     }
 
     gl::AttachmentArray<VkClearAttachment> clearAttachments;
@@ -980,7 +980,7 @@
     vk::ShaderLibrary *shaderLibrary = renderer->getShaderLibrary();
 
     // Trigger a new command node to ensure overlapping writes happen sequentially.
-    finishCurrentCommands(renderer);
+    mFramebuffer.finishCurrentCommands(renderer);
 
     const vk::ShaderAndSerial *fullScreenQuad = nullptr;
     ANGLE_TRY(shaderLibrary->getShader(contextVk, vk::InternalShaderID::FullScreenQuad_vert,
@@ -1006,7 +1006,7 @@
     vk::CommandBuffer *drawCommands = nullptr;
     ANGLE_TRY(getCommandBufferForDraw(contextVk, &drawCommands, &recordingMode));
 
-    const gl::Rectangle &renderArea = getRenderPassRenderArea();
+    const gl::Rectangle &renderArea = mFramebuffer.getRenderPassRenderArea();
     bool invertViewport             = contextVk->isViewportFlipEnabledForDrawFBO();
 
     // This pipeline desc could be cached.
@@ -1040,7 +1040,7 @@
     pipeline->updateSerial(renderer->getCurrentQueueSerial());
 
     vk::CommandBuffer *writeCommands = nullptr;
-    ANGLE_TRY(recordCommands(contextVk, &writeCommands));
+    ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &writeCommands));
 
     // If the format of the framebuffer does not have an alpha channel, we need to make sure we does
     // not affect the alpha channel of the type we're using to emulate the format.
@@ -1099,7 +1099,7 @@
     std::vector<VkClearValue> attachmentClearValues;
 
     vk::CommandBuffer *writeCommands = nullptr;
-    ANGLE_TRY(recordCommands(contextVk, &writeCommands));
+    ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &writeCommands));
 
     vk::RenderPassDesc renderPassDesc;
 
@@ -1111,22 +1111,23 @@
         RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
         ASSERT(colorRenderTarget);
 
-        colorRenderTarget->onColorDraw(this, writeCommands, &renderPassDesc);
+        colorRenderTarget->onColorDraw(&mFramebuffer, writeCommands, &renderPassDesc);
         attachmentClearValues.emplace_back(contextVk->getClearColorValue());
     }
 
     RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
     if (depthStencilRenderTarget)
     {
-        depthStencilRenderTarget->onDepthStencilDraw(this, writeCommands, &renderPassDesc);
+        depthStencilRenderTarget->onDepthStencilDraw(&mFramebuffer, writeCommands, &renderPassDesc);
         attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
     }
 
     gl::Rectangle renderArea =
         gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
 
-    return beginRenderPass(contextVk, *framebuffer, renderArea, mRenderPassDesc.value(),
-                           attachmentClearValues, commandBufferOut);
+    return mFramebuffer.beginRenderPass(contextVk, *framebuffer, renderArea,
+                                        mRenderPassDesc.value(), attachmentClearValues,
+                                        commandBufferOut);
 }
 
 void FramebufferVk::updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a)
@@ -1152,12 +1153,12 @@
     RendererVk *renderer = contextVk->getRenderer();
 
     vk::CommandBuffer *commandBuffer = nullptr;
-    ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
+    ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
 
     // Note that although we're reading from the image, we need to update the layout below.
 
-    vk::ImageHelper *srcImage =
-        renderTarget->getImageForRead(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
+    vk::ImageHelper *srcImage = renderTarget->getImageForRead(
+        &mFramebuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
 
     const angle::Format *readFormat = &srcImage->getFormat().textureFormat();
 
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.h b/src/libANGLE/renderer/vulkan/FramebufferVk.h
index 059f96a..a583965 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.h
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.h
@@ -22,7 +22,7 @@
 class RenderTargetVk;
 class WindowSurfaceVk;
 
-class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
+class FramebufferVk : public FramebufferImpl
 {
   public:
     // Factory methods so we don't have to use constructors with overloads.
@@ -105,7 +105,12 @@
     RenderTargetVk *getColorReadRenderTarget() const;
 
     // This will clear the current write operation if it is complete.
-    using CommandGraphResource::appendToStartedRenderPass;
+    bool appendToStartedRenderPass(RendererVk *renderer, vk::CommandBuffer **commandBufferOut)
+    {
+        return mFramebuffer.appendToStartedRenderPass(renderer, commandBufferOut);
+    }
+
+    vk::FramebufferHelper *getFramebuffer() { return &mFramebuffer; }
 
     angle::Result startNewRenderPass(ContextVk *context, vk::CommandBuffer **commandBufferOut);
 
@@ -159,7 +164,7 @@
     WindowSurfaceVk *mBackbuffer;
 
     Optional<vk::RenderPassDesc> mRenderPassDesc;
-    vk::Framebuffer mFramebuffer;
+    vk::FramebufferHelper mFramebuffer;
     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
 
     // These two variables are used to quickly compute if we need to do a masked clear. If a color
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index a4446b3..eb09e32 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -626,7 +626,7 @@
         framebufferVk));
 
     mImage.finishCurrentCommands(renderer);
-    framebufferVk->addReadDependency(&mImage);
+    framebufferVk->getFramebuffer()->addReadDependency(&mImage);
     return angle::Result::Continue();
 }
 
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 32b26d9..254e976 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -933,5 +933,21 @@
     commandBuffer->copyImage(srcImage->getImage(), srcImage->getCurrentLayout(),
                              dstImage->getImage(), dstImage->getCurrentLayout(), 1, &region);
 }
+
+// FramebufferHelper implementation.
+FramebufferHelper::FramebufferHelper() = default;
+
+FramebufferHelper::~FramebufferHelper() = default;
+
+angle::Result FramebufferHelper::init(ContextVk *contextVk,
+                                      const VkFramebufferCreateInfo &createInfo)
+{
+    return mFramebuffer.init(contextVk, createInfo);
+}
+
+void FramebufferHelper::release(RendererVk *renderer)
+{
+    renderer->releaseObject(getStoredQueueSerial(), &mFramebuffer);
+}
 }  // namespace vk
 }  // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index ab20e72..83b57e9 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -166,7 +166,7 @@
     DynamicBuffer mDynamicIndexBuffer;
 };
 
-class BufferHelper final : public CommandGraphResource
+class BufferHelper final : public CommandGraphResource, angle::NonCopyable
 {
   public:
     BufferHelper();
@@ -190,7 +190,7 @@
     VkMemoryPropertyFlags mMemoryPropertyFlags;
 };
 
-class ImageHelper final : public CommandGraphResource
+class ImageHelper final : public CommandGraphResource, angle::NonCopyable
 {
   public:
     ImageHelper();
@@ -298,6 +298,35 @@
     // Cached properties.
     uint32_t mLayerCount;
 };
+
+class FramebufferHelper : public CommandGraphResource, angle::NonCopyable
+{
+  public:
+    FramebufferHelper();
+    ~FramebufferHelper();
+
+    angle::Result init(ContextVk *contextVk, const VkFramebufferCreateInfo &createInfo);
+    void release(RendererVk *renderer);
+
+    bool valid() { return mFramebuffer.valid(); }
+
+    const Framebuffer &getFramebuffer() const
+    {
+        ASSERT(mFramebuffer.valid());
+        return mFramebuffer;
+    }
+
+    Framebuffer &getFramebuffer()
+    {
+        ASSERT(mFramebuffer.valid());
+        return mFramebuffer;
+    }
+
+  private:
+    // Vulkan object.
+    Framebuffer mFramebuffer;
+};
+
 }  // namespace vk
 }  // namespace rx