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.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index 16d4a8f..eb20678 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -161,11 +161,34 @@
     // Returns true if the resource has unsubmitted work pending.
     bool hasPendingWork(RendererVk *renderer) const;
 
+    // Get the current queue serial for this resource. Used to release resources, and for
+    // queries, to know if the queue they are submitted on has finished execution.
+    Serial getStoredQueueSerial() const;
+
+  protected:
+    explicit CommandGraphResource(CommandGraphResourceType resourceType);
+
+    Serial mStoredQueueSerial;
+
+    // Additional diagnostic information.
+    CommandGraphResourceType mResourceType;
+
+    // Current command graph writing node.
+    CommandGraphNode *mCurrentWritingNode;
+};
+
+// Subclass of graph resources that can record command buffers. Images/Buffers/Framebuffers.
+// Does not include Query graph resources.
+class RecordableGraphResource : public CommandGraphResource
+{
+  public:
+    ~RecordableGraphResource() override;
+
     // Sets up dependency relations. 'this' resource is the resource being written to.
-    void addWriteDependency(CommandGraphResource *writingResource);
+    void addWriteDependency(RecordableGraphResource *writingResource);
 
     // Sets up dependency relations. 'this' resource is the resource being read.
-    void addReadDependency(CommandGraphResource *readingResource);
+    void addReadDependency(RecordableGraphResource *readingResource);
 
     // Allocates a write node via getNewWriteNode and returns a started command buffer.
     // The started command buffer will render outside of a RenderPass.
@@ -181,10 +204,6 @@
                                   const std::vector<VkClearValue> &clearValues,
                                   CommandBuffer **commandBufferOut);
 
-    void beginQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-    void endQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-    void writeTimestamp(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-
     // Checks if we're in a RenderPass, returning true if so. Updates serial internally.
     // Returns the started command buffer in commandBufferOut.
     bool appendToStartedRenderPass(RendererVk *renderer, CommandBuffer **commandBufferOut);
@@ -195,17 +214,10 @@
     // Called when 'this' object changes, but we'd like to start a new command buffer later.
     void finishCurrentCommands(RendererVk *renderer);
 
-    // Get the current queue serial for this resource. Used to release resources, and for
-    // queries, to know if the queue they are submitted on has finished execution.
-    Serial getStoredQueueSerial() const;
-
   protected:
-    explicit CommandGraphResource(CommandGraphResourceType resourceType);
+    explicit RecordableGraphResource(CommandGraphResourceType resourceType);
 
   private:
-    void startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function);
-
-    void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial);
 
     // Returns true if this node has a current writing node with no children.
     bool hasChildlessWritingNode() const
@@ -231,12 +243,28 @@
     // was not used in this set of command nodes.
     void updateQueueSerial(Serial queueSerial);
 
-    Serial mStoredQueueSerial;
-    std::vector<CommandGraphNode *> mCurrentReadingNodes;
-    CommandGraphNode *mCurrentWritingNode;
+    void startNewCommands(RendererVk *renderer);
 
-    // Additional diagnostic information.
-    CommandGraphResourceType mResourceType;
+    void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial);
+
+    std::vector<CommandGraphNode *> mCurrentReadingNodes;
+};
+
+// Specialized command graph node for queries. Not for use with any exposed command buffers.
+class QueryGraphResource : public CommandGraphResource
+{
+  public:
+    ~QueryGraphResource() override;
+
+    void beginQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
+    void endQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
+    void writeTimestamp(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
+
+  protected:
+    QueryGraphResource();
+
+  private:
+    void startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function);
 };
 
 // Translating OpenGL commands into Vulkan and submitting them immediately loses out on some
@@ -270,7 +298,7 @@
     // relations exist in the node by default. Call CommandGraphNode::SetHappensBeforeDependency
     // to set up dependency relations. If the node is a barrier, it will automatically add
     // dependencies between the previous barrier, the new barrier and all nodes in between.
-    CommandGraphNode *allocateNode(bool isBarrier, CommandGraphNodeFunction function);
+    CommandGraphNode *allocateNode(CommandGraphNodeFunction function);
 
     angle::Result submitCommands(Context *context,
                                  Serial serial,
@@ -281,10 +309,11 @@
 
     CommandGraphNode *getLastBarrierNode(size_t *indexOut);
 
+    void setNewBarrier(CommandGraphNode *newBarrier);
+
   private:
     void dumpGraphDotFile(std::ostream &out) const;
 
-    void setNewBarrier(CommandGraphNode *newBarrier);
     void addDependenciesToNextBarrier(size_t begin, size_t end, CommandGraphNode *nextBarrier);
 
     std::vector<CommandGraphNode *> mNodes;