anv: rename anv_utrace_flush_copy in anv_utrace_submit

We want to use this for submission of traces outside command buffers,
so it won't just execute copies of timestamp buffers.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22006>
This commit is contained in:
Lionel Landwerlin
2023-03-18 23:51:04 +02:00
parent becfbb2a19
commit b868f22b46
3 changed files with 91 additions and 77 deletions

View File

@@ -4212,7 +4212,7 @@ anv_device_init_generated_indirect_draws(struct anv_device *device);
void
anv_device_finish_generated_indirect_draws(struct anv_device *device);
struct anv_utrace_flush_copy {
struct anv_utrace_submit {
/* Needs to be the first field */
struct intel_ds_flush_data ds;
@@ -4241,7 +4241,7 @@ VkResult
anv_device_utrace_flush_cmd_buffers(struct anv_queue *queue,
uint32_t cmd_buffer_count,
struct anv_cmd_buffer **cmd_buffers,
struct anv_utrace_flush_copy **out_flush_data);
struct anv_utrace_submit **out_submit);
#ifdef HAVE_PERFETTO
void anv_perfetto_init(void);

View File

@@ -50,25 +50,25 @@ command_buffers_count_utraces(struct anv_device *device,
}
static void
anv_utrace_delete_flush_data(struct u_trace_context *utctx,
void *flush_data)
anv_utrace_delete_submit(struct u_trace_context *utctx, void *submit_data)
{
struct anv_device *device =
container_of(utctx, struct anv_device, ds.trace_context);
struct anv_utrace_flush_copy *flush = flush_data;
struct anv_utrace_submit *submit = submit_data;
intel_ds_flush_data_fini(&flush->ds);
intel_ds_flush_data_fini(&submit->ds);
if (flush->trace_bo) {
assert(flush->batch_bo);
anv_reloc_list_finish(&flush->relocs, &device->vk.alloc);
anv_bo_pool_free(&device->utrace_bo_pool, flush->batch_bo);
anv_bo_pool_free(&device->utrace_bo_pool, flush->trace_bo);
if (submit->trace_bo)
anv_bo_pool_free(&device->utrace_bo_pool, submit->trace_bo);
if (submit->batch_bo) {
anv_reloc_list_finish(&submit->relocs, &device->vk.alloc);
anv_bo_pool_free(&device->utrace_bo_pool, submit->batch_bo);
}
vk_sync_destroy(&device->vk, flush->sync);
vk_sync_destroy(&device->vk, submit->sync);
vk_free(&device->vk.alloc, flush);
vk_free(&device->vk.alloc, submit);
}
static void
@@ -80,13 +80,13 @@ anv_device_utrace_emit_copy_ts_buffer(struct u_trace_context *utctx,
{
struct anv_device *device =
container_of(utctx, struct anv_device, ds.trace_context);
struct anv_utrace_flush_copy *flush = cmdstream;
struct anv_utrace_submit *submit = cmdstream;
struct anv_address from_addr = (struct anv_address) {
.bo = ts_from, .offset = from_offset * sizeof(uint64_t) };
struct anv_address to_addr = (struct anv_address) {
.bo = ts_to, .offset = to_offset * sizeof(uint64_t) };
anv_genX(device->info, emit_so_memcpy)(&flush->memcpy_state,
anv_genX(device->info, emit_so_memcpy)(&submit->memcpy_state,
to_addr, from_addr, count * sizeof(uint64_t));
}
@@ -94,7 +94,7 @@ VkResult
anv_device_utrace_flush_cmd_buffers(struct anv_queue *queue,
uint32_t cmd_buffer_count,
struct anv_cmd_buffer **cmd_buffers,
struct anv_utrace_flush_copy **out_flush_data)
struct anv_utrace_submit **out_submit)
{
struct anv_device *device = queue->device;
uint32_t utrace_copies = 0;
@@ -103,95 +103,96 @@ anv_device_utrace_flush_cmd_buffers(struct anv_queue *queue,
cmd_buffers,
&utrace_copies);
if (!utraces) {
*out_flush_data = NULL;
*out_submit = NULL;
return VK_SUCCESS;
}
VkResult result;
struct anv_utrace_flush_copy *flush =
vk_zalloc(&device->vk.alloc, sizeof(struct anv_utrace_flush_copy),
struct anv_utrace_submit *submit =
vk_zalloc(&device->vk.alloc, sizeof(struct anv_utrace_submit),
8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!flush)
if (!submit)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
intel_ds_flush_data_init(&flush->ds, &queue->ds, queue->ds.submission_id);
intel_ds_flush_data_init(&submit->ds, &queue->ds, queue->ds.submission_id);
result = vk_sync_create(&device->vk, &device->physical->sync_syncobj_type,
0, 0, &flush->sync);
0, 0, &submit->sync);
if (result != VK_SUCCESS)
goto error_sync;
if (utrace_copies > 0) {
result = anv_bo_pool_alloc(&device->utrace_bo_pool,
utrace_copies * 4096,
&flush->trace_bo);
&submit->trace_bo);
if (result != VK_SUCCESS)
goto error_trace_buf;
result = anv_bo_pool_alloc(&device->utrace_bo_pool,
/* 128 dwords of setup + 64 dwords per copy */
align(512 + 64 * utrace_copies, 4096),
&flush->batch_bo);
&submit->batch_bo);
if (result != VK_SUCCESS)
goto error_batch_buf;
result = anv_reloc_list_init(&flush->relocs, &device->vk.alloc);
result = anv_reloc_list_init(&submit->relocs, &device->vk.alloc);
if (result != VK_SUCCESS)
goto error_reloc_list;
flush->batch.alloc = &device->vk.alloc;
flush->batch.relocs = &flush->relocs;
anv_batch_set_storage(&flush->batch,
(struct anv_address) { .bo = flush->batch_bo, },
flush->batch_bo->map, flush->batch_bo->size);
submit->batch.alloc = &device->vk.alloc;
submit->batch.relocs = &submit->relocs;
anv_batch_set_storage(&submit->batch,
(struct anv_address) { .bo = submit->batch_bo, },
submit->batch_bo->map, submit->batch_bo->size);
/* Emit the copies */
anv_genX(device->info, emit_so_memcpy_init)(&flush->memcpy_state,
device,
&flush->batch);
anv_genX(device->info, emit_so_memcpy_init)(&submit->memcpy_state,
device,
&submit->batch);
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
if (cmd_buffers[i]->usage_flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) {
u_trace_flush(&cmd_buffers[i]->trace, flush, false);
u_trace_flush(&cmd_buffers[i]->trace, submit, false);
} else {
u_trace_clone_append(u_trace_begin_iterator(&cmd_buffers[i]->trace),
u_trace_end_iterator(&cmd_buffers[i]->trace),
&flush->ds.trace,
flush,
&submit->ds.trace,
submit,
anv_device_utrace_emit_copy_ts_buffer);
}
}
anv_genX(device->info, emit_so_memcpy_fini)(&flush->memcpy_state);
anv_genX(device->info, emit_so_memcpy_end)(&flush->memcpy_state);
anv_genX(device->info, emit_so_memcpy_fini)(&submit->memcpy_state);
anv_genX(device->info, emit_so_memcpy_end)(&submit->memcpy_state);
u_trace_flush(&flush->ds.trace, flush, true);
u_trace_flush(&submit->ds.trace, submit, true);
if (flush->batch.status != VK_SUCCESS) {
result = flush->batch.status;
if (submit->batch.status != VK_SUCCESS) {
result = submit->batch.status;
goto error_batch;
}
} else {
for (uint32_t i = 0; i < cmd_buffer_count; i++) {
assert(cmd_buffers[i]->usage_flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
u_trace_flush(&cmd_buffers[i]->trace, flush, i == (cmd_buffer_count - 1));
u_trace_flush(&cmd_buffers[i]->trace, submit, i == (cmd_buffer_count - 1));
}
}
flush->queue = queue;
submit->queue = queue;
*out_flush_data = flush;
*out_submit = submit;
return VK_SUCCESS;
error_batch:
anv_reloc_list_finish(&flush->relocs, &device->vk.alloc);
anv_reloc_list_finish(&submit->relocs, &device->vk.alloc);
error_reloc_list:
anv_bo_pool_free(&device->utrace_bo_pool, flush->batch_bo);
anv_bo_pool_free(&device->utrace_bo_pool, submit->batch_bo);
error_batch_buf:
anv_bo_pool_free(&device->utrace_bo_pool, flush->trace_bo);
anv_bo_pool_free(&device->utrace_bo_pool, submit->trace_bo);
error_trace_buf:
vk_sync_destroy(&device->vk, flush->sync);
vk_sync_destroy(&device->vk, submit->sync);
error_sync:
vk_free(&device->vk.alloc, flush);
intel_ds_flush_data_fini(&submit->ds);
vk_free(&device->vk.alloc, submit);
return result;
}
@@ -226,15 +227,17 @@ anv_utrace_record_ts(struct u_trace *ut, void *cs,
void *timestamps, unsigned idx,
bool end_of_pipe)
{
struct anv_cmd_buffer *cmd_buffer =
container_of(ut, struct anv_cmd_buffer, trace);
struct anv_device *device = cmd_buffer->device;
struct anv_device *device =
container_of(ut->utctx, struct anv_device, ds.trace_context);
struct anv_batch *batch =
cs != NULL ? cs :
&container_of(ut, struct anv_cmd_buffer, trace)->batch;
struct anv_bo *bo = timestamps;
enum anv_timestamp_capture_type capture_type =
(end_of_pipe) ? ANV_TIMESTAMP_CAPTURE_END_OF_PIPE
: ANV_TIMESTAMP_CAPTURE_TOP_OF_PIPE;
device->physical->cmd_emit_timestamp(&cmd_buffer->batch, device,
device->physical->cmd_emit_timestamp(batch, device,
(struct anv_address) {
.bo = bo,
.offset = idx * sizeof(uint64_t) },
@@ -248,13 +251,13 @@ anv_utrace_read_ts(struct u_trace_context *utctx,
struct anv_device *device =
container_of(utctx, struct anv_device, ds.trace_context);
struct anv_bo *bo = timestamps;
struct anv_utrace_flush_copy *flush = flush_data;
struct anv_utrace_submit *submit = flush_data;
/* Only need to stall on results for the first entry: */
if (idx == 0) {
UNUSED VkResult result =
vk_sync_wait(&device->vk,
flush->sync,
submit->sync,
0,
VK_SYNC_WAIT_COMPLETE,
os_time_get_absolute_timeout(OS_TIMEOUT_INFINITE));
@@ -283,7 +286,7 @@ anv_device_utrace_init(struct anv_device *device)
anv_utrace_destroy_ts_buffer,
anv_utrace_record_ts,
anv_utrace_read_ts,
anv_utrace_delete_flush_data);
anv_utrace_delete_submit);
for (uint32_t q = 0; q < device->queue_count; q++) {
struct anv_queue *queue = &device->queues[q];

View File

@@ -460,46 +460,56 @@ setup_empty_execbuf(struct anv_execbuf *execbuf, struct anv_queue *queue)
static VkResult
setup_utrace_execbuf(struct anv_execbuf *execbuf, struct anv_queue *queue,
struct anv_utrace_flush_copy *flush)
struct anv_utrace_submit *submit)
{
struct anv_device *device = queue->device;
/* Always add the workaround BO as it includes a driver identifier for the
* error_state.
*/
VkResult result = anv_execbuf_add_bo(device, execbuf,
flush->batch_bo,
&flush->relocs, 0);
device->workaround_bo,
NULL, 0);
if (result != VK_SUCCESS)
return result;
result = anv_execbuf_add_sync(device, execbuf, flush->sync,
result = anv_execbuf_add_bo(device, execbuf,
submit->batch_bo,
&submit->relocs, 0);
if (result != VK_SUCCESS)
return result;
result = anv_execbuf_add_sync(device, execbuf, submit->sync,
true /* is_signal */, 0 /* value */);
if (result != VK_SUCCESS)
return result;
if (flush->batch_bo->exec_obj_index != execbuf->bo_count - 1) {
uint32_t idx = flush->batch_bo->exec_obj_index;
if (submit->batch_bo->exec_obj_index != execbuf->bo_count - 1) {
uint32_t idx = submit->batch_bo->exec_obj_index;
uint32_t last_idx = execbuf->bo_count - 1;
struct drm_i915_gem_exec_object2 tmp_obj = execbuf->objects[idx];
assert(execbuf->bos[idx] == flush->batch_bo);
assert(execbuf->bos[idx] == submit->batch_bo);
execbuf->objects[idx] = execbuf->objects[last_idx];
execbuf->bos[idx] = execbuf->bos[last_idx];
execbuf->bos[idx]->exec_obj_index = idx;
execbuf->objects[last_idx] = tmp_obj;
execbuf->bos[last_idx] = flush->batch_bo;
flush->batch_bo->exec_obj_index = last_idx;
execbuf->bos[last_idx] = submit->batch_bo;
submit->batch_bo->exec_obj_index = last_idx;
}
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
if (device->physical->memory.need_clflush)
intel_flush_range(flush->batch_bo->map, flush->batch_bo->size);
intel_flush_range(submit->batch_bo->map, submit->batch_bo->size);
#endif
execbuf->execbuf = (struct drm_i915_gem_execbuffer2) {
.buffers_ptr = (uintptr_t) execbuf->objects,
.buffer_count = execbuf->bo_count,
.batch_start_offset = 0,
.batch_len = flush->batch.next - flush->batch.start,
.batch_len = submit->batch.next - submit->batch.start,
.flags = I915_EXEC_NO_RELOC |
I915_EXEC_HANDLE_LUT |
I915_EXEC_FENCE_ARRAY |
@@ -525,9 +535,9 @@ anv_gem_execbuffer(struct anv_device *device,
static VkResult
anv_queue_exec_utrace_locked(struct anv_queue *queue,
struct anv_utrace_flush_copy *flush)
struct anv_utrace_submit *submit)
{
assert(flush->batch_bo);
assert(submit->batch_bo);
struct anv_device *device = queue->device;
struct anv_execbuf execbuf = {
@@ -535,7 +545,7 @@ anv_queue_exec_utrace_locked(struct anv_queue *queue,
.alloc_scope = VK_SYSTEM_ALLOCATION_SCOPE_DEVICE,
};
VkResult result = setup_utrace_execbuf(&execbuf, queue, flush);
VkResult result = setup_utrace_execbuf(&execbuf, queue, submit);
if (result != VK_SUCCESS)
goto error;
@@ -589,7 +599,7 @@ i915_queue_exec_locked(struct anv_queue *queue,
uint32_t perf_query_pass)
{
struct anv_device *device = queue->device;
struct anv_utrace_flush_copy *utrace_flush_data = NULL;
struct anv_utrace_submit *utrace_submit = NULL;
struct anv_execbuf execbuf = {
.alloc = &queue->device->vk.alloc,
.alloc_scope = VK_SYSTEM_ALLOCATION_SCOPE_DEVICE,
@@ -601,19 +611,20 @@ i915_queue_exec_locked(struct anv_queue *queue,
anv_device_utrace_flush_cmd_buffers(queue,
cmd_buffer_count,
cmd_buffers,
&utrace_flush_data);
&utrace_submit);
if (result != VK_SUCCESS)
goto error;
if (utrace_flush_data && !utrace_flush_data->batch_bo) {
if (utrace_submit && !utrace_submit->batch_bo) {
result = anv_execbuf_add_sync(device, &execbuf,
utrace_flush_data->sync,
utrace_submit->sync,
true /* is_signal */,
0);
if (result != VK_SUCCESS)
goto error;
utrace_flush_data = NULL;
/* When The utrace submission doesn't have its own batch buffer*/
utrace_submit = NULL;
}
/* Always add the workaround BO as it includes a driver identifier for the
@@ -743,8 +754,8 @@ i915_queue_exec_locked(struct anv_queue *queue,
error:
anv_execbuf_finish(&execbuf);
if (result == VK_SUCCESS && utrace_flush_data)
result = anv_queue_exec_utrace_locked(queue, utrace_flush_data);
if (result == VK_SUCCESS && utrace_submit)
result = anv_queue_exec_utrace_locked(queue, utrace_submit);
return result;
}