mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 00:40:09 +01:00
tu: Implement utrace CS marker support
Adds support for emitting utrace markers into the CS, this allows for useful debug information that can be decoded from a recorded command stream. Signed-off-by: Mark Collins <mark@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18271>
This commit is contained in:
parent
ac5a55ef11
commit
d151ba5c30
4 changed files with 113 additions and 4 deletions
|
|
@ -39,6 +39,10 @@ extern "C" {
|
|||
#define CP_TYPE4_PKT 0x40000000
|
||||
#define CP_TYPE7_PKT 0x70000000
|
||||
|
||||
#define CP_NOP_MESG 0x4D455347
|
||||
#define CP_NOP_BEGN 0x4245474E
|
||||
#define CP_NOP_END 0x454E4400
|
||||
|
||||
/*
|
||||
* Helpers for pm4 pkt header building/parsing:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -435,3 +435,71 @@ tu_cs_reset(struct tu_cs *cs)
|
|||
|
||||
cs->entry_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tu_cs_emit_debug_string(struct tu_cs *cs, const char *string, int len)
|
||||
{
|
||||
assert(cs->mode == TU_CS_MODE_GROW);
|
||||
|
||||
/* max packet size is 0x3fff dwords */
|
||||
len = MIN2(len, 0x3fff * 4);
|
||||
|
||||
tu_cs_emit_pkt7(cs, CP_NOP, align(len, 4) / 4);
|
||||
const uint32_t *buf = (const uint32_t *) string;
|
||||
|
||||
tu_cs_emit_array(cs, buf, len / 4);
|
||||
buf += len / 4;
|
||||
len = len % 4;
|
||||
|
||||
/* copy remainder bytes without reading past end of input string */
|
||||
if (len > 0) {
|
||||
uint32_t w = 0;
|
||||
memcpy(&w, buf, len);
|
||||
tu_cs_emit(cs, w);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tu_cs_emit_debug_magic_strv(struct tu_cs *cs,
|
||||
uint32_t magic,
|
||||
const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
int fmt_len = vsnprintf(NULL, 0, fmt, args);
|
||||
int len = 4 + fmt_len + 1;
|
||||
char *string = (char *) malloc(len);
|
||||
|
||||
/* format: <magic><formatted string>\0 */
|
||||
*(uint32_t *) string = magic;
|
||||
vsnprintf(string + 4, fmt_len + 1, fmt, args);
|
||||
|
||||
tu_cs_emit_debug_string(cs, string, len);
|
||||
free(string);
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 2, 3))) void
|
||||
tu_cs_emit_debug_msg(struct tu_cs *cs, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
tu_cs_emit_debug_magic_strv(cs, CP_NOP_MESG, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
tu_cs_trace_start(void *cs, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
tu_cs_emit_debug_magic_strv((struct tu_cs *) cs, CP_NOP_BEGN, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
tu_cs_trace_end(void *cs, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
tu_cs_emit_debug_magic_strv((struct tu_cs *) cs, CP_NOP_END, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
|
@ -375,6 +375,40 @@ tu_cs_emit_call(struct tu_cs *cs, const struct tu_cs *target)
|
|||
tu_cs_emit_ib(cs, target->entries + i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a CP_NOP with a string tail into the command stream.
|
||||
*/
|
||||
void
|
||||
tu_cs_emit_debug_string(struct tu_cs *cs, const char *string, int len);
|
||||
|
||||
void
|
||||
tu_cs_emit_debug_magic_strv(struct tu_cs *cs,
|
||||
uint32_t magic,
|
||||
const char *fmt,
|
||||
va_list args);
|
||||
|
||||
__attribute__((format(printf, 2, 3))) void
|
||||
tu_cs_emit_debug_msg(struct tu_cs *cs, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* Emit a single message into the CS that denote the calling function and any
|
||||
* optional printf-style parameters when utrace markers are enabled.
|
||||
*/
|
||||
#define TU_CS_DEBUG_MSG(CS, FORMAT_STRING, ...) \
|
||||
do { \
|
||||
if (unlikely(u_trace_markers_enabled(&(CS)->device->trace_context))) \
|
||||
tu_cs_emit_debug_msg(CS, "%s(" FORMAT_STRING ")", __func__, \
|
||||
## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
typedef struct tu_cs *tu_debug_scope;
|
||||
|
||||
__attribute__((format(printf, 2, 3))) void
|
||||
tu_cs_trace_start(void *cs, const char *fmt, ...);
|
||||
|
||||
__attribute__((format(printf, 2, 3))) void
|
||||
tu_cs_trace_end(void *cs, const char *fmt, ...);
|
||||
|
||||
/* Helpers for bracketing a large sequence of commands of unknown size inside
|
||||
* a CP_COND_REG_EXEC packet.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ tu_default_tps = []
|
|||
#
|
||||
|
||||
def begin_end_tp(name, args=[], tp_struct=None, tp_print=None,
|
||||
tp_default_enabled=True):
|
||||
tp_default_enabled=True, marker_tp=True,
|
||||
queue_tp=True):
|
||||
global tu_default_tps
|
||||
if tp_default_enabled:
|
||||
tu_default_tps.append(name)
|
||||
|
|
@ -53,11 +54,13 @@ def begin_end_tp(name, args=[], tp_struct=None, tp_print=None,
|
|||
toggle_name=name,
|
||||
args=args,
|
||||
tp_struct=tp_struct,
|
||||
tp_perfetto='tu_perfetto_start_{0}'.format(name),
|
||||
tp_print=tp_print)
|
||||
tp_perfetto='tu_perfetto_start_{0}'.format(name) if queue_tp else None,
|
||||
tp_print=tp_print if queue_tp else None,
|
||||
tp_markers='tu_cs_trace_start' if marker_tp else None)
|
||||
Tracepoint('end_{0}'.format(name),
|
||||
toggle_name=name,
|
||||
tp_perfetto='tu_perfetto_end_{0}'.format(name))
|
||||
tp_perfetto='tu_perfetto_end_{0}'.format(name),
|
||||
tp_markers='tu_cs_trace_end' if marker_tp else None)
|
||||
|
||||
begin_end_tp('cmd_buffer',
|
||||
args=[ArgStruct(type='const struct tu_cmd_buffer *', var='cmd')],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue