Vulkan: Enable command queueing.
This adds the ability for rendering to happen asynchronously. If
objects in-use are deleted as they are being accessed, ownership
is transferred to the Renderer and they are deleted when not in
use. We determine they're ready for delete using a Fence object.
BUG=angleproject:1898
Change-Id: I4fcfd90ad0665d127bf01a10214a604f3407d9e4
Reviewed-on: https://chromium-review.googlesource.com/428353
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 490fad3..2df08e8 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -576,7 +576,7 @@
return &mCommandBuffer;
}
-vk::Error RendererVk::submitAndFinishCommandBuffer(const vk::CommandBuffer &commandBuffer)
+vk::Error RendererVk::submitCommandBuffer(const vk::CommandBuffer &commandBuffer)
{
VkFenceCreateInfo fenceInfo;
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@@ -599,7 +599,12 @@
// TODO(jmadill): Investigate how to properly submit command buffers.
ANGLE_TRY(submit(submitInfo));
- // Wait indefinitely for the queue to finish.
+ return vk::NoError();
+}
+
+vk::Error RendererVk::submitAndFinishCommandBuffer(const vk::CommandBuffer &commandBuffer)
+{
+ ANGLE_TRY(submitCommandBuffer(commandBuffer));
ANGLE_TRY(finish());
return vk::NoError();
@@ -635,13 +640,15 @@
vk::Error RendererVk::finish()
{
ASSERT(mQueue != VK_NULL_HANDLE);
- checkInFlightCommands();
ANGLE_VK_TRY(vkQueueWaitIdle(mQueue));
+ checkInFlightCommands();
return vk::NoError();
}
vk::Error RendererVk::checkInFlightCommands()
{
+ bool anyFinished = false;
+
// Check if any in-flight command buffers are finished.
for (size_t index = 0; index < mInFlightCommands.size();)
{
@@ -655,6 +662,7 @@
mLastCompletedQueueSerial = inFlightCommand->queueSerial();
inFlightCommand->destroy(mDevice);
mInFlightCommands.erase(mInFlightCommands.begin() + index);
+ anyFinished = true;
}
else
{
@@ -662,6 +670,22 @@
}
}
+ if (anyFinished)
+ {
+ size_t freeIndex = 0;
+ for (; freeIndex < mGarbage.size(); ++freeIndex)
+ {
+ if (!mGarbage[freeIndex]->destroyIfComplete(mDevice, mLastCompletedQueueSerial))
+ break;
+ }
+
+ // Remove the entries from the garbage list - they should be ready to go.
+ if (freeIndex > 0)
+ {
+ mGarbage.erase(mGarbage.begin(), mGarbage.begin() + freeIndex);
+ }
+ }
+
return vk::NoError();
}