Vulkan: Split vk::CommandGraphResource.

This adds two subclasses: RecordableGraphResource and
QueryGraphResource. Each specializes for Buffer/Image/Frambuffer use
cases and Query use cases respectively. No virtual functions are added
to keep best performance.

We also change the CommandGraph API slightly to optimize away the check
for a barrier resource. This requires exposing the set current barrier
API on the CommandGraph.

Bug: angleproject:2828
Change-Id: I1c23f52bfe04cc682a00b245d63c3ac9a651615d
Reviewed-on: https://chromium-review.googlesource.com/c/1305994
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index eca1693..6754132 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -82,24 +82,12 @@
 
 // CommandGraphResource implementation.
 CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType)
-    : mCurrentWritingNode(nullptr), mResourceType(resourceType)
+    : mResourceType(resourceType), mCurrentWritingNode(nullptr)
 {
 }
 
 CommandGraphResource::~CommandGraphResource() = default;
 
-void CommandGraphResource::updateQueueSerial(Serial queueSerial)
-{
-    ASSERT(queueSerial >= mStoredQueueSerial);
-
-    if (queueSerial > mStoredQueueSerial)
-    {
-        mCurrentWritingNode = nullptr;
-        mCurrentReadingNodes.clear();
-        mStoredQueueSerial = queueSerial;
-    }
-}
-
 bool CommandGraphResource::isResourceInUse(RendererVk *renderer) const
 {
     return renderer->isSerialInUse(mStoredQueueSerial);
@@ -117,14 +105,34 @@
     return mStoredQueueSerial;
 }
 
-angle::Result CommandGraphResource::recordCommands(Context *context,
-                                                   CommandBuffer **commandBufferOut)
+// RecordableGraphResource implementation.
+RecordableGraphResource::RecordableGraphResource(CommandGraphResourceType resourceType)
+    : CommandGraphResource(resourceType)
+{
+}
+
+RecordableGraphResource::~RecordableGraphResource() = default;
+
+void RecordableGraphResource::updateQueueSerial(Serial queueSerial)
+{
+    ASSERT(queueSerial >= mStoredQueueSerial);
+
+    if (queueSerial > mStoredQueueSerial)
+    {
+        mCurrentWritingNode = nullptr;
+        mCurrentReadingNodes.clear();
+        mStoredQueueSerial = queueSerial;
+    }
+}
+
+angle::Result RecordableGraphResource::recordCommands(Context *context,
+                                                      CommandBuffer **commandBufferOut)
 {
     updateQueueSerial(context->getRenderer()->getCurrentQueueSerial());
 
     if (!hasChildlessWritingNode() || hasStartedRenderPass())
     {
-        startNewCommands(context->getRenderer(), CommandGraphNodeFunction::Generic);
+        startNewCommands(context->getRenderer());
         return mCurrentWritingNode->beginOutsideRenderPassRecording(
             context, context->getRenderer()->getCommandPool(), commandBufferOut);
     }
@@ -143,8 +151,8 @@
     return angle::Result::Continue();
 }
 
-bool CommandGraphResource::appendToStartedRenderPass(RendererVk *renderer,
-                                                     CommandBuffer **commandBufferOut)
+bool RecordableGraphResource::appendToStartedRenderPass(RendererVk *renderer,
+                                                        CommandBuffer **commandBufferOut)
 {
     updateQueueSerial(renderer->getCurrentQueueSerial());
     if (hasStartedRenderPass())
@@ -158,23 +166,23 @@
     }
 }
 
-const gl::Rectangle &CommandGraphResource::getRenderPassRenderArea() const
+const gl::Rectangle &RecordableGraphResource::getRenderPassRenderArea() const
 {
     ASSERT(hasStartedRenderPass());
     return mCurrentWritingNode->getRenderPassRenderArea();
 }
 
-angle::Result CommandGraphResource::beginRenderPass(Context *context,
-                                                    const Framebuffer &framebuffer,
-                                                    const gl::Rectangle &renderArea,
-                                                    const RenderPassDesc &renderPassDesc,
-                                                    const std::vector<VkClearValue> &clearValues,
-                                                    CommandBuffer **commandBufferOut)
+angle::Result RecordableGraphResource::beginRenderPass(Context *context,
+                                                       const Framebuffer &framebuffer,
+                                                       const gl::Rectangle &renderArea,
+                                                       const RenderPassDesc &renderPassDesc,
+                                                       const std::vector<VkClearValue> &clearValues,
+                                                       CommandBuffer **commandBufferOut)
 {
     // If a barrier has been inserted in the meantime, stop the command buffer.
     if (!hasChildlessWritingNode())
     {
-        startNewCommands(context->getRenderer(), CommandGraphNodeFunction::Generic);
+        startNewCommands(context->getRenderer());
     }
 
     // Hard-code RenderPass to clear the first render target to the current clear value.
@@ -184,44 +192,7 @@
     return mCurrentWritingNode->beginInsideRenderPassRecording(context, commandBufferOut);
 }
 
-void CommandGraphResource::beginQuery(Context *context,
-                                      const QueryPool *queryPool,
-                                      uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::BeginQuery);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void CommandGraphResource::endQuery(Context *context,
-                                    const QueryPool *queryPool,
-                                    uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::EndQuery);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void CommandGraphResource::writeTimestamp(Context *context,
-                                          const QueryPool *queryPool,
-                                          uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::WriteTimestamp);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void CommandGraphResource::finishCurrentCommands(RendererVk *renderer)
-{
-    startNewCommands(renderer, CommandGraphNodeFunction::Generic);
-}
-
-void CommandGraphResource::startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function)
-{
-    bool isBarrier                = function != CommandGraphNodeFunction::Generic;
-    CommandGraphNode *newCommands = renderer->getCommandGraph()->allocateNode(isBarrier, function);
-    newCommands->setDiagnosticInfo(mResourceType, reinterpret_cast<uintptr_t>(this));
-    onWriteImpl(newCommands, renderer->getCurrentQueueSerial());
-}
-
-void CommandGraphResource::addWriteDependency(CommandGraphResource *writingResource)
+void RecordableGraphResource::addWriteDependency(RecordableGraphResource *writingResource)
 {
     CommandGraphNode *writingNode = writingResource->mCurrentWritingNode;
     ASSERT(writingNode);
@@ -229,7 +200,37 @@
     onWriteImpl(writingNode, writingResource->getStoredQueueSerial());
 }
 
-void CommandGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
+void RecordableGraphResource::addReadDependency(RecordableGraphResource *readingResource)
+{
+    updateQueueSerial(readingResource->getStoredQueueSerial());
+
+    CommandGraphNode *readingNode = readingResource->mCurrentWritingNode;
+    ASSERT(readingNode);
+
+    if (hasChildlessWritingNode())
+    {
+        // Ensure 'readingNode' happens after the current writing node.
+        CommandGraphNode::SetHappensBeforeDependency(mCurrentWritingNode, readingNode);
+    }
+
+    // Add the read node to the list of nodes currently reading this resource.
+    mCurrentReadingNodes.push_back(readingNode);
+}
+
+void RecordableGraphResource::finishCurrentCommands(RendererVk *renderer)
+{
+    startNewCommands(renderer);
+}
+
+void RecordableGraphResource::startNewCommands(RendererVk *renderer)
+{
+    CommandGraphNode *newCommands =
+        renderer->getCommandGraph()->allocateNode(CommandGraphNodeFunction::Generic);
+    newCommands->setDiagnosticInfo(mResourceType, reinterpret_cast<uintptr_t>(this));
+    onWriteImpl(newCommands, renderer->getCurrentQueueSerial());
+}
+
+void RecordableGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
 {
     updateQueueSerial(currentSerial);
 
@@ -249,21 +250,44 @@
     mCurrentWritingNode = writingNode;
 }
 
-void CommandGraphResource::addReadDependency(CommandGraphResource *readingResource)
+// QueryGraphResource implementation.
+QueryGraphResource::QueryGraphResource() : CommandGraphResource(CommandGraphResourceType::Query)
 {
-    updateQueueSerial(readingResource->getStoredQueueSerial());
+}
 
-    CommandGraphNode *readingNode = readingResource->mCurrentWritingNode;
-    ASSERT(readingNode);
+QueryGraphResource::~QueryGraphResource() = default;
 
-    if (hasChildlessWritingNode())
-    {
-        // Ensure 'readingNode' happens after the current writing node.
-        CommandGraphNode::SetHappensBeforeDependency(mCurrentWritingNode, readingNode);
-    }
+void QueryGraphResource::beginQuery(Context *context,
+                                    const QueryPool *queryPool,
+                                    uint32_t queryIndex)
+{
+    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::BeginQuery);
+    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
+}
 
-    // Add the read node to the list of nodes currently reading this resource.
-    mCurrentReadingNodes.push_back(readingNode);
+void QueryGraphResource::endQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex)
+{
+    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::EndQuery);
+    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
+}
+
+void QueryGraphResource::writeTimestamp(Context *context,
+                                        const QueryPool *queryPool,
+                                        uint32_t queryIndex)
+{
+    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::WriteTimestamp);
+    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
+}
+
+void QueryGraphResource::startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function)
+{
+    CommandGraph *commandGraph = renderer->getCommandGraph();
+    CommandGraphNode *newNode  = commandGraph->allocateNode(function);
+    newNode->setDiagnosticInfo(mResourceType, reinterpret_cast<uintptr_t>(this));
+    commandGraph->setNewBarrier(newNode);
+
+    mStoredQueueSerial  = renderer->getCurrentQueueSerial();
+    mCurrentWritingNode = newNode;
 }
 
 // CommandGraphNode implementation.
@@ -555,17 +579,11 @@
     ASSERT(empty());
 }
 
-CommandGraphNode *CommandGraph::allocateNode(bool isBarrier, CommandGraphNodeFunction function)
+CommandGraphNode *CommandGraph::allocateNode(CommandGraphNodeFunction function)
 {
     // TODO(jmadill): Use a pool allocator for the CPU node allocations.
     CommandGraphNode *newCommands = new CommandGraphNode(function);
     mNodes.emplace_back(newCommands);
-
-    if (isBarrier)
-    {
-        setNewBarrier(newCommands);
-    }
-
     return newCommands;
 }