}
void
+intel_ds_begin_queue_annotation(struct intel_ds_device *device,
+ uint64_t ts_ns,
+ const void *flush_data,
+ const struct trace_intel_begin_queue_annotation *payload)
+{
+ const struct intel_ds_flush_data *flush =
+ (const struct intel_ds_flush_data *) flush_data;
+ begin_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_QUEUE);
+}
+
+void
+intel_ds_end_queue_annotation(struct intel_ds_device *device,
+ uint64_t ts_ns,
+ const void *flush_data,
+ const struct trace_intel_end_queue_annotation *payload)
+{
+ const struct intel_ds_flush_data *flush =
+ (const struct intel_ds_flush_data *) flush_data;
+ end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_QUEUE,
+ flush->submission_id, payload->str, NULL, NULL);
+}
+
+void
intel_ds_begin_stall(struct intel_ds_device *device,
uint64_t ts_ns,
const void *flush_data,
tp_args=[Arg(type='uint32_t', var='frame', c_format='%u'),],
end_pipelined=False)
+ # Annotations for Queue(Begin|End)DebugUtilsLabelEXT
+ begin_end_tp('queue_annotation',
+ tp_args=[ArgStruct(type='unsigned', var='len'),
+ ArgStruct(type='const char *', var='str'),],
+ tp_struct=[Arg(type='uint8_t', name='dummy', var='0', c_format='%hhu'),
+ Arg(type='char', name='str', var='str', c_format='%s', length_arg='len + 1', copy_func='strncpy'),],
+ end_pipelined=False,
+ need_cs_param=True)
+
# Batch buffer tracepoints, only for Iris
begin_end_tp('batch',
tp_args=[Arg(type='uint8_t', var='name', c_format='%hhu'),],
struct anv_device;
struct anv_queue;
struct anv_query_pool;
+struct anv_utrace_submit;
struct anv_kmd_backend {
/*
const struct vk_sync_signal *signals,
struct anv_query_pool *perf_query_pool,
uint32_t perf_query_pass);
+ VkResult (*queue_exec_trace)(struct anv_queue *queue,
+ struct anv_utrace_submit *submit);
};
const struct anv_kmd_backend *anv_kmd_backend_get(enum intel_kmd_type type);
void
anv_device_finish_generated_indirect_draws(struct anv_device *device);
+/* This structure is used in 2 scenarios :
+ *
+ * - copy utrace timestamps from command buffer so that command buffer can
+ * be resubmitted multiple times without the recorded timestamps being
+ * overwritten before they're read back
+ *
+ * - emit trace points for queue debug tagging
+ * (vkQueueBeginDebugUtilsLabelEXT/vkQueueEndDebugUtilsLabelEXT)
+ */
struct anv_utrace_submit {
/* Needs to be the first field */
struct intel_ds_flush_data ds;
struct anv_batch batch;
struct anv_bo *batch_bo;
- /* Buffer of 64bits timestamps */
- struct anv_bo *trace_bo;
-
/* Syncobj to be signaled when the batch completes */
struct vk_sync *sync;
/* Queue on which all the recorded traces are submitted */
struct anv_queue *queue;
+ /* Buffer of 64bits timestamps (only used for timestamp copies) */
+ struct anv_bo *trace_bo;
+
+ /* Memcpy state tracking (only used for timestamp copies) */
struct anv_memcpy_state memcpy_state;
};
#include "anv_private.h"
#include "ds/intel_tracepoints.h"
+#include "genxml/gen8_pack.h"
#include "perf/intel_perf.h"
#include "vulkan/runtime/vk_common_entrypoints.h"
}
vk_common_CmdEndDebugUtilsLabelEXT(_commandBuffer);
- }
+}
+
+static void
+anv_queue_trace(struct anv_queue *queue, const VkDebugUtilsLabelEXT *label, bool begin)
+{
+ struct anv_device *device = queue->device;
+
+ VkResult result;
+ struct anv_utrace_submit *submit =
+ vk_zalloc(&device->vk.alloc, sizeof(struct anv_utrace_submit),
+ 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (!submit)
+ return;
+
+ submit->queue = queue;
+
+ 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, &submit->sync);
+ if (result != VK_SUCCESS)
+ goto error_trace;
+
+ result = anv_bo_pool_alloc(&device->utrace_bo_pool, 4096,
+ &submit->batch_bo);
+ if (result != VK_SUCCESS)
+ goto error_sync;
+
+ result = anv_reloc_list_init(&submit->relocs, &device->vk.alloc);
+ if (result != VK_SUCCESS)
+ goto error_batch_bo;
+
+ 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);
+
+ if (begin) {
+ trace_intel_begin_queue_annotation(&submit->ds.trace, &submit->batch);
+ } else {
+ trace_intel_end_queue_annotation(&submit->ds.trace,
+ &submit->batch,
+ strlen(label->pLabelName),
+ label->pLabelName);
+ }
+
+ anv_batch_emit(&submit->batch, GFX8_MI_BATCH_BUFFER_END, bbs);
+ anv_batch_emit(&submit->batch, GFX8_MI_NOOP, noop);
+
+ if (submit->batch.status != VK_SUCCESS) {
+ result = submit->batch.status;
+ goto error_reloc_list;
+ }
+
+ u_trace_flush(&submit->ds.trace, submit, true);
+
+ pthread_mutex_lock(&device->mutex);
+ device->kmd_backend->queue_exec_trace(queue, submit);
+ pthread_mutex_unlock(&device->mutex);
+
+ return;
+
+ error_reloc_list:
+ anv_reloc_list_finish(&submit->relocs, &device->vk.alloc);
+ error_batch_bo:
+ anv_bo_pool_free(&device->utrace_bo_pool, submit->batch_bo);
+ error_sync:
+ vk_sync_destroy(&device->vk, submit->sync);
+ error_trace:
+ intel_ds_flush_data_fini(&submit->ds);
+ vk_free(&device->vk.alloc, submit);
+}
+
+void
+anv_QueueBeginDebugUtilsLabelEXT(
+ VkQueue _queue,
+ const VkDebugUtilsLabelEXT *pLabelInfo)
+{
+ VK_FROM_HANDLE(anv_queue, queue, _queue);
+
+ vk_common_QueueBeginDebugUtilsLabelEXT(_queue, pLabelInfo);
+
+ anv_queue_trace(queue, pLabelInfo, true /* begin */);
+}
+
+void
+anv_QueueEndDebugUtilsLabelEXT(VkQueue _queue)
+{
+ VK_FROM_HANDLE(anv_queue, queue, _queue);
+
+ if (queue->vk.labels.size > 0) {
+ const VkDebugUtilsLabelEXT *label =
+ util_dynarray_top_ptr(&queue->vk.labels, VkDebugUtilsLabelEXT);
+ anv_queue_trace(queue, label, false /* begin */);
+
+ u_trace_context_process(&queue->device->ds.trace_context, true);
+ }
+
+ vk_common_QueueEndDebugUtilsLabelEXT(_queue);
+}
anv_execbuf_finish(&execbuf);
return result;
}
+
+VkResult
+i915_queue_exec_trace(struct anv_queue *queue,
+ struct anv_utrace_submit *submit)
+{
+ assert(submit->batch_bo);
+
+ return anv_queue_exec_utrace_locked(queue, submit);
+}
struct anv_bo;
struct anv_cmd_buffer;
struct anv_query_pool;
+struct anv_utrace_submit;
VkResult
+i915_queue_exec_trace(struct anv_queue *queue,
+ struct anv_utrace_submit *submit);
+VkResult
i915_execute_simple_batch(struct anv_queue *queue, struct anv_bo *batch_bo,
uint32_t batch_bo_size);
VkResult
.gem_vm_bind = i915_gem_vm_bind,
.gem_vm_unbind = i915_gem_vm_unbind,
.execute_simple_batch = i915_execute_simple_batch,
- .queue_exec_locked = i915_queue_exec_locked
+ .queue_exec_locked = i915_queue_exec_locked,
+ .queue_exec_trace = i915_queue_exec_trace,
};
return &i915_backend;
}