Module: Mesa Branch: main Commit: 28b15fa9e7706da41c3b6bed3c640b4198359984 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=28b15fa9e7706da41c3b6bed3c640b4198359984
Author: Lionel Landwerlin <[email protected]> Date: Sun May 22 13:18:42 2022 +0300 anv: add support for command buffer tagging in traces Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Emma Anholt <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16655> --- src/intel/ds/intel_driver_ds.cc | 82 ++++++++++++++++++++++++++++++++++++--- src/intel/ds/intel_driver_ds.h | 17 +++++++- src/intel/ds/intel_tracepoints.py | 8 ++++ src/intel/vulkan/anv_utrace.c | 30 ++++++++++++++ 4 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/intel/ds/intel_driver_ds.cc b/src/intel/ds/intel_driver_ds.cc index 42e2b69e530..ca93d481d79 100644 --- a/src/intel/ds/intel_driver_ds.cc +++ b/src/intel/ds/intel_driver_ds.cc @@ -195,12 +195,15 @@ send_descriptors(IntelRenderpassDataSource::TraceContext &ctx, PERFETTO_LOG("Sending renderstage descriptors"); device->event_id = 0; + device->current_app_event_iid = device->start_app_event_iids; u_vector_foreach(queue, &device->queues) { for (uint32_t s = 0; s < ARRAY_SIZE(queue->stages); s++) { queue->stages[s].start_ns[0] = 0; } } + _mesa_hash_table_clear(device->app_events, NULL); + { auto packet = ctx.NewTracePacket(); @@ -271,13 +274,46 @@ begin_event(struct intel_ds_queue *queue, uint64_t ts_ns, return; } + if (level >= (ARRAY_SIZE(queue->stages[stage_id].start_ns) - 1)) + return; + queue->stages[stage_id].start_ns[level] = ts_ns; + queue->stages[stage_id].level++; +} + +static uint64_t +add_app_event(IntelRenderpassDataSource::TraceContext &tctx, + struct intel_ds_device *device, + const char *app_event) +{ + struct hash_entry *entry = + _mesa_hash_table_search(device->app_events, app_event); + if (entry) + return (uint64_t) entry->data; + + /* Allocate a new iid for the string */ + uint64_t iid = device->current_app_event_iid++; + _mesa_hash_table_insert(device->app_events, app_event, (void*)(uintptr_t)iid); + + /* Send the definition of iid/string to perfetto */ + { + auto packet = tctx.NewTracePacket(); + auto interned_data = packet->set_interned_data(); + + auto desc = interned_data->add_gpu_specifications(); + desc->set_iid(iid); + desc->set_name(app_event); + } + + return iid; } static void end_event(struct intel_ds_queue *queue, uint64_t ts_ns, enum intel_ds_queue_stage stage_id, - uint32_t submission_id, const void* payload = nullptr, + uint32_t submission_id, + const char *app_event, + const void* payload = nullptr, trace_payload_as_extra_func payload_as_extra = nullptr) { struct intel_ds_device *device = queue->device; @@ -310,6 +346,13 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns, uint64_t evt_id = device->event_id++; + /* If this is an application event, we might need to generate a new + * stage_iid if not already seen. Otherwise, it's a driver event and we + * have use the internal stage_iid. + */ + uint64_t stage_iid = app_event ? + add_app_event(tctx, queue->device, app_event) : stage->stage_iid; + auto packet = tctx.NewTracePacket(); packet->set_timestamp(start_ns); @@ -321,7 +364,7 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns, event->set_gpu_id(queue->device->gpu_id); event->set_hw_queue_iid(stage->queue_iid); - event->set_stage_iid(stage->stage_iid); + event->set_stage_iid(stage_iid); event->set_context(queue->device->iid); event->set_event_id(evt_id); event->set_duration(ts_ns - start_ns); @@ -403,7 +446,7 @@ extern "C" { const struct intel_ds_flush_data *flush = \ (const struct intel_ds_flush_data *) flush_data; \ end_event(flush->queue, ts_ns, stage, flush->submission_id, \ - payload, \ + NULL, payload, \ (trace_payload_as_extra_func) \ &trace_payload_as_extra_intel_end_##event_name); \ } \ @@ -430,6 +473,29 @@ CREATE_DUAL_EVENT_CALLBACK(compute, INTEL_DS_QUEUE_STAGE_COMPUTE) CREATE_DUAL_EVENT_CALLBACK(generate_draws, INTEL_DS_QUEUE_STAGE_GENERATE_DRAWS) CREATE_DUAL_EVENT_CALLBACK(trace_copy, INTEL_DS_QUEUE_STAGE_BLORP) +void +intel_ds_begin_cmd_buffer_annotation(struct intel_ds_device *device, + uint64_t ts_ns, + const void *flush_data, + const struct trace_intel_begin_cmd_buffer_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_CMD_BUFFER); +} + +void +intel_ds_end_cmd_buffer_annotation(struct intel_ds_device *device, + uint64_t ts_ns, + const void *flush_data, + const struct trace_intel_end_cmd_buffer_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_CMD_BUFFER, + flush->submission_id, payload->str, NULL, NULL); +} + void intel_ds_begin_stall(struct intel_ds_device *device, uint64_t ts_ns, @@ -450,7 +516,7 @@ intel_ds_end_stall(struct intel_ds_device *device, 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_STALL, - flush->submission_id, payload, + flush->submission_id, NULL, payload, (trace_payload_as_extra_func)custom_trace_payload_as_extra_end_stall); } @@ -510,10 +576,10 @@ intel_driver_ds_init_once(void) } static once_flag intel_driver_ds_once_flag = ONCE_FLAG_INIT; +static uint64_t iid = 1; static uint64_t get_iid() { - static uint64_t iid = 1; return iid++; } @@ -541,12 +607,18 @@ intel_ds_device_init(struct intel_ds_device *device, device->iid = get_iid(); device->api = api; u_vector_init(&device->queues, 4, sizeof(struct intel_ds_queue)); + + /* Reserve iids for the application generated events */ + device->start_app_event_iids = 1ull << 32; + device->app_events = + _mesa_hash_table_create(NULL, _mesa_hash_string, _mesa_key_string_equal); } void intel_ds_device_fini(struct intel_ds_device *device) { u_trace_context_fini(&device->trace_context); + _mesa_hash_table_destroy(device->app_events, NULL); u_vector_finish(&device->queues); } diff --git a/src/intel/ds/intel_driver_ds.h b/src/intel/ds/intel_driver_ds.h index 52c5a436d5c..004864d622c 100644 --- a/src/intel/ds/intel_driver_ds.h +++ b/src/intel/ds/intel_driver_ds.h @@ -103,9 +103,24 @@ struct intel_ds_device { /* Unique perfetto identifier for the context */ uint64_t iid; - /* Event ID generator */ + /* Event ID generator (manipulate only inside + * IntelRenderpassDataSource::Trace) + */ uint64_t event_id; + /* Start of unique IID for device generated events */ + uint64_t start_app_event_iids; + + /* Last app event iid (manipulate only inside + * IntelRenderpassDataSource::Trace) + */ + uint64_t current_app_event_iid; + + /* Hash table of application generated events (string -> iid) (manipulate + * only inside IntelRenderpassDataSource::Trace) + */ + struct hash_table *app_events; + struct u_trace_context trace_context; /* List of intel_ds_queue */ diff --git a/src/intel/ds/intel_tracepoints.py b/src/intel/ds/intel_tracepoints.py index 8811f6db87e..71f13e9b097 100644 --- a/src/intel/ds/intel_tracepoints.py +++ b/src/intel/ds/intel_tracepoints.py @@ -57,6 +57,14 @@ def define_tracepoints(args): tp_args=[Arg(type='uint8_t', var='level', c_format='%hhu'),], end_pipelined=False) + # Annotations for Cmd(Begin|End)DebugUtilsLabelEXT + begin_end_tp('cmd_buffer_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=True) + begin_end_tp('xfb', end_pipelined=False) diff --git a/src/intel/vulkan/anv_utrace.c b/src/intel/vulkan/anv_utrace.c index 1c2f0e4aca3..16728864f35 100644 --- a/src/intel/vulkan/anv_utrace.c +++ b/src/intel/vulkan/anv_utrace.c @@ -23,8 +23,11 @@ #include "anv_private.h" +#include "ds/intel_tracepoints.h" #include "perf/intel_perf.h" +#include "vulkan/runtime/vk_common_entrypoints.h" + static uint32_t command_buffers_count_utraces(struct anv_device *device, uint32_t cmd_buffer_count, @@ -332,3 +335,30 @@ anv_pipe_flush_bit_to_ds_stall_flag(enum anv_pipe_bits bits) return ret; } + +void anv_CmdBeginDebugUtilsLabelEXT( + VkCommandBuffer _commandBuffer, + const VkDebugUtilsLabelEXT *pLabelInfo) +{ + VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _commandBuffer); + + vk_common_CmdBeginDebugUtilsLabelEXT(_commandBuffer, pLabelInfo); + + trace_intel_begin_cmd_buffer_annotation(&cmd_buffer->trace); +} + +void anv_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer) +{ + VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _commandBuffer); + + if (cmd_buffer->vk.labels.size > 0) { + const VkDebugUtilsLabelEXT *label = + util_dynarray_top_ptr(&cmd_buffer->vk.labels, VkDebugUtilsLabelEXT); + + trace_intel_end_cmd_buffer_annotation(&cmd_buffer->trace, + strlen(label->pLabelName), + label->pLabelName); + } + + vk_common_CmdEndDebugUtilsLabelEXT(_commandBuffer); + }
