vulkan: Add a vk_command_buffer_ops struct

This is the standard pattern in the kernel for providing vfunc tables
for C objects.  We're using it in the pipeline cache code but we're
about to start adding more stuff and so it really helps if we have it
for command buffers as well.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18324>
This commit is contained in:
Jason Ekstrand 2022-08-30 12:41:48 -05:00 committed by Marge Bot
parent 5c143b132a
commit 44ab076fea
11 changed files with 52 additions and 26 deletions

View File

@ -355,7 +355,7 @@ radv_create_cmd_buffer(struct radv_device *device, struct radv_cmd_pool *pool,
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result =
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, level);
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL, level);
if (result != VK_SUCCESS) {
vk_free(&cmd_buffer->pool->vk.alloc, cmd_buffer);
return result;
@ -4693,7 +4693,7 @@ radv_AllocateCommandBuffers(VkDevice _device, const VkCommandBufferAllocateInfo
result = radv_reset_cmd_buffer(cmd_buffer);
vk_command_buffer_finish(&cmd_buffer->vk);
VkResult init_result =
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, pAllocateInfo->level);
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL, pAllocateInfo->level);
if (init_result != VK_SUCCESS)
result = init_result;

View File

@ -76,6 +76,10 @@ cmd_buffer_init(struct v3dv_cmd_buffer *cmd_buffer,
static void cmd_buffer_destroy(struct vk_command_buffer *cmd_buffer);
static const struct vk_command_buffer_ops cmd_buffer_ops = {
.destroy = cmd_buffer_destroy,
};
static VkResult
cmd_buffer_create(struct v3dv_device *device,
struct vk_command_pool *pool,
@ -91,13 +95,13 @@ cmd_buffer_create(struct v3dv_device *device,
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result;
result = vk_command_buffer_init(pool, &cmd_buffer->vk, level);
result = vk_command_buffer_init(pool, &cmd_buffer->vk,
&cmd_buffer_ops, level);
if (result != VK_SUCCESS) {
vk_free(&pool->alloc, cmd_buffer);
return result;
}
cmd_buffer->vk.destroy = cmd_buffer_destroy;
cmd_buffer_init(cmd_buffer, device);
*pCommandBuffer = v3dv_cmd_buffer_to_handle(cmd_buffer);

View File

@ -1588,7 +1588,8 @@ tu_create_cmd_buffer(struct tu_device *device,
if (cmd_buffer == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, level);
VkResult result = vk_command_buffer_init(&pool->vk, &cmd_buffer->vk,
NULL, level);
if (result != VK_SUCCESS) {
vk_free2(&device->vk.alloc, NULL, cmd_buffer);
return result;
@ -1713,7 +1714,8 @@ tu_AllocateCommandBuffers(VkDevice _device,
result = tu_reset_cmd_buffer(cmd_buffer);
vk_command_buffer_finish(&cmd_buffer->vk);
VkResult init_result =
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, pAllocateInfo->level);
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL,
pAllocateInfo->level);
if (init_result != VK_SUCCESS)
result = init_result;

View File

@ -38,7 +38,8 @@ static VkResult lvp_create_cmd_buffer(
if (cmd_buffer == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, level);
VkResult result = vk_command_buffer_init(&pool->vk, &cmd_buffer->vk,
NULL, level);
if (result != VK_SUCCESS) {
vk_free(&pool->vk.alloc, cmd_buffer);
return result;
@ -91,7 +92,7 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateCommandBuffers(
result = lvp_reset_cmd_buffer(cmd_buffer);
vk_command_buffer_finish(&cmd_buffer->vk);
VkResult init_result =
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk,
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL,
pAllocateInfo->level);
if (init_result != VK_SUCCESS)
result = init_result;

View File

@ -170,6 +170,10 @@ static void pvr_cmd_buffer_destroy(struct vk_command_buffer *vk_cmd_buffer)
vk_free(&cmd_buffer->vk.pool->alloc, cmd_buffer);
}
static const struct vk_command_buffer_ops cmd_buffer_ops = {
.destroy = pvr_cmd_buffer_destroy,
};
static VkResult pvr_cmd_buffer_create(struct pvr_device *device,
struct vk_command_pool *pool,
VkCommandBufferLevel level,
@ -185,13 +189,13 @@ static VkResult pvr_cmd_buffer_create(struct pvr_device *device,
if (!cmd_buffer)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
result = vk_command_buffer_init(pool, &cmd_buffer->vk, level);
result = vk_command_buffer_init(pool, &cmd_buffer->vk,
&cmd_buffer_ops, level);
if (result != VK_SUCCESS) {
vk_free(&pool->alloc, cmd_buffer);
return result;
}
cmd_buffer->vk.destroy = pvr_cmd_buffer_destroy;
cmd_buffer->device = device;
util_dynarray_init(&cmd_buffer->depth_bias_array, NULL);

View File

@ -84,6 +84,10 @@ anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
static void anv_cmd_buffer_destroy(struct vk_command_buffer *vk_cmd_buffer);
static const struct vk_command_buffer_ops cmd_buffer_ops = {
.destroy = anv_cmd_buffer_destroy,
};
static VkResult anv_create_cmd_buffer(
struct anv_device * device,
struct vk_command_pool * pool,
@ -98,11 +102,11 @@ static VkResult anv_create_cmd_buffer(
if (cmd_buffer == NULL)
return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
result = vk_command_buffer_init(pool, &cmd_buffer->vk, level);
result = vk_command_buffer_init(pool, &cmd_buffer->vk,
&cmd_buffer_ops, level);
if (result != VK_SUCCESS)
goto fail_alloc;
cmd_buffer->vk.destroy = anv_cmd_buffer_destroy;
cmd_buffer->vk.dynamic_graphics_state.ms.sample_locations =
&cmd_buffer->state.gfx.sample_locations;

View File

@ -335,6 +335,10 @@ dzn_cmd_buffer_dsv_key_equals_function(const void *a, const void *b)
return memcmp(a, b, sizeof(struct dzn_cmd_buffer_dsv_key)) == 0;
}
static const struct vk_command_buffer_ops cmd_buffer_ops = {
.destroy = dzn_cmd_buffer_destroy,
};
static VkResult
dzn_cmd_buffer_create(const VkCommandBufferAllocateInfo *info,
VkCommandBuffer *out)
@ -355,7 +359,7 @@ dzn_cmd_buffer_create(const VkCommandBufferAllocateInfo *info,
return vk_error(pool->base.device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result =
vk_command_buffer_init(pool, &cmdbuf->vk, info->level);
vk_command_buffer_init(pool, &cmdbuf->vk, &cmd_buffer_ops, info->level);
if (result != VK_SUCCESS) {
vk_free(&pool->alloc, cmdbuf);
return result;
@ -402,8 +406,6 @@ dzn_cmd_buffer_create(const VkCommandBufferAllocateInfo *info,
goto out;
}
cmdbuf->vk.destroy = dzn_cmd_buffer_destroy;
if (FAILED(ID3D12Device1_CreateCommandAllocator(device->dev, type,
&IID_ID3D12CommandAllocator,
(void **)&cmdbuf->cmdalloc))) {

View File

@ -1125,7 +1125,8 @@ panvk_create_cmdbuf(struct panvk_device *device,
if (!cmdbuf)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk, level);
VkResult result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk,
NULL, level);
if (result != VK_SUCCESS) {
vk_free(&device->vk.alloc, cmdbuf);
return result;
@ -1184,7 +1185,8 @@ panvk_per_arch(AllocateCommandBuffers)(VkDevice _device,
list_addtail(&cmdbuf->pool_link, &pool->active_cmd_buffers);
vk_command_buffer_finish(&cmdbuf->vk);
result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk, pAllocateInfo->level);
result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk, NULL,
pAllocateInfo->level);
} else {
result = panvk_create_cmdbuf(device, pool, pAllocateInfo->level, &cmdbuf);
}

View File

@ -30,6 +30,7 @@
VkResult
vk_command_buffer_init(struct vk_command_pool *pool,
struct vk_command_buffer *command_buffer,
const struct vk_command_buffer_ops *ops,
VkCommandBufferLevel level)
{
memset(command_buffer, 0, sizeof(*command_buffer));
@ -38,6 +39,7 @@ vk_command_buffer_init(struct vk_command_pool *pool,
command_buffer->pool = pool;
command_buffer->level = level;
command_buffer->ops = ops;
vk_dynamic_graphics_state_init(&command_buffer->dynamic_graphics_state);
command_buffer->record_result = VK_SUCCESS;
vk_cmd_queue_init(&command_buffer->cmd_queue, &pool->alloc);

View File

@ -59,6 +59,15 @@ struct vk_attachment_state {
VkClearValue clear_value;
};
struct vk_command_buffer_ops {
/** Destroys the command buffer
*
* Used by the common command pool implementation. This function MUST
* call `vk_command_buffer_finish()`.
*/
void (*destroy)(struct vk_command_buffer *);
};
struct vk_command_buffer {
struct vk_object_base base;
@ -67,6 +76,8 @@ struct vk_command_buffer {
/** VkCommandBufferAllocateInfo::level */
VkCommandBufferLevel level;
const struct vk_command_buffer_ops *ops;
struct vk_dynamic_graphics_state dynamic_graphics_state;
/** Command buffer recording error state. */
@ -75,13 +86,6 @@ struct vk_command_buffer {
/** Link in vk_command_pool::command_buffers if pool != NULL */
struct list_head pool_link;
/** Destroys the command buffer
*
* Used by the common command pool implementation. This function MUST
* call vk_command_buffer_finish().
*/
void (*destroy)(struct vk_command_buffer *);
/** Command list for emulated secondary command buffers */
struct vk_cmd_queue cmd_queue;
@ -143,6 +147,7 @@ VK_DEFINE_HANDLE_CASTS(vk_command_buffer, base, VkCommandBuffer,
VkResult MUST_CHECK
vk_command_buffer_init(struct vk_command_pool *pool,
struct vk_command_buffer *command_buffer,
const struct vk_command_buffer_ops *ops,
VkCommandBufferLevel level);
void

View File

@ -53,7 +53,7 @@ vk_command_pool_finish(struct vk_command_pool *pool)
{
list_for_each_entry_safe(struct vk_command_buffer, cmd_buffer,
&pool->command_buffers, pool_link) {
cmd_buffer->destroy(cmd_buffer);
cmd_buffer->ops->destroy(cmd_buffer);
}
assert(list_is_empty(&pool->command_buffers));
@ -143,7 +143,7 @@ vk_common_FreeCommandBuffers(VkDevice device,
if (cmd_buffer == NULL)
continue;
cmd_buffer->destroy(cmd_buffer);
cmd_buffer->ops->destroy(cmd_buffer);
}
}