lavapipe: fix CmdPushDescriptorSetWithTemplateKHR with refcounting
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 22 Apr 2022 18:16:42 +0000 (14:16 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 10 May 2022 20:30:09 +0000 (20:30 +0000)
this is a cmdbuf function, which means it gets enqueued, which means
the template can't be destroyed until the cmdbuf has finished using it

cc: mesa-stable

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16137>

src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
src/gallium/frontends/lavapipe/lvp_descriptor_set.c
src/gallium/frontends/lavapipe/lvp_private.h

index d9da147..84f20f9 100644 (file)
@@ -266,6 +266,14 @@ VKAPI_ATTR void VKAPI_CALL lvp_TrimCommandPool(
    list_inithead(&pool->free_cmd_buffers);
 }
 
+static void
+lvp_free_CmdPushDescriptorSetWithTemplateKHR(struct vk_cmd_queue *queue, struct vk_cmd_queue_entry *cmd)
+{
+   struct lvp_device *device = cmd->driver_data;
+   LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, cmd->u.push_descriptor_set_with_template_khr.descriptor_update_template);
+   lvp_descriptor_template_templ_unref(device, templ);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdPushDescriptorSetWithTemplateKHR(
    VkCommandBuffer                             commandBuffer,
    VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
@@ -285,8 +293,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdPushDescriptorSetWithTemplateKHR(
    cmd->type = VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_KHR;
 
    list_addtail(&cmd->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
+   cmd->driver_free_cb = lvp_free_CmdPushDescriptorSetWithTemplateKHR;
+   cmd->driver_data = cmd_buffer->device;
 
    cmd->u.push_descriptor_set_with_template_khr.descriptor_update_template = descriptorUpdateTemplate;
+   lvp_descriptor_template_templ_ref(templ);
    cmd->u.push_descriptor_set_with_template_khr.layout = layout;
    cmd->u.push_descriptor_set_with_template_khr.set = set;
 
index b007e3e..4147ac3 100644 (file)
@@ -682,13 +682,14 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorUpdateTemplate(VkDevice _devi
 
    struct lvp_descriptor_update_template *templ;
 
-   templ = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   templ = vk_alloc(&device->vk.alloc, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (!templ)
       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
 
    vk_object_base_init(&device->vk, &templ->base,
                        VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
 
+   templ->ref_cnt = 1;
    templ->type = pCreateInfo->templateType;
    templ->bind_point = pCreateInfo->pipelineBindPoint;
    templ->set = pCreateInfo->set;
@@ -708,18 +709,23 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorUpdateTemplate(VkDevice _devi
    return VK_SUCCESS;
 }
 
+void
+lvp_descriptor_template_destroy(struct lvp_device *device, struct lvp_descriptor_update_template *templ)
+{
+   if (!templ)
+      return;
+
+   vk_object_base_finish(&templ->base);
+   vk_free(&device->vk.alloc, templ);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorUpdateTemplate(VkDevice _device,
                                          VkDescriptorUpdateTemplate descriptorUpdateTemplate,
                                          const VkAllocationCallbacks *pAllocator)
 {
    LVP_FROM_HANDLE(lvp_device, device, _device);
    LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, descriptorUpdateTemplate);
-
-   if (!templ)
-      return;
-
-   vk_object_base_finish(&templ->base);
-   vk_free2(&device->vk.alloc, pAllocator, templ);
+   lvp_descriptor_template_templ_unref(device, templ);
 }
 
 VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSetWithTemplate(VkDevice _device,
index 94e2ca8..2fae582 100644 (file)
@@ -380,6 +380,7 @@ struct lvp_descriptor_pool {
 
 struct lvp_descriptor_update_template {
    struct vk_object_base base;
+   unsigned ref_cnt;
    uint32_t entry_count;
    uint32_t set;
    VkDescriptorUpdateTemplateType type;
@@ -388,6 +389,27 @@ struct lvp_descriptor_update_template {
    VkDescriptorUpdateTemplateEntry entry[0];
 };
 
+static inline void
+lvp_descriptor_template_templ_ref(struct lvp_descriptor_update_template *templ)
+{
+   assert(templ && templ->ref_cnt >= 1);
+   p_atomic_inc(&templ->ref_cnt);
+}
+
+void
+lvp_descriptor_template_destroy(struct lvp_device *device, struct lvp_descriptor_update_template *templ);
+
+static inline void
+lvp_descriptor_template_templ_unref(struct lvp_device *device,
+                                    struct lvp_descriptor_update_template *templ)
+{
+   if (!templ)
+      return;
+   assert(templ->ref_cnt >= 1);
+   if (p_atomic_dec_zero(&templ->ref_cnt))
+      lvp_descriptor_template_destroy(device, templ);
+}
+
 VkResult
 lvp_descriptor_set_create(struct lvp_device *device,
                           struct lvp_descriptor_set_layout *layout,