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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user