v3dv: drop layout refs for all allocated sets from a pool on destroy / reset

In 7f6ecb8667 we added reference counting for descriptor set layouts,
however, we didn't realize that pools created without the flag
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT don't free individual
descriptors and can only be reset or destroyed. Since we only drop
references when individual descriptor sets were destroyed, we would
leak set layouts referenced from descriptor sets allocated from these
pools.

Fix that by keeping a list of all allocated descriptor sets (no matter
whether VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT is present or
not) and then traversing the list dropping the references on pool resets
and destroys.

Fixes: 7f6ecb8667 ('v3dv: add reference counting for descriptor set layouts')
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19337>
(cherry picked from commit 07c7d846e5)
This commit is contained in:
Iago Toral Quiroga
2022-10-27 10:03:14 +02:00
committed by Dylan Baker
parent 81c02465a4
commit 511013d313
3 changed files with 29 additions and 5 deletions

View File

@@ -2740,7 +2740,7 @@
"description": "v3dv: drop layout refs for all allocated sets from a pool on destroy / reset",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "7f6ecb8667c6c756109954ad23f8c2c0ae0a9bf8"
},

View File

@@ -504,6 +504,8 @@ v3dv_CreateDescriptorPool(VkDevice _device,
pool->bo = NULL;
}
list_inithead(&pool->set_list);
*pDescriptorPool = v3dv_descriptor_pool_to_handle(pool);
return VK_SUCCESS;
@@ -521,8 +523,6 @@ descriptor_set_destroy(struct v3dv_device *device,
{
assert(!pool->host_memory_base);
v3dv_descriptor_set_layout_unref(device, set->layout);
if (free_bo && !pool->host_memory_base) {
for (uint32_t i = 0; i < pool->entry_count; i++) {
if (pool->entries[i].set == set) {
@@ -547,6 +547,11 @@ v3dv_DestroyDescriptorPool(VkDevice _device,
if (!pool)
return;
list_for_each_entry_safe(struct v3dv_descriptor_set, set,
&pool->set_list, pool_link) {
v3dv_descriptor_set_layout_unref(device, set->layout);
}
if (!pool->host_memory_base) {
for(int i = 0; i < pool->entry_count; ++i) {
descriptor_set_destroy(device, pool, pool->entries[i].set, false);
@@ -569,6 +574,12 @@ v3dv_ResetDescriptorPool(VkDevice _device,
V3DV_FROM_HANDLE(v3dv_device, device, _device);
V3DV_FROM_HANDLE(v3dv_descriptor_pool, pool, descriptorPool);
list_for_each_entry_safe(struct v3dv_descriptor_set, set,
&pool->set_list, pool_link) {
v3dv_descriptor_set_layout_unref(device, set->layout);
}
list_inithead(&pool->set_list);
if (!pool->host_memory_base) {
for(int i = 0; i < pool->entry_count; ++i) {
descriptor_set_destroy(device, pool, pool->entries[i].set, false);
@@ -898,6 +909,8 @@ descriptor_set_create(struct v3dv_device *device,
}
v3dv_descriptor_set_layout_ref(layout);
list_addtail(&set->pool_link, &pool->set_list);
*out_set = set;
return VK_SUCCESS;
@@ -948,9 +961,14 @@ v3dv_FreeDescriptorSets(VkDevice _device,
for (uint32_t i = 0; i < count; i++) {
V3DV_FROM_HANDLE(v3dv_descriptor_set, set, pDescriptorSets[i]);
if (set && !pool->host_memory_base)
if (set) {
v3dv_descriptor_set_layout_unref(device, set->layout);
list_del(&set->pool_link);
if (!pool->host_memory_base)
descriptor_set_destroy(device, pool, set, true);
}
}
return VK_SUCCESS;
}

View File

@@ -1667,6 +1667,9 @@ struct v3dv_descriptor_pool_entry
struct v3dv_descriptor_pool {
struct vk_object_base base;
/* A list with all descriptor sets allocated from the pool. */
struct list_head set_list;
/* If this descriptor pool has been allocated for the driver for internal
* use, typically to implement meta operations.
*/
@@ -1696,6 +1699,9 @@ struct v3dv_descriptor_pool {
struct v3dv_descriptor_set {
struct vk_object_base base;
/* List link into the list of all sets allocated from the pool */
struct list_head pool_link;
struct v3dv_descriptor_pool *pool;
struct v3dv_descriptor_set_layout *layout;