diff --git a/src/freedreno/vulkan/tu_cs.cc b/src/freedreno/vulkan/tu_cs.cc index af9c88cd1ad..47e1939d611 100644 --- a/src/freedreno/vulkan/tu_cs.cc +++ b/src/freedreno/vulkan/tu_cs.cc @@ -630,6 +630,15 @@ tu_cs_trace_end(struct u_trace_context *utctx, void *cs, const char *fmt, ...) va_end(args); } +void +tu_cs_trace_singular(struct u_trace_context *utctx, void *cs, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + tu_cs_emit_debug_magic_strv((struct tu_cs *) cs, CP_NOP_MESG, fmt, args); + va_end(args); +} + tu_crb tu_cs::crb(uint32_t nregs) { diff --git a/src/freedreno/vulkan/tu_cs.h b/src/freedreno/vulkan/tu_cs.h index 9ad80cc4b73..6a66de1caa3 100644 --- a/src/freedreno/vulkan/tu_cs.h +++ b/src/freedreno/vulkan/tu_cs.h @@ -450,6 +450,9 @@ tu_cs_trace_start(struct u_trace_context *utctx, __attribute__((format(printf, 3, 4))) void tu_cs_trace_end(struct u_trace_context *utctx, void *cs, const char *fmt, ...); +__attribute__((format(printf, 3, 4))) void +tu_cs_trace_singular(struct u_trace_context *utctx, void *cs, const char *fmt, ...); + struct tu_cs_patchable_state { uint32_t *nop_header; uint32_t dwords; diff --git a/src/freedreno/vulkan/tu_perfetto.cc b/src/freedreno/vulkan/tu_perfetto.cc index 1421a66b1e1..2d0eef9026f 100644 --- a/src/freedreno/vulkan/tu_perfetto.cc +++ b/src/freedreno/vulkan/tu_perfetto.cc @@ -38,6 +38,7 @@ static const struct { [ANNOTATIONS_QUEUE_ID] = {"Annotations", "Annotations Queue"}, [BR_HW_QUEUE_ID] = {"GPU Queue 0", "Default Adreno Hardware Queue"}, [BV_HW_QUEUE_ID] = {"GPU Queue 1", "Adreno Bin Visibility Queue"}, + [PERF_WARNINGS_QUEUE_ID] = {"Performance Warnings", "Performance Warnings Queue"}, }; static const struct { @@ -330,6 +331,23 @@ stage_end(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id, } uint32_t queue_id = BR_HW_QUEUE_ID; + + /* Warnings should last until the end of the corresponding stage. + * This is a roundabout way to achive that, since we don't track + * which stage warning corresponds to. + */ + if (stage_id != CLEAR_SYSMEM_STAGE_ID && + stage_id != CLEAR_GMEM_STAGE_ID && + stage_id != GENERIC_CLEAR_STAGE_ID && + stage_id != GMEM_LOAD_STAGE_ID && + stage_id != GMEM_STORE_STAGE_ID) { + while (dev->perfetto.sticky_warnings_stack.stage_depth > 0) { + struct tu_perfetto_stage *stage = + &dev->perfetto.sticky_warnings_stack.stages[dev->perfetto.sticky_warnings_stack.stage_depth - 1]; + stage_end(dev, ts_ns, (tu_stage_id) stage->stage_id, nullptr, flush_data); + } + } + switch (stage->stage_id) { case CMD_BUFFER_ANNOTATION_STAGE_ID: case CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID: @@ -587,6 +605,14 @@ tu_perfetto_end_submit(struct tu_queue *queue, (trace_payload_as_extra_func) &trace_payload_as_extra_end_##event_name); \ } +#define CREATE_STICKY_WARNING_EVENT_CALLBACK(event_name, stage_id) \ + void tu_perfetto_##event_name(struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, const void *flush_data, \ + const struct trace_##event_name *payload, const void *indirect_data) \ + { \ + stage_start(dev, ts_ns, stage_id, payload, sizeof(*payload), indirect_data, \ + (trace_payload_as_extra_func) & trace_payload_as_extra_##event_name); \ + } + CREATE_EVENT_CALLBACK(cmd_buffer, CMD_BUFFER_STAGE_ID) CREATE_EVENT_CALLBACK(secondary_cmd_buffer, SECONDARY_CMD_BUFFER_STAGE_ID) CREATE_EVENT_CALLBACK(render_pass, RENDER_PASS_STAGE_ID) diff --git a/src/freedreno/vulkan/tu_perfetto.h b/src/freedreno/vulkan/tu_perfetto.h index 11899c17477..72dcc7acd0d 100644 --- a/src/freedreno/vulkan/tu_perfetto.h +++ b/src/freedreno/vulkan/tu_perfetto.h @@ -41,6 +41,7 @@ enum tu_queue_id { ANNOTATIONS_QUEUE_ID, BR_HW_QUEUE_ID, BV_HW_QUEUE_ID, + PERF_WARNINGS_QUEUE_ID, TU_QUEUE_ID_COUNT, }; @@ -111,6 +112,7 @@ struct tu_perfetto_clocks struct tu_perfetto_state { struct tu_perfetto_stage_stack annotations_stack; struct tu_perfetto_stage_stack render_stack; + struct tu_perfetto_stage_stack sticky_warnings_stack; uint64_t context_iid; uint64_t queue_iids[TU_QUEUE_ID_COUNT]; diff --git a/src/freedreno/vulkan/tu_tracepoints.py b/src/freedreno/vulkan/tu_tracepoints.py index bac93f21298..7ab20642af4 100644 --- a/src/freedreno/vulkan/tu_tracepoints.py +++ b/src/freedreno/vulkan/tu_tracepoints.py @@ -83,6 +83,29 @@ def begin_end_tp(name, args=[], tp_struct=None, tp_print=None, tp_print=end_tp_print if queue_tp else None, tp_markers='tu_cs_trace_end' if marker_tp else None) +def singular_tp(name, args=[], tp_struct=None, tp_print=None, + tp_default_enabled=True, marker_tp=True, + queue_tp=True, toggle_name=None): + global tu_default_tps + + if not toggle_name: + toggle_name = name + + if tp_default_enabled and toggle_name not in tu_default_tps: + tu_default_tps.append(toggle_name) + + tp_struct = [command_buffer_struct] + (tp_struct if tp_struct else []) + args = [command_buffer_arg] + (args if args else []) + + Tracepoint('{0}'.format(name), + toggle_name=toggle_name, + args=args, + tp_struct=tp_struct, + tp_perfetto='tu_perfetto_{0}'.format(name) if queue_tp else None, + tp_print=tp_print if queue_tp else None, + tp_markers='tu_cs_trace_singular' if marker_tp else None) + + begin_end_tp('cmd_buffer', args=[Arg(type='str', var='TUdebugFlags', c_format='%s', length_arg='96', copy_func='strncpy'), Arg(type='str', var='IR3debugFlags', c_format='%s', length_arg='96', copy_func='strncpy')],