Vulkan: Call GraphResource instead of GraphNode.

We don't need to use the CommandGraphNode class directly. This CL
consolidates our code so we never call the GraphNodes class directly.
Instead we call operations on GraphResource. This should simplify the
interaction with APIs from the various graph and dependency management
classes in the Vulkan back-end.

A new concept of 'starting' vs 'appending' commands is introduced.
Appending tries to avoid starting new command buffers when possible.

Should not change how the graphs are constructed, and mostly be a
refactoring change. There may be minor behaviour changes to some
commands.

Bug: angleproject:2539
Change-Id: Ia971e5cacb1164b9b3b22fa4a0a55b954d81f10e
Reviewed-on: https://chromium-review.googlesource.com/1052068
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index 54d0a0d..788376d 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -57,9 +57,7 @@
 {
 }
 
-CommandGraphResource::~CommandGraphResource()
-{
-}
+CommandGraphResource::~CommandGraphResource() = default;
 
 void CommandGraphResource::updateQueueSerial(Serial queueSerial)
 {
@@ -83,18 +81,19 @@
     return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren());
 }
 
-CommandGraphNode *CommandGraphResource::getCurrentWritingNode()
-{
-    return mCurrentWritingNode;
-}
-
 CommandGraphNode *CommandGraphResource::getNewWritingNode(RendererVk *renderer)
 {
     CommandGraphNode *newCommands = renderer->allocateCommandNode();
-    onWriteResource(newCommands, renderer->getCurrentQueueSerial());
+    onWriteImpl(newCommands, renderer->getCurrentQueueSerial());
     return newCommands;
 }
 
+bool CommandGraphResource::hasStartedWriteResource() const
+{
+    return hasChildlessWritingNode() &&
+           mCurrentWritingNode->getOutsideRenderPassCommands()->valid();
+}
+
 Error CommandGraphResource::beginWriteResource(RendererVk *renderer,
                                                CommandBuffer **commandBufferOut)
 {
@@ -106,9 +105,75 @@
     return NoError();
 }
 
-void CommandGraphResource::onWriteResource(CommandGraphNode *writingNode, Serial serial)
+Error CommandGraphResource::appendWriteResource(RendererVk *renderer,
+                                                CommandBuffer **commandBufferOut)
 {
-    updateQueueSerial(serial);
+    if (!hasChildlessWritingNode())
+    {
+        return beginWriteResource(renderer, commandBufferOut);
+    }
+
+    CommandBuffer *outsideRenderPassCommands = mCurrentWritingNode->getOutsideRenderPassCommands();
+    if (!outsideRenderPassCommands->valid())
+    {
+        ANGLE_TRY(mCurrentWritingNode->beginOutsideRenderPassRecording(
+            renderer->getDevice(), renderer->getCommandPool(), commandBufferOut));
+    }
+    else
+    {
+        *commandBufferOut = outsideRenderPassCommands;
+    }
+
+    return NoError();
+}
+
+void CommandGraphResource::appendToRenderPass(class CommandBuffer **commandBufferOut) const
+{
+    ASSERT(hasStartedRenderPass());
+    *commandBufferOut = mCurrentWritingNode->getInsideRenderPassCommands();
+}
+
+bool CommandGraphResource::hasStartedRenderPass() const
+{
+    return hasChildlessWritingNode() && mCurrentWritingNode->getInsideRenderPassCommands()->valid();
+}
+
+const gl::Rectangle &CommandGraphResource::getRenderPassRenderArea() const
+{
+    ASSERT(hasStartedRenderPass());
+    return mCurrentWritingNode->getRenderPassRenderArea();
+}
+
+Error CommandGraphResource::beginRenderPass(RendererVk *renderer,
+                                            const Framebuffer &framebuffer,
+                                            const gl::Rectangle &renderArea,
+                                            const RenderPassDesc &renderPassDesc,
+                                            const std::vector<VkClearValue> &clearValues,
+                                            CommandBuffer **commandBufferOut) const
+{
+    // Hard-code RenderPass to clear the first render target to the current clear value.
+    // TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
+    mCurrentWritingNode->storeRenderPassInfo(framebuffer, renderArea, renderPassDesc, clearValues);
+
+    return mCurrentWritingNode->beginInsideRenderPassRecording(renderer, commandBufferOut);
+}
+
+void CommandGraphResource::onResourceChanged(RendererVk *renderer)
+{
+    getNewWritingNode(renderer);
+}
+
+void CommandGraphResource::addWriteDependency(CommandGraphResource *writingResource)
+{
+    CommandGraphNode *writingNode = writingResource->mCurrentWritingNode;
+    ASSERT(writingNode);
+
+    onWriteImpl(writingNode, writingResource->getQueueSerial());
+}
+
+void CommandGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
+{
+    updateQueueSerial(currentSerial);
 
     // Make sure any open reads and writes finish before we execute 'writingNode'.
     if (!mCurrentReadingNodes.empty())
@@ -125,14 +190,15 @@
     mCurrentWritingNode = writingNode;
 }
 
-void CommandGraphResource::onReadResource(CommandGraphNode *readingNode, Serial serial)
+void CommandGraphResource::addReadDependency(CommandGraphResource *readingResource)
 {
-    updateQueueSerial(serial);
+    updateQueueSerial(readingResource->getQueueSerial());
+
+    CommandGraphNode *readingNode = readingResource->mCurrentWritingNode;
+    ASSERT(readingNode);
 
     if (hasChildlessWritingNode())
     {
-        ASSERT(mStoredQueueSerial == serial);
-
         // Ensure 'readingNode' happens after the current writing node.
         CommandGraphNode::SetHappensBeforeDependency(mCurrentWritingNode, readingNode);
     }
@@ -158,7 +224,8 @@
 
 // CommandGraphNode implementation.
 
-CommandGraphNode::CommandGraphNode() : mHasChildren(false), mVisitedState(VisitedState::Unvisited)
+CommandGraphNode::CommandGraphNode()
+    : mRenderPassClearValues{}, mHasChildren(false), mVisitedState(VisitedState::Unvisited)
 {
 }
 
@@ -370,9 +437,7 @@
 }
 
 // CommandGraph implementation.
-CommandGraph::CommandGraph()
-{
-}
+CommandGraph::CommandGraph() = default;
 
 CommandGraph::~CommandGraph()
 {