panvk: Refcount the descriptor set and pipeline layouts

Lifetime of descriptor sets and pipeline layouts are odd. Let's refcount
them so we don't end up with use-after-free patterns.

That means we can't use custom allocators for those objects.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14406>
This commit is contained in:
Boris Brezillon
2022-03-09 18:49:22 +01:00
committed by Marge Bot
parent df92f56d8d
commit 18fced0226
2 changed files with 70 additions and 5 deletions

View File

@@ -71,7 +71,7 @@ panvk_CreateDescriptorSetLayout(VkDevice _device,
(sizeof(struct panvk_descriptor_set_binding_layout) *
num_bindings) +
(sizeof(struct panvk_sampler *) * num_immutable_samplers);
set_layout = vk_object_zalloc(&device->vk, pAllocator, size,
set_layout = vk_object_zalloc(&device->vk, NULL, size,
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
if (!set_layout) {
result = VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -165,6 +165,7 @@ panvk_CreateDescriptorSetLayout(VkDevice _device,
set_layout->num_ssbos = ssbo_idx;
set_layout->num_dyn_ssbos = dyn_ssbo_idx;
set_layout->num_imgs = img_idx;
p_atomic_set(&set_layout->refcount, 1);
free(bindings);
*pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout);
@@ -175,6 +176,13 @@ err_free_bindings:
return vk_error(device, result);
}
void
panvk_descriptor_set_layout_destroy(struct panvk_device *device,
struct panvk_descriptor_set_layout *layout)
{
vk_object_free(&device->vk, NULL, layout);
}
void
panvk_DestroyDescriptorSetLayout(VkDevice _device,
VkDescriptorSetLayout _set_layout,
@@ -186,7 +194,7 @@ panvk_DestroyDescriptorSetLayout(VkDevice _device,
if (!set_layout)
return;
vk_object_free(&device->vk, pAllocator, set_layout);
panvk_descriptor_set_layout_unref(device, set_layout);
}
/* FIXME: make sure those values are correct */
@@ -281,7 +289,7 @@ panvk_CreatePipelineLayout(VkDevice _device,
struct panvk_pipeline_layout *layout;
struct mesa_sha1 ctx;
layout = vk_object_zalloc(&device->vk, pAllocator, sizeof(*layout),
layout = vk_object_zalloc(&device->vk, NULL, sizeof(*layout),
VK_OBJECT_TYPE_PIPELINE_LAYOUT);
if (layout == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -294,7 +302,8 @@ panvk_CreatePipelineLayout(VkDevice _device,
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout,
pCreateInfo->pSetLayouts[set]);
layout->sets[set].layout = set_layout;
layout->sets[set].layout = panvk_descriptor_set_layout_ref(set_layout);
p_atomic_inc(&set_layout->refcount);
layout->sets[set].sampler_offset = sampler_idx;
layout->sets[set].tex_offset = tex_idx;
layout->sets[set].ubo_offset = ubo_idx;
@@ -357,10 +366,22 @@ panvk_CreatePipelineLayout(VkDevice _device,
_mesa_sha1_final(&ctx, layout->sha1);
p_atomic_set(&layout->refcount, 1);
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
return VK_SUCCESS;
}
void
panvk_pipeline_layout_destroy(struct panvk_device *device,
struct panvk_pipeline_layout *layout)
{
for (unsigned i = 0; i < layout->num_sets; i++)
panvk_descriptor_set_layout_unref(device, layout->sets[i].layout);
vk_object_free(&device->vk, NULL, layout);
}
void
panvk_DestroyPipelineLayout(VkDevice _device,
VkPipelineLayout _pipelineLayout,
@@ -372,7 +393,7 @@ panvk_DestroyPipelineLayout(VkDevice _device,
if (!pipeline_layout)
return;
vk_object_free(&device->vk, pAllocator, pipeline_layout);
panvk_pipeline_layout_unref(device, pipeline_layout);
}
VkResult

View File

@@ -380,6 +380,7 @@ struct panvk_descriptor_set_binding_layout {
struct panvk_descriptor_set_layout {
struct vk_object_base base;
int32_t refcount;
/* The create flags for this descriptor set layout */
VkDescriptorSetLayoutCreateFlags flags;
@@ -403,8 +404,30 @@ struct panvk_descriptor_set_layout {
struct panvk_descriptor_set_binding_layout bindings[0];
};
void
panvk_descriptor_set_layout_destroy(struct panvk_device *dev,
struct panvk_descriptor_set_layout *layout);
static inline void
panvk_descriptor_set_layout_unref(struct panvk_device *dev,
struct panvk_descriptor_set_layout *layout)
{
if (layout && p_atomic_dec_zero(&layout->refcount))
panvk_descriptor_set_layout_destroy(dev, layout);
}
static inline struct panvk_descriptor_set_layout *
panvk_descriptor_set_layout_ref(struct panvk_descriptor_set_layout *layout)
{
if (layout)
p_atomic_inc(&layout->refcount);
return layout;
}
struct panvk_pipeline_layout {
struct vk_object_base base;
int32_t refcount;
unsigned char sha1[20];
unsigned num_samplers;
@@ -433,6 +456,27 @@ struct panvk_pipeline_layout {
} sets[MAX_SETS];
};
void
panvk_pipeline_layout_destroy(struct panvk_device *dev,
struct panvk_pipeline_layout *layout);
static inline void
panvk_pipeline_layout_unref(struct panvk_device *dev,
struct panvk_pipeline_layout *layout)
{
if (layout && p_atomic_dec_zero(&layout->refcount))
panvk_pipeline_layout_destroy(dev, layout);
}
static inline struct panvk_pipeline_layout *
panvk_pipeline_layout_ref(struct panvk_pipeline_layout *layout)
{
if (layout)
p_atomic_inc(&layout->refcount);
return layout;
}
struct panvk_desc_pool_counters {
unsigned samplers;
unsigned combined_image_samplers;