lavapipe: add reference counting to descriptor set layout

asan flagged some use after frees, copy the anv solution
of refcounting the descriptor set layout objects.

dEQP-VK.api.descriptor_set.descriptor_set_layout_lifetime.*

Acked-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9093>
This commit is contained in:
Dave Airlie
2021-02-09 13:44:58 +10:00
committed by Marge Bot
parent d12cecbd53
commit f94a5f30e0
2 changed files with 45 additions and 5 deletions

View File

@@ -54,6 +54,7 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorSetLayout(
vk_object_base_init(&device->vk, &set_layout->base, vk_object_base_init(&device->vk, &set_layout->base,
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
set_layout->ref_cnt = 1;
/* We just allocate all the samplers at the end of the struct */ /* We just allocate all the samplers at the end of the struct */
struct lvp_sampler **samplers = struct lvp_sampler **samplers =
(struct lvp_sampler **)&set_layout->binding[max_binding + 1]; (struct lvp_sampler **)&set_layout->binding[max_binding + 1];
@@ -156,6 +157,15 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorSetLayout(
return VK_SUCCESS; return VK_SUCCESS;
} }
void
lvp_descriptor_set_layout_destroy(struct lvp_device *device,
struct lvp_descriptor_set_layout *layout)
{
assert(layout->ref_cnt == 0);
vk_object_base_finish(&layout->base);
vk_free(&device->vk.alloc, layout);
}
VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorSetLayout( VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorSetLayout(
VkDevice _device, VkDevice _device,
VkDescriptorSetLayout _set_layout, VkDescriptorSetLayout _set_layout,
@@ -166,8 +176,8 @@ VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorSetLayout(
if (!_set_layout) if (!_set_layout)
return; return;
vk_object_base_finish(&set_layout->base);
vk_free2(&device->vk.alloc, pAllocator, set_layout); lvp_descriptor_set_layout_unref(device, set_layout);
} }
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePipelineLayout( VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePipelineLayout(
@@ -194,6 +204,7 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePipelineLayout(
LVP_FROM_HANDLE(lvp_descriptor_set_layout, set_layout, LVP_FROM_HANDLE(lvp_descriptor_set_layout, set_layout,
pCreateInfo->pSetLayouts[set]); pCreateInfo->pSetLayouts[set]);
layout->set[set].layout = set_layout; layout->set[set].layout = set_layout;
lvp_descriptor_set_layout_ref(set_layout);
} }
layout->push_constant_size = 0; layout->push_constant_size = 0;
@@ -218,13 +229,16 @@ VKAPI_ATTR void VKAPI_CALL lvp_DestroyPipelineLayout(
if (!_pipelineLayout) if (!_pipelineLayout)
return; return;
for (uint32_t i = 0; i < pipeline_layout->num_sets; i++)
lvp_descriptor_set_layout_unref(device, pipeline_layout->set[i].layout);
vk_object_base_finish(&pipeline_layout->base); vk_object_base_finish(&pipeline_layout->base);
vk_free2(&device->vk.alloc, pAllocator, pipeline_layout); vk_free2(&device->vk.alloc, pAllocator, pipeline_layout);
} }
VkResult VkResult
lvp_descriptor_set_create(struct lvp_device *device, lvp_descriptor_set_create(struct lvp_device *device,
const struct lvp_descriptor_set_layout *layout, struct lvp_descriptor_set_layout *layout,
struct lvp_descriptor_set **out_set) struct lvp_descriptor_set **out_set)
{ {
struct lvp_descriptor_set *set; struct lvp_descriptor_set *set;
@@ -243,6 +257,7 @@ lvp_descriptor_set_create(struct lvp_device *device,
vk_object_base_init(&device->vk, &set->base, vk_object_base_init(&device->vk, &set->base,
VK_OBJECT_TYPE_DESCRIPTOR_SET); VK_OBJECT_TYPE_DESCRIPTOR_SET);
set->layout = layout; set->layout = layout;
lvp_descriptor_set_layout_ref(layout);
/* Go through and fill out immutable samplers if we have any */ /* Go through and fill out immutable samplers if we have any */
struct lvp_descriptor *desc = set->descriptors; struct lvp_descriptor *desc = set->descriptors;
@@ -263,6 +278,7 @@ void
lvp_descriptor_set_destroy(struct lvp_device *device, lvp_descriptor_set_destroy(struct lvp_device *device,
struct lvp_descriptor_set *set) struct lvp_descriptor_set *set)
{ {
lvp_descriptor_set_layout_unref(device, set->layout);
vk_object_base_finish(&set->base); vk_object_base_finish(&set->base);
vk_free(&device->vk.alloc, set); vk_free(&device->vk.alloc, set);
} }
@@ -460,6 +476,7 @@ static void lvp_reset_descriptor_pool(struct lvp_device *device,
{ {
struct lvp_descriptor_set *set, *tmp; struct lvp_descriptor_set *set, *tmp;
LIST_FOR_EACH_ENTRY_SAFE(set, tmp, &pool->sets, link) { LIST_FOR_EACH_ENTRY_SAFE(set, tmp, &pool->sets, link) {
lvp_descriptor_set_layout_unref(device, set->layout);
list_del(&set->link); list_del(&set->link);
vk_free(&device->vk.alloc, set); vk_free(&device->vk.alloc, set);
} }

View File

@@ -416,6 +416,10 @@ struct lvp_descriptor_set_binding_layout {
struct lvp_descriptor_set_layout { struct lvp_descriptor_set_layout {
struct vk_object_base base; struct vk_object_base base;
/* Descriptor set layouts can be destroyed at almost any time */
uint32_t ref_cnt;
/* Number of bindings in this descriptor set */ /* Number of bindings in this descriptor set */
uint16_t binding_count; uint16_t binding_count;
@@ -440,6 +444,25 @@ struct lvp_descriptor_set_layout {
struct lvp_descriptor_set_binding_layout binding[0]; struct lvp_descriptor_set_binding_layout binding[0];
}; };
void lvp_descriptor_set_layout_destroy(struct lvp_device *device,
struct lvp_descriptor_set_layout *layout);
static inline void
lvp_descriptor_set_layout_ref(struct lvp_descriptor_set_layout *layout)
{
assert(layout && layout->ref_cnt >= 1);
p_atomic_inc(&layout->ref_cnt);
}
static inline void
lvp_descriptor_set_layout_unref(struct lvp_device *device,
struct lvp_descriptor_set_layout *layout)
{
assert(layout && layout->ref_cnt >= 1);
if (p_atomic_dec_zero(&layout->ref_cnt))
lvp_descriptor_set_layout_destroy(device, layout);
}
union lvp_descriptor_info { union lvp_descriptor_info {
struct { struct {
struct lvp_sampler *sampler; struct lvp_sampler *sampler;
@@ -462,7 +485,7 @@ struct lvp_descriptor {
struct lvp_descriptor_set { struct lvp_descriptor_set {
struct vk_object_base base; struct vk_object_base base;
const struct lvp_descriptor_set_layout *layout; struct lvp_descriptor_set_layout *layout;
struct list_head link; struct list_head link;
struct lvp_descriptor descriptors[0]; struct lvp_descriptor descriptors[0];
}; };
@@ -488,7 +511,7 @@ struct lvp_descriptor_update_template {
VkResult VkResult
lvp_descriptor_set_create(struct lvp_device *device, lvp_descriptor_set_create(struct lvp_device *device,
const struct lvp_descriptor_set_layout *layout, struct lvp_descriptor_set_layout *layout,
struct lvp_descriptor_set **out_set); struct lvp_descriptor_set **out_set);
void void