diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 7729e8a1dd..53538a8ee8 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -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; - fn.DestroyCommandPool(mVkDevice, mRecordingContext.commandPool, nullptr); + 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(); @@ -899,4 +912,4 @@ namespace dawn_native { namespace vulkan { mVkDevice = VK_NULL_HANDLE; } -}} // namespace dawn_native::vulkan \ No newline at end of file +}} // namespace dawn_native::vulkan