Commit bc30e72c by Jamie Madill Committed by Commit Bot

Vulkan: Recycle command pools with vkResetCommandPool.

vkDestroyCommandPool has worse performance than reset. Instead of destroying and creating new command pools for every batch of work we can instead recycle unused command pools. This seems to improve performance on most systems. Bug: angleproject:3489 Change-Id: I7f8fe7f9385ca481e04f226a26426c3e92da19ff Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1636410Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
parent 94d5e051
...@@ -220,10 +220,11 @@ void ContextVk::onDestroy(const gl::Context *context) ...@@ -220,10 +220,11 @@ void ContextVk::onDestroy(const gl::Context *context)
mSubmitFence.reset(device); mSubmitFence.reset(device);
mShaderLibrary.destroy(device); mShaderLibrary.destroy(device);
mGpuEventQueryPool.destroy(device); mGpuEventQueryPool.destroy(device);
mCommandPool.destroy(device);
if (mCommandPool.valid()) for (vk::CommandPool &pool : mCommandPoolFreeList)
{ {
mCommandPool.destroy(device); pool.destroy(device);
} }
} }
...@@ -240,13 +241,13 @@ angle::Result ContextVk::initialize() ...@@ -240,13 +241,13 @@ angle::Result ContextVk::initialize()
{ {
TRACE_EVENT0("gpu.angle", "ContextVk::initialize"); TRACE_EVENT0("gpu.angle", "ContextVk::initialize");
// Note that this may reserve more sets than strictly necessary for a particular layout. // Note that this may reserve more sets than strictly necessary for a particular layout.
VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VkDescriptorPoolSize uniformSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
GetUniformBufferDescriptorCount()}; GetUniformBufferDescriptorCount()};
VkDescriptorPoolSize uniformBlockSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VkDescriptorPoolSize uniformBlockSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
mRenderer->getMaxUniformBlocks()}; mRenderer->getMaxUniformBlocks()};
VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VkDescriptorPoolSize textureSetSize = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
mRenderer->getMaxActiveTextures()}; mRenderer->getMaxActiveTextures()};
VkDescriptorPoolSize driverSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}; VkDescriptorPoolSize driverSetSize = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1};
ANGLE_TRY(mDynamicDescriptorPools[kUniformsDescriptorSetIndex].init(this, &uniformSetSize, 1)); ANGLE_TRY(mDynamicDescriptorPools[kUniformsDescriptorSetIndex].init(this, &uniformSetSize, 1));
ANGLE_TRY(mDynamicDescriptorPools[kUniformBlockDescriptorSetIndex].init( ANGLE_TRY(mDynamicDescriptorPools[kUniformBlockDescriptorSetIndex].init(
this, &uniformBlockSetSize, 1)); this, &uniformBlockSetSize, 1));
...@@ -681,7 +682,16 @@ angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo, ...@@ -681,7 +682,16 @@ angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
poolInfo.queueFamilyIndex = getRenderer()->getQueueFamilyIndex(); poolInfo.queueFamilyIndex = getRenderer()->getQueueFamilyIndex();
ANGLE_VK_TRY(this, mCommandPool.init(device, poolInfo)); if (mCommandPoolFreeList.empty())
{
ANGLE_VK_TRY(this, mCommandPool.init(device, poolInfo));
}
else
{
mCommandPool = std::move(mCommandPoolFreeList.back());
mCommandPoolFreeList.pop_back();
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -698,7 +708,10 @@ void ContextVk::freeAllInFlightResources() ...@@ -698,7 +708,10 @@ void ContextVk::freeAllInFlightResources()
// If wait times out, it is probably not possible to recover from lost device // If wait times out, it is probably not possible to recover from lost device
ASSERT(status == VK_SUCCESS || status == VK_ERROR_DEVICE_LOST); ASSERT(status == VK_SUCCESS || status == VK_ERROR_DEVICE_LOST);
} }
batch.commandPool.destroy(device);
batch.commandPool.reset(device, 0);
mCommandPoolFreeList.emplace_back(std::move(batch.commandPool));
batch.fence.reset(device); batch.fence.reset(device);
} }
mInFlightCommands.clear(); mInFlightCommands.clear();
...@@ -860,8 +873,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime() ...@@ -860,8 +873,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
// Submit the command buffer // Submit the command buffer
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), {}, &waitMask, InitializeSubmitInfo(&submitInfo, commandBatch.get(), {}, &waitMask, {});
{});
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBuffer))); ANGLE_TRY(submitFrame(submitInfo, std::move(commandBuffer)));
......
...@@ -469,7 +469,10 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff ...@@ -469,7 +469,10 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
gl::AttributesMask mDirtyDefaultAttribsMask; gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers; gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
// We use a single pool for recording commands. We also keep a free list for pool recycling.
vk::CommandPool mCommandPool; vk::CommandPool mCommandPool;
std::vector<vk::CommandPool> mCommandPoolFreeList;
Serial mLastCompletedQueueSerial; Serial mLastCompletedQueueSerial;
Serial mLastSubmittedQueueSerial; Serial mLastSubmittedQueueSerial;
Serial mCurrentQueueSerial; Serial mCurrentQueueSerial;
......
...@@ -143,6 +143,7 @@ class CommandPool final : public WrappedObject<CommandPool, VkCommandPool> ...@@ -143,6 +143,7 @@ class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
CommandPool() = default; CommandPool() = default;
void destroy(VkDevice device); void destroy(VkDevice device);
VkResult reset(VkDevice device, VkCommandPoolResetFlags flags);
VkResult init(VkDevice device, const VkCommandPoolCreateInfo &createInfo); VkResult init(VkDevice device, const VkCommandPoolCreateInfo &createInfo);
}; };
...@@ -555,6 +556,12 @@ ANGLE_INLINE void CommandPool::destroy(VkDevice device) ...@@ -555,6 +556,12 @@ ANGLE_INLINE void CommandPool::destroy(VkDevice device)
} }
} }
ANGLE_INLINE VkResult CommandPool::reset(VkDevice device, VkCommandPoolResetFlags flags)
{
ASSERT(valid());
return vkResetCommandPool(device, mHandle, flags);
}
ANGLE_INLINE VkResult CommandPool::init(VkDevice device, const VkCommandPoolCreateInfo &createInfo) ANGLE_INLINE VkResult CommandPool::init(VkDevice device, const VkCommandPoolCreateInfo &createInfo)
{ {
ASSERT(!valid()); ASSERT(!valid());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment