Free VkCommandPool if vkResetCommandPool fails
Bug: chromium:1234680
Change-Id: If8f5c2dc0cdf14bf8a0c713d724b883657bd1463
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/61103
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 2f1e4d9..5e72eac 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -565,8 +565,22 @@
if (!mUnusedCommands.empty()) {
CommandPoolAndBuffer commands = mUnusedCommands.back();
mUnusedCommands.pop_back();
- DAWN_TRY(CheckVkSuccess(fn.ResetCommandPool(mVkDevice, commands.pool, 0),
- "vkResetCommandPool"));
+ DAWN_TRY_WITH_CLEANUP(CheckVkSuccess(fn.ResetCommandPool(mVkDevice, commands.pool, 0),
+ "vkResetCommandPool"),
+ {
+ // vkResetCommandPool failed (it may return out-of-memory).
+ // Free the commands in the cleanup step before returning to
+ // reclaim memory.
+
+ // 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 they 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);
+ });
mRecordingContext.commandBuffer = commands.commandBuffer;
mRecordingContext.commandPool = commands.pool;