mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 19:50:11 +01:00
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:
parent
df92f56d8d
commit
18fced0226
2 changed files with 70 additions and 5 deletions
|
|
@ -71,7 +71,7 @@ panvk_CreateDescriptorSetLayout(VkDevice _device,
|
||||||
(sizeof(struct panvk_descriptor_set_binding_layout) *
|
(sizeof(struct panvk_descriptor_set_binding_layout) *
|
||||||
num_bindings) +
|
num_bindings) +
|
||||||
(sizeof(struct panvk_sampler *) * num_immutable_samplers);
|
(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);
|
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
|
||||||
if (!set_layout) {
|
if (!set_layout) {
|
||||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
@ -165,6 +165,7 @@ panvk_CreateDescriptorSetLayout(VkDevice _device,
|
||||||
set_layout->num_ssbos = ssbo_idx;
|
set_layout->num_ssbos = ssbo_idx;
|
||||||
set_layout->num_dyn_ssbos = dyn_ssbo_idx;
|
set_layout->num_dyn_ssbos = dyn_ssbo_idx;
|
||||||
set_layout->num_imgs = img_idx;
|
set_layout->num_imgs = img_idx;
|
||||||
|
p_atomic_set(&set_layout->refcount, 1);
|
||||||
|
|
||||||
free(bindings);
|
free(bindings);
|
||||||
*pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout);
|
*pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout);
|
||||||
|
|
@ -175,6 +176,13 @@ err_free_bindings:
|
||||||
return vk_error(device, result);
|
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
|
void
|
||||||
panvk_DestroyDescriptorSetLayout(VkDevice _device,
|
panvk_DestroyDescriptorSetLayout(VkDevice _device,
|
||||||
VkDescriptorSetLayout _set_layout,
|
VkDescriptorSetLayout _set_layout,
|
||||||
|
|
@ -186,7 +194,7 @@ panvk_DestroyDescriptorSetLayout(VkDevice _device,
|
||||||
if (!set_layout)
|
if (!set_layout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vk_object_free(&device->vk, pAllocator, set_layout);
|
panvk_descriptor_set_layout_unref(device, set_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: make sure those values are correct */
|
/* FIXME: make sure those values are correct */
|
||||||
|
|
@ -281,7 +289,7 @@ panvk_CreatePipelineLayout(VkDevice _device,
|
||||||
struct panvk_pipeline_layout *layout;
|
struct panvk_pipeline_layout *layout;
|
||||||
struct mesa_sha1 ctx;
|
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);
|
VK_OBJECT_TYPE_PIPELINE_LAYOUT);
|
||||||
if (layout == NULL)
|
if (layout == NULL)
|
||||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
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++) {
|
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
|
||||||
VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout,
|
VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout,
|
||||||
pCreateInfo->pSetLayouts[set]);
|
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].sampler_offset = sampler_idx;
|
||||||
layout->sets[set].tex_offset = tex_idx;
|
layout->sets[set].tex_offset = tex_idx;
|
||||||
layout->sets[set].ubo_offset = ubo_idx;
|
layout->sets[set].ubo_offset = ubo_idx;
|
||||||
|
|
@ -357,10 +366,22 @@ panvk_CreatePipelineLayout(VkDevice _device,
|
||||||
|
|
||||||
_mesa_sha1_final(&ctx, layout->sha1);
|
_mesa_sha1_final(&ctx, layout->sha1);
|
||||||
|
|
||||||
|
p_atomic_set(&layout->refcount, 1);
|
||||||
|
|
||||||
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
|
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
|
||||||
return VK_SUCCESS;
|
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
|
void
|
||||||
panvk_DestroyPipelineLayout(VkDevice _device,
|
panvk_DestroyPipelineLayout(VkDevice _device,
|
||||||
VkPipelineLayout _pipelineLayout,
|
VkPipelineLayout _pipelineLayout,
|
||||||
|
|
@ -372,7 +393,7 @@ panvk_DestroyPipelineLayout(VkDevice _device,
|
||||||
if (!pipeline_layout)
|
if (!pipeline_layout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vk_object_free(&device->vk, pAllocator, pipeline_layout);
|
panvk_pipeline_layout_unref(device, pipeline_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,7 @@ struct panvk_descriptor_set_binding_layout {
|
||||||
|
|
||||||
struct panvk_descriptor_set_layout {
|
struct panvk_descriptor_set_layout {
|
||||||
struct vk_object_base base;
|
struct vk_object_base base;
|
||||||
|
int32_t refcount;
|
||||||
|
|
||||||
/* The create flags for this descriptor set layout */
|
/* The create flags for this descriptor set layout */
|
||||||
VkDescriptorSetLayoutCreateFlags flags;
|
VkDescriptorSetLayoutCreateFlags flags;
|
||||||
|
|
@ -403,8 +404,30 @@ struct panvk_descriptor_set_layout {
|
||||||
struct panvk_descriptor_set_binding_layout bindings[0];
|
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 panvk_pipeline_layout {
|
||||||
struct vk_object_base base;
|
struct vk_object_base base;
|
||||||
|
int32_t refcount;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
|
|
||||||
unsigned num_samplers;
|
unsigned num_samplers;
|
||||||
|
|
@ -433,6 +456,27 @@ struct panvk_pipeline_layout {
|
||||||
} sets[MAX_SETS];
|
} 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 {
|
struct panvk_desc_pool_counters {
|
||||||
unsigned samplers;
|
unsigned samplers;
|
||||||
unsigned combined_image_samplers;
|
unsigned combined_image_samplers;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue