diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 00fc3876a97..cd5df56fbb9 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -2292,6 +2292,19 @@ bool RenderingDeviceDriverD3D12::command_pool_reset(CommandPoolID p_cmd_pool) { void RenderingDeviceDriverD3D12::command_pool_free(CommandPoolID p_cmd_pool) { CommandPoolInfo *command_pool = (CommandPoolInfo *)(p_cmd_pool.id); + + // Destroy all command buffers associated with this command pool, mirroring Vulkan's behavior. + SelfList *cmd_buf_elem = command_pool->command_buffers.first(); + while (cmd_buf_elem != nullptr) { + CommandBufferInfo *cmd_buf_info = cmd_buf_elem->self(); + cmd_buf_elem = cmd_buf_elem->next(); + + cmd_buf_info->cmd_list.Reset(); + cmd_buf_info->cmd_allocator.Reset(); + + VersatileResource::free(resources_allocator, cmd_buf_info); + } + memdelete(command_pool); } @@ -2300,7 +2313,7 @@ void RenderingDeviceDriverD3D12::command_pool_free(CommandPoolID p_cmd_pool) { RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPoolID p_cmd_pool) { DEV_ASSERT(p_cmd_pool); - const CommandPoolInfo *command_pool = (CommandPoolInfo *)(p_cmd_pool.id); + CommandPoolInfo *command_pool = (CommandPoolInfo *)(p_cmd_pool.id); D3D12_COMMAND_LIST_TYPE list_type; if (command_pool->buffer_type == COMMAND_BUFFER_TYPE_SECONDARY) { list_type = D3D12_COMMAND_LIST_TYPE_BUNDLE; @@ -2336,6 +2349,9 @@ RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPo cmd_buf_info->cmd_allocator = cmd_allocator; cmd_buf_info->cmd_list = cmd_list; + // Add this command buffer to the command pool's list of command buffers. + command_pool->command_buffers.add(&cmd_buf_info->command_buffer_info_elem); + return CommandBufferID(cmd_buf_info); } diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 59c81db726b..5bcef066421 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -430,6 +430,9 @@ private: struct CommandPoolInfo { CommandQueueFamilyID queue_family; CommandBufferType buffer_type = COMMAND_BUFFER_TYPE_PRIMARY; + // Since there are no command pools in D3D12, we need to track the command buffers created by this pool + // so that we can free them when the pool is freed. + SelfList::List command_buffers; }; public: @@ -458,6 +461,9 @@ private: // Leveraging knowledge of actual usage and D3D12 specifics (namely, command lists from the same allocator // can't be freely begun and ended), an allocator per list works better. struct CommandBufferInfo { + // Store a self list reference to be used by the command pool. + SelfList command_buffer_info_elem{ this }; + ComPtr cmd_allocator; ComPtr cmd_list;