Vulkan: Implement command re-ordering.

This introduces a new CommandBufferNode class. Nodes are linked
together to form a graph based on their dependencies. When the app
triggers a readback or swap, the graph is flushed entirely. This
sends the queued ANGLE Vulkan work to the Vulkan queue which is
then processed on the GPU with the right dependencies.

This design allows us to save on some unnecessary RenderPass creation
and also allows us to know what load/store ops to use. It also allows
us to take advantage of the Vulkan automatic RenderPass transitions
for performance. Load/Store ops and automatic transitions will be
implemented in later patches.

Bug: angleproject:2264
Change-Id: I0e729c719e38254202c6fedcede4e63125eb4810
Reviewed-on: https://chromium-review.googlesource.com/780849
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 0ce3d18..6ce71d2 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -13,6 +13,7 @@
 
 #include "libANGLE/Context.h"
 #include "libANGLE/renderer/vulkan/BufferVk.h"
+#include "libANGLE/renderer/vulkan/CommandBufferNode.h"
 #include "libANGLE/renderer/vulkan/ContextVk.h"
 #include "libANGLE/renderer/vulkan/formatutilsvk.h"
 
@@ -48,7 +49,7 @@
     // Invalidate current pipeline.
     // TODO(jmadill): Use pipeline cache.
     ContextVk *contextVk = vk::GetImpl(context);
-    contextVk->invalidateCurrentPipeline();
+    contextVk->onVertexArrayChange();
 
     // Invalidate the vertex descriptions.
     invalidateVertexDescriptions();
@@ -107,22 +108,23 @@
     return mCurrentArrayBufferHandles;
 }
 
-void VertexArrayVk::updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask,
-                                               Serial serial,
-                                               DrawType drawType)
+void VertexArrayVk::updateDrawDependencies(vk::CommandBufferNode *readNode,
+                                           const gl::AttributesMask &activeAttribsMask,
+                                           Serial serial,
+                                           DrawType drawType)
 {
     // Handle the bound array buffers.
     for (auto attribIndex : activeAttribsMask)
     {
         ASSERT(mCurrentArrayBufferResources[attribIndex]);
-        mCurrentArrayBufferResources[attribIndex]->setQueueSerial(serial);
+        mCurrentArrayBufferResources[attribIndex]->updateDependencies(readNode, serial);
     }
 
     // Handle the bound element array buffer.
     if (drawType == DrawType::Elements)
     {
         ASSERT(mCurrentElementArrayBufferResource);
-        mCurrentElementArrayBufferResource->setQueueSerial(serial);
+        mCurrentElementArrayBufferResource->updateDependencies(readNode, serial);
     }
 }