anv: add new command buffer space allocation

To be used for acceleration structure building.

v2: fix missing u_vector_finish
    Free all BOs

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jianxun Zhang <jianxun.zhang@linux.intel.com>
Acked-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16970>
This commit is contained in:
Lionel Landwerlin 2022-02-17 14:22:57 +02:00 committed by Marge Bot
parent 6c76ceb613
commit 49976b23e9
3 changed files with 116 additions and 0 deletions

View file

@ -691,6 +691,63 @@ anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
size, alignment);
}
/** Allocate space associated with a command buffer
*
* Some commands like vkCmdBuildAccelerationStructuresKHR() can end up needing
* large amount of temporary buffers. This function is here to deal with those
* potentially larger allocations, using a side BO if needed.
*
*/
struct anv_cmd_alloc
anv_cmd_buffer_alloc_space(struct anv_cmd_buffer *cmd_buffer,
size_t size, uint32_t alignment)
{
/* Below 16k, source memory from dynamic state, otherwise allocate a BO. */
if (size < 16 * 1024) {
struct anv_state state =
anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
size, alignment);
return (struct anv_cmd_alloc) {
.address = (struct anv_address) {
.bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
.offset = state.offset,
},
.map = state.map,
.size = size,
};
}
assert(alignment <= 4096);
struct anv_bo *bo = NULL;
VkResult result =
anv_device_alloc_bo(cmd_buffer->device,
"cmd-buffer-space",
align_u32(size, 4096),
ANV_BO_ALLOC_MAPPED,
0,
&bo);
if (result != VK_SUCCESS) {
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
return ANV_EMPTY_ALLOC;
}
struct anv_bo **bo_entry =
u_vector_add(&cmd_buffer->dynamic_bos);
if (bo_entry == NULL) {
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
return ANV_EMPTY_ALLOC;
}
*bo_entry = bo;
return (struct anv_cmd_alloc) {
.address = (struct anv_address) { .bo = bo },
.map = bo->map,
.size = size,
};
}
VkResult
anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer)
{
@ -1322,6 +1379,14 @@ setup_execbuf_for_cmd_buffer(struct anv_execbuf *execbuf,
return result;
}
struct anv_bo **bo_entry;
u_vector_foreach(bo_entry, &cmd_buffer->dynamic_bos) {
result = anv_execbuf_add_bo(cmd_buffer->device, execbuf,
*bo_entry, NULL, 0);
if (result != VK_SUCCESS)
return result;
}
return VK_SUCCESS;
}

View file

@ -129,6 +129,11 @@ static VkResult anv_create_cmd_buffer(
anv_state_stream_init(&cmd_buffer->general_state_stream,
&device->general_state_pool, 16384);
int success = u_vector_init_pow2(&cmd_buffer->dynamic_bos, 8,
sizeof(struct anv_bo *));
if (!success)
goto fail_batch_bo;
cmd_buffer->self_mod_locations = NULL;
anv_cmd_state_init(cmd_buffer);
@ -141,6 +146,8 @@ static VkResult anv_create_cmd_buffer(
return VK_SUCCESS;
fail_batch_bo:
anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
fail_vk:
vk_command_buffer_finish(&cmd_buffer->vk);
fail_alloc:
@ -195,6 +202,12 @@ anv_cmd_buffer_destroy(struct vk_command_buffer *vk_cmd_buffer)
anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
anv_state_stream_finish(&cmd_buffer->general_state_stream);
while (u_vector_length(&cmd_buffer->dynamic_bos) > 0) {
struct anv_bo **bo = u_vector_remove(&cmd_buffer->dynamic_bos);
anv_device_release_bo(cmd_buffer->device, *bo);
}
u_vector_finish(&cmd_buffer->dynamic_bos);
anv_cmd_state_finish(cmd_buffer);
vk_free(&cmd_buffer->vk.pool->alloc, cmd_buffer->self_mod_locations);
@ -225,6 +238,11 @@ anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
anv_state_stream_init(&cmd_buffer->general_state_stream,
&cmd_buffer->device->general_state_pool, 16384);
while (u_vector_length(&cmd_buffer->dynamic_bos) > 0) {
struct anv_bo **bo = u_vector_remove(&cmd_buffer->dynamic_bos);
anv_device_release_bo(cmd_buffer->device, *bo);
}
anv_measure_reset(cmd_buffer);
u_trace_fini(&cmd_buffer->trace);

View file

@ -2654,6 +2654,15 @@ struct anv_cmd_buffer {
*/
uint32_t total_batch_size;
/**
* A vector of anv_bo pointers for chunks of memory used by the command
* buffer that are too large to be allocated through dynamic_state_stream.
* This is the case for large enough acceleration structures.
*
* initialized by anv_cmd_buffer_init_batch_bo_chain()
*/
struct u_vector dynamic_bos;
/**
*
*/
@ -2709,6 +2718,30 @@ struct anv_state
anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
uint32_t size, uint32_t alignment);
/**
* A allocation tied to a command buffer.
*
* Don't use anv_cmd_alloc::address::map to write memory from userspace, use
* anv_cmd_alloc::map instead.
*/
struct anv_cmd_alloc {
struct anv_address address;
void *map;
size_t size;
};
#define ANV_EMPTY_ALLOC ((struct anv_cmd_alloc) { .map = NULL, .size = 0 })
static inline bool
anv_cmd_alloc_is_empty(struct anv_cmd_alloc alloc)
{
return alloc.size == 0;
}
struct anv_cmd_alloc
anv_cmd_buffer_alloc_space(struct anv_cmd_buffer *cmd_buffer,
size_t size, uint32_t alignment);
VkResult
anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer);