Vulkan: Add dumping of the command graph to GraphViz.

Dot files are a graph format that can be visualized with GraphViz.
Giving a small visualization output can help diagnose problems with
the graph. For example extra edges or incorrect dependencies.

Bug: angleproject:2379
Change-Id: I544cba11c5e33579b06fef2fb41bad60066a64e4
Reviewed-on: https://chromium-review.googlesource.com/1254383
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tobin Ehlis <tobine@google.com>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index 447ddd1..894f6ae 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -24,6 +24,13 @@
     Visited,
 };
 
+enum class CommandGraphResourceType
+{
+    Buffer,
+    Framebuffer,
+    Image,
+};
+
 // Only used internally in the command graph. Kept in the header for better inlining performance.
 class CommandGraphNode final : angle::NonCopyable
 {
@@ -72,6 +79,13 @@
                                   RenderPassCache *renderPassCache,
                                   CommandBuffer *primaryCommandBuffer);
 
+    // Only used in the command graph diagnostics.
+    const std::vector<CommandGraphNode *> &getParentsForDiagnostics() const;
+    void setDiagnosticInfo(CommandGraphResourceType resourceType, uintptr_t resourceID);
+
+    CommandGraphResourceType getResourceTypeForDiagnostics() const { return mResourceType; }
+    uintptr_t getResourceIDForDiagnostics() const { return mResourceID; }
+
     const gl::Rectangle &getRenderPassRenderArea() const;
 
   private:
@@ -99,6 +113,10 @@
 
     // Used when traversing the dependency graph.
     VisitedState mVisitedState;
+
+    // Additional diagnostic information.
+    CommandGraphResourceType mResourceType;
+    uintptr_t mResourceID;
 };
 
 // This is a helper class for back-end objects used in Vk command buffers. It records a serial
@@ -107,10 +125,9 @@
 // queue serial in a special 'garbage' queue. Resources also track current read and write
 // dependencies. Only one command buffer node can be writing to the Resource at a time, but many
 // can be reading from it. Together the dependencies will form a command graph at submission time.
-class CommandGraphResource
+class CommandGraphResource : angle::NonCopyable
 {
   public:
-    CommandGraphResource();
     virtual ~CommandGraphResource();
 
     // Returns true if the resource is in use by the renderer.
@@ -147,6 +164,8 @@
     void finishCurrentCommands(RendererVk *renderer);
 
   protected:
+    explicit CommandGraphResource(CommandGraphResourceType resourceType);
+
     // Get the current queue serial for this resource. Only used to release resources.
     Serial getStoredQueueSerial() const;
 
@@ -173,6 +192,9 @@
     Serial mStoredQueueSerial;
     std::vector<CommandGraphNode *> mCurrentReadingNodes;
     CommandGraphNode *mCurrentWritingNode;
+
+    // Additional diagnostic information.
+    CommandGraphResourceType mResourceType;
 };
 
 // Translating OpenGL commands into Vulkan and submitting them immediately loses out on some
@@ -199,7 +221,7 @@
 class CommandGraph final : angle::NonCopyable
 {
   public:
-    CommandGraph();
+    explicit CommandGraph(bool enableGraphDiagnostics);
     ~CommandGraph();
 
     // Allocates a new CommandGraphNode and adds it to the list of current open nodes. No ordering
@@ -215,9 +237,11 @@
     bool empty() const;
 
   private:
-    std::vector<CommandGraphNode *> mNodes;
-};
+    void dumpGraphDotFile(std::ostream &out) const;
 
+    std::vector<CommandGraphNode *> mNodes;
+    bool mEnableGraphDiagnostics;
+};
 }  // namespace vk
 }  // namespace rx