Call vkFreeCommandBuffers before destroying the vkCommandPool

This should not be necessary as the command pool should own the
memory if it was created without the creation flag
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT. However, some drivers
leak memory if vkFreeCommandBuffers is not called.

Bug: chromium:1082181
Change-Id: Ia437fc17b2a304a248b9227b43cfff1868f9f10e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/25062
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Austin Eng 2020-07-17 15:26:56 +00:00 committed by Commit Bot service account
parent 64dd82e94f
commit 4b7ca6bf96
1 changed files with 15 additions and 2 deletions

View File

@ -852,7 +852,15 @@ namespace dawn_native { namespace vulkan {
// Immediately tag the recording context as unused so we don't try to submit it in Tick.
mRecordingContext.used = false;
if (mRecordingContext.commandPool != VK_NULL_HANDLE) {
// The VkCommandBuffer memory should be wholly owned by the pool and freed when it is
// destroyed, but that's not the case in some drivers and the leak memory.
// So we call FreeCommandBuffers before DestroyCommandPool to be safe.
// TODO(enga): Only do this on a known list of bad drivers.
fn.FreeCommandBuffers(mVkDevice, mRecordingContext.commandPool, 1,
&mRecordingContext.commandBuffer);
fn.DestroyCommandPool(mVkDevice, mRecordingContext.commandPool, nullptr);
}
for (VkSemaphore semaphore : mRecordingContext.waitSemaphores) {
fn.DestroySemaphore(mVkDevice, semaphore, nullptr);
@ -866,6 +874,11 @@ namespace dawn_native { namespace vulkan {
ASSERT(mCommandsInFlight.Empty());
for (const CommandPoolAndBuffer& commands : mUnusedCommands) {
// The VkCommandBuffer memory should be wholly owned by the pool and freed when it is
// destroyed, but that's not the case in some drivers and the leak memory.
// So we call FreeCommandBuffers before DestroyCommandPool to be safe.
// TODO(enga): Only do this on a known list of bad drivers.
fn.FreeCommandBuffers(mVkDevice, commands.pool, 1, &commands.commandBuffer);
fn.DestroyCommandPool(mVkDevice, commands.pool, nullptr);
}
mUnusedCommands.clear();