diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index aacf5542ce9..7192a0f0d06 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -122,6 +122,7 @@ cmd_buffer_init(struct v3dv_cmd_buffer *cmd_buffer, cmd_buffer->pool = pool; cmd_buffer->level = level; + list_inithead(&cmd_buffer->private_objs); list_inithead(&cmd_buffer->submit_jobs); assert(pool); @@ -190,6 +191,37 @@ v3dv_job_destroy(struct v3dv_job *job) vk_free(&job->device->alloc, job); } +void +v3dv_cmd_buffer_add_private_obj(struct v3dv_cmd_buffer *cmd_buffer, + void *obj, + v3dv_cmd_buffer_private_obj_destroy_cb destroy_cb) +{ + struct v3dv_cmd_buffer_private_obj *pobj = + vk_alloc(&cmd_buffer->device->alloc, sizeof(*pobj), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!pobj) { + cmd_buffer->state.oom = true; + return; + } + + pobj->obj = obj; + pobj->destroy_cb = destroy_cb; + + list_addtail(&pobj->list_link, &cmd_buffer->private_objs); +} + +static void +cmd_buffer_destroy_private_obj(struct v3dv_cmd_buffer *cmd_buffer, + struct v3dv_cmd_buffer_private_obj *pobj) +{ + assert(pobj && pobj->obj && pobj->destroy_cb); + pobj->destroy_cb(v3dv_device_to_handle(cmd_buffer->device), + pobj->obj, + &cmd_buffer->device->alloc); + list_del(&pobj->list_link); + vk_free(&cmd_buffer->device->alloc, pobj); +} + static void cmd_buffer_free_resources(struct v3dv_cmd_buffer *cmd_buffer) { @@ -213,6 +245,11 @@ cmd_buffer_free_resources(struct v3dv_cmd_buffer *cmd_buffer) if (cmd_buffer->push_constants_resource.bo) v3dv_bo_free(cmd_buffer->device, cmd_buffer->push_constants_resource.bo); + + list_for_each_entry_safe(struct v3dv_cmd_buffer_private_obj, pobj, + &cmd_buffer->private_objs, list_link) { + cmd_buffer_destroy_private_obj(cmd_buffer, pobj); + } } static void diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 7a0c0fae3d1..e94b4be54c7 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -851,6 +851,15 @@ VkResult v3dv_get_query_pool_results_cpu(struct v3dv_device *device, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (*v3dv_cmd_buffer_private_obj_destroy_cb)(VkDevice device, + void *pobj, + VkAllocationCallbacks *alloc); +struct v3dv_cmd_buffer_private_obj { + struct list_head list_link; + void *obj; + v3dv_cmd_buffer_private_obj_destroy_cb destroy_cb; +}; + struct v3dv_cmd_buffer { VK_LOADER_DATA _loader_data; @@ -869,6 +878,12 @@ struct v3dv_cmd_buffer { uint32_t push_constants_data[MAX_PUSH_CONSTANTS_SIZE / 4]; struct v3dv_resource push_constants_resource; + /* Collection of Vulkan objects created internally by the driver (typically + * during recording of meta operations) that are part of the command buffer + * and should be destroyed with it. + */ + struct list_head private_objs; /* v3dv_cmd_buffer_private_obj */ + /* List of jobs to submit to the kernel */ struct list_head submit_jobs; }; @@ -921,6 +936,10 @@ void v3dv_cmd_buffer_copy_query_results(struct v3dv_cmd_buffer *cmd_buffer, void v3dv_cmd_buffer_add_tfu_job(struct v3dv_cmd_buffer *cmd_buffer, struct drm_v3d_submit_tfu *tfu); +void v3dv_cmd_buffer_add_private_obj(struct v3dv_cmd_buffer *cmd_buffer, + void *obj, + v3dv_cmd_buffer_private_obj_destroy_cb destroy_cb); + struct v3dv_semaphore { /* A syncobject handle associated with this semaphore */ uint32_t sync;