Vulkan: Implement glFlush

A semaphore pool is implemented to allow dynamic allocation of
semaphores as needed when breaking up a frame with flushes.  The pool is
used both for acquiring the next image and for chaining mid-frame
submissions.

RendererVk::flush() is changed so that instead of taking the wait/signal
semaphores as parameters, it would use the last known signaled semaphore
as wait semaphore and allocates a semaphore for signaling.  It would
additionally wait for any extra semaphore provided externally (i.e. the
surface's image acquire semaphore).

Bug: angleproject:2504
Change-Id: Iecd2d5535230c48b26a6b7d078710af8730121da
Reviewed-on: https://chromium-review.googlesource.com/c/1276805
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index 6dfdefd..5b0d951 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -571,6 +571,10 @@
                                            CommandPool *commandPool,
                                            CommandBuffer *primaryCommandBufferOut)
 {
+    // There is no point in submitting an empty command buffer, so make sure not to call this
+    // function if there's nothing to do.
+    ASSERT(!mNodes.empty());
+
     size_t previousBarrierIndex       = 0;
     CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex);
 
@@ -582,6 +586,8 @@
             previousBarrier, &mNodes[previousBarrierIndex + 1], afterNodesCount);
     }
 
+    mLastBarrierIndex = kInvalidNodeIndex;
+
     VkCommandBufferAllocateInfo primaryInfo = {};
     primaryInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
     primaryInfo.commandPool        = commandPool->getHandle();
@@ -590,11 +596,6 @@
 
     ANGLE_TRY(primaryCommandBufferOut->init(context, primaryInfo));
 
-    if (mNodes.empty())
-    {
-        return angle::Result::Continue();
-    }
-
     if (mEnableGraphDiagnostics)
     {
         dumpGraphDotFile(std::cout);
@@ -650,7 +651,6 @@
         delete node;
     }
     mNodes.clear();
-    mLastBarrierIndex = kInvalidNodeIndex;
 
     return angle::Result::Continue();
 }