anv: Add an anv_execbuf helper struct
This commit adds a little helper struct for storing everything we use to build an execbuf2 call. Since the add_bo function really has nothing to do with a command buffer, it makes sense to break it out a bit. This also reduces some of the churn in the next commit. Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com> Cc: "13.0" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
095c48a496
commit
0fe6829427
|
@ -648,6 +648,20 @@ anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer)
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
anv_execbuf_init(struct anv_execbuf *exec)
|
||||
{
|
||||
memset(exec, 0, sizeof(*exec));
|
||||
}
|
||||
|
||||
static void
|
||||
anv_execbuf_finish(struct anv_execbuf *exec,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
vk_free(alloc, exec->objects);
|
||||
vk_free(alloc, exec->bos);
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
|
@ -694,9 +708,7 @@ anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
|
|||
|
||||
anv_cmd_buffer_new_binding_table_block(cmd_buffer);
|
||||
|
||||
cmd_buffer->execbuf2.objects = NULL;
|
||||
cmd_buffer->execbuf2.bos = NULL;
|
||||
cmd_buffer->execbuf2.array_length = 0;
|
||||
anv_execbuf_init(&cmd_buffer->execbuf2);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
|
@ -730,8 +742,7 @@ anv_cmd_buffer_fini_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
|
|||
anv_batch_bo_destroy(bbo, cmd_buffer);
|
||||
}
|
||||
|
||||
vk_free(&cmd_buffer->pool->alloc, cmd_buffer->execbuf2.objects);
|
||||
vk_free(&cmd_buffer->pool->alloc, cmd_buffer->execbuf2.bos);
|
||||
anv_execbuf_finish(&cmd_buffer->execbuf2, &cmd_buffer->pool->alloc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -929,55 +940,57 @@ anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
|
|||
}
|
||||
|
||||
static VkResult
|
||||
anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_bo *bo,
|
||||
struct anv_reloc_list *relocs)
|
||||
anv_execbuf_add_bo(struct anv_execbuf *exec,
|
||||
struct anv_bo *bo,
|
||||
struct anv_reloc_list *relocs,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
struct drm_i915_gem_exec_object2 *obj = NULL;
|
||||
|
||||
if (bo->index < cmd_buffer->execbuf2.bo_count &&
|
||||
cmd_buffer->execbuf2.bos[bo->index] == bo)
|
||||
obj = &cmd_buffer->execbuf2.objects[bo->index];
|
||||
if (bo->index < exec->bo_count && exec->bos[bo->index] == bo)
|
||||
obj = &exec->objects[bo->index];
|
||||
|
||||
if (obj == NULL) {
|
||||
/* We've never seen this one before. Add it to the list and assign
|
||||
* an id that we can use later.
|
||||
*/
|
||||
if (cmd_buffer->execbuf2.bo_count >= cmd_buffer->execbuf2.array_length) {
|
||||
uint32_t new_len = cmd_buffer->execbuf2.objects ?
|
||||
cmd_buffer->execbuf2.array_length * 2 : 64;
|
||||
if (exec->bo_count >= exec->array_length) {
|
||||
uint32_t new_len = exec->objects ? exec->array_length * 2 : 64;
|
||||
|
||||
struct drm_i915_gem_exec_object2 *new_objects =
|
||||
vk_alloc(&cmd_buffer->pool->alloc, new_len * sizeof(*new_objects),
|
||||
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
vk_alloc(alloc, new_len * sizeof(*new_objects),
|
||||
8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (new_objects == NULL)
|
||||
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
struct anv_bo **new_bos =
|
||||
vk_alloc(&cmd_buffer->pool->alloc, new_len * sizeof(*new_bos),
|
||||
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
vk_alloc(alloc, new_len * sizeof(*new_bos),
|
||||
8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (new_bos == NULL) {
|
||||
vk_free(&cmd_buffer->pool->alloc, new_objects);
|
||||
vk_free(alloc, new_objects);
|
||||
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
if (cmd_buffer->execbuf2.objects) {
|
||||
memcpy(new_objects, cmd_buffer->execbuf2.objects,
|
||||
cmd_buffer->execbuf2.bo_count * sizeof(*new_objects));
|
||||
memcpy(new_bos, cmd_buffer->execbuf2.bos,
|
||||
cmd_buffer->execbuf2.bo_count * sizeof(*new_bos));
|
||||
if (exec->objects) {
|
||||
memcpy(new_objects, exec->objects,
|
||||
exec->bo_count * sizeof(*new_objects));
|
||||
memcpy(new_bos, exec->bos,
|
||||
exec->bo_count * sizeof(*new_bos));
|
||||
}
|
||||
|
||||
cmd_buffer->execbuf2.objects = new_objects;
|
||||
cmd_buffer->execbuf2.bos = new_bos;
|
||||
cmd_buffer->execbuf2.array_length = new_len;
|
||||
vk_free(alloc, exec->objects);
|
||||
vk_free(alloc, exec->bos);
|
||||
|
||||
exec->objects = new_objects;
|
||||
exec->bos = new_bos;
|
||||
exec->array_length = new_len;
|
||||
}
|
||||
|
||||
assert(cmd_buffer->execbuf2.bo_count < cmd_buffer->execbuf2.array_length);
|
||||
assert(exec->bo_count < exec->array_length);
|
||||
|
||||
bo->index = cmd_buffer->execbuf2.bo_count++;
|
||||
obj = &cmd_buffer->execbuf2.objects[bo->index];
|
||||
cmd_buffer->execbuf2.bos[bo->index] = bo;
|
||||
bo->index = exec->bo_count++;
|
||||
obj = &exec->objects[bo->index];
|
||||
exec->bos[bo->index] = bo;
|
||||
|
||||
obj->handle = bo->gem_handle;
|
||||
obj->relocation_count = 0;
|
||||
|
@ -1000,7 +1013,7 @@ anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
|
|||
for (size_t i = 0; i < relocs->num_relocs; i++) {
|
||||
/* A quick sanity check on relocations */
|
||||
assert(relocs->relocs[i].offset < bo->size);
|
||||
anv_cmd_buffer_add_bo(cmd_buffer, relocs->reloc_bos[i], NULL);
|
||||
anv_execbuf_add_bo(exec, relocs->reloc_bos[i], NULL, alloc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1117,9 @@ anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer)
|
|||
cmd_buffer->execbuf2.bo_count = 0;
|
||||
|
||||
adjust_relocations_from_state_pool(ss_pool, &cmd_buffer->surface_relocs);
|
||||
anv_cmd_buffer_add_bo(cmd_buffer, &ss_pool->bo, &cmd_buffer->surface_relocs);
|
||||
anv_execbuf_add_bo(&cmd_buffer->execbuf2, &ss_pool->bo,
|
||||
&cmd_buffer->surface_relocs,
|
||||
&cmd_buffer->pool->alloc);
|
||||
|
||||
/* First, we walk over all of the bos we've seen and add them and their
|
||||
* relocations to the validate list.
|
||||
|
@ -1114,7 +1129,8 @@ anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer)
|
|||
adjust_relocations_to_state_pool(ss_pool, &(*bbo)->bo, &(*bbo)->relocs,
|
||||
&(*bbo)->last_ss_pool_bo_offset);
|
||||
|
||||
anv_cmd_buffer_add_bo(cmd_buffer, &(*bbo)->bo, &(*bbo)->relocs);
|
||||
anv_execbuf_add_bo(&cmd_buffer->execbuf2, &(*bbo)->bo, &(*bbo)->relocs,
|
||||
&cmd_buffer->pool->alloc);
|
||||
}
|
||||
|
||||
struct anv_batch_bo *first_batch_bo =
|
||||
|
|
|
@ -1147,6 +1147,17 @@ enum anv_cmd_buffer_exec_mode {
|
|||
ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN,
|
||||
};
|
||||
|
||||
struct anv_execbuf {
|
||||
struct drm_i915_gem_execbuffer2 execbuf;
|
||||
|
||||
struct drm_i915_gem_exec_object2 * objects;
|
||||
uint32_t bo_count;
|
||||
struct anv_bo ** bos;
|
||||
|
||||
/* Allocated length of the 'objects' and 'bos' arrays */
|
||||
uint32_t array_length;
|
||||
};
|
||||
|
||||
struct anv_cmd_buffer {
|
||||
VK_LOADER_DATA _loader_data;
|
||||
|
||||
|
@ -1179,20 +1190,7 @@ struct anv_cmd_buffer {
|
|||
uint32_t bt_next;
|
||||
struct anv_reloc_list surface_relocs;
|
||||
|
||||
/* Information needed for execbuf
|
||||
*
|
||||
* These fields are generated by anv_cmd_buffer_prepare_execbuf().
|
||||
*/
|
||||
struct {
|
||||
struct drm_i915_gem_execbuffer2 execbuf;
|
||||
|
||||
struct drm_i915_gem_exec_object2 * objects;
|
||||
uint32_t bo_count;
|
||||
struct anv_bo ** bos;
|
||||
|
||||
/* Allocated length of the 'objects' and 'bos' arrays */
|
||||
uint32_t array_length;
|
||||
} execbuf2;
|
||||
struct anv_execbuf execbuf2;
|
||||
|
||||
/* Serial for tracking buffer completion */
|
||||
uint32_t serial;
|
||||
|
|
Loading…
Reference in New Issue