u_trace: rework tracepoint argument declaration

We're about to add indirect arguments, having a better way to describe
arguments (as capture/storage) will be useful.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29944>
This commit is contained in:
Lionel Landwerlin
2024-06-27 16:41:04 +03:00
committed by Lionel Landwerlin
parent 29bf1547c0
commit 4347ccbe57
3 changed files with 79 additions and 65 deletions

View File

@@ -143,10 +143,9 @@ begin_end_tp('compute',
# Annotations for Cmd(Begin|End)DebugUtilsLabelEXT
for suffix in ["", "_rp"]:
begin_end_tp('cmd_buffer_annotation' + suffix,
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'),])
args=[Arg(type='unsigned', var='len'),
Arg(type='str', var='str', c_format='%s', length_arg='len + 1', copy_func='strncpy'),],
tp_struct=[Arg(type='uint8_t', name='dummy', var='0'),])
utrace_generate(cpath=args.utrace_src,
hpath=args.utrace_hdr,

View File

@@ -78,10 +78,9 @@ def define_tracepoints(args):
# 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'),],
tp_args=[Arg(type='unsigned', var='len'),
Arg(type='str', var='str', c_format='%s', length_arg='len + 1', copy_func='strncpy'),],
tp_struct=[Arg(type='uint8_t', name='dummy', var='0')],
end_pipelined=False,
need_cs_param=True)
@@ -97,10 +96,9 @@ def define_tracepoints(args):
# 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'),],
tp_args=[Arg(type='unsigned', var='len'),
Arg(type='str', var='str', c_format='%s', length_arg='len + 1', copy_func='strncpy'),],
tp_struct=[Arg(type='uint8_t', name='dummy', var='0'),],
end_pipelined=True)
# Transform feedback, only for Anv
@@ -171,8 +169,7 @@ def define_tracepoints(args):
begin_end_tp('draw_mesh',
tp_args=[Arg(type='uint32_t', var='group_x', c_format='%u'),
Arg(type='uint32_t', var='group_y', c_format='%u'),
Arg(type='uint32_t', var='group_z', c_format='%u'),],
tp_print=['group=%ux%ux%u', '__entry->group_x', '__entry->group_y', '__entry->group_z'])
Arg(type='uint32_t', var='group_z', c_format='%u'),])
begin_end_tp('draw_mesh_indirect',
tp_args=[Arg(type='uint32_t', var='draw_count', c_format='%u'),])
begin_end_tp('draw_mesh_indirect_count',
@@ -182,7 +179,6 @@ def define_tracepoints(args):
tp_args=[Arg(type='uint32_t', var='group_x', c_format='%u'),
Arg(type='uint32_t', var='group_y', c_format='%u'),
Arg(type='uint32_t', var='group_z', c_format='%u'),],
tp_print=['group=%ux%ux%u', '__entry->group_x', '__entry->group_y', '__entry->group_z'],
compute=True)
# Used to identify copies generated by utrace
@@ -198,7 +194,6 @@ def define_tracepoints(args):
tp_args=[Arg(type='uint32_t', var='group_x', c_format='%u'),
Arg(type='uint32_t', var='group_y', c_format='%u'),
Arg(type='uint32_t', var='group_z', c_format='%u'),],
tp_print=['group=%ux%ux%u', '__entry->group_x', '__entry->group_y', '__entry->group_z'],
compute=True)
def flag_bits(args):

View File

@@ -56,21 +56,31 @@ class Tracepoint(object):
assert isinstance(args, list)
assert name not in TRACEPOINTS
def needs_storage(a):
if a.c_format is None:
return False
return True
self.name = name
self.args = args
if tp_struct is None:
tp_struct = args
else:
tp_struct += [x for x in args if isinstance(x, TracepointArg)]
# For storage data, include all the specified tp_struct by the caller
# as well as arguments needing storage
self.tp_struct = []
if tp_struct is not None:
self.tp_struct += tp_struct
self.tp_struct += [x for x in args if needs_storage(x)]
# For printing, include all the arguments & tp_struct elements that
# have a format printer
self.tp_print = [x for x in args if x.c_format is not None]
if tp_struct is not None:
self.tp_print += [x for x in tp_struct if x.c_format is not None]
self.tp_struct = tp_struct
self.has_variable_arg = False
for arg in self.tp_struct:
if arg.length_arg != None and not arg.length_arg.isdigit():
self.has_variable_arg = True
break
self.tp_print = tp_print
self.tp_print_custom = tp_print
self.tp_perfetto = tp_perfetto
self.tp_markers = tp_markers
self.tp_flags = tp_flags
@@ -95,7 +105,7 @@ class Tracepoint(object):
class TracepointArgStruct():
"""Represents struct that is being passed as an argument
"""
def __init__(self, type, var):
def __init__(self, type, var, c_format=None, fields=[]):
"""Parameters:
- type: argument's C type.
@@ -106,13 +116,27 @@ class TracepointArgStruct():
self.type = type
self.var = var
self.name = var
self.is_struct = True
self.c_format = c_format
self.fields = fields
self.to_prim_type = None
self.func_param = f"{self.type} {self.var}"
def value_expr(self, entry_name):
ret = None
if self.is_struct:
ret = ", ".join([f"{entry_name}->{self.name}.{f}" for f in self.fields])
else:
ret = f"{entry_name}->{self.name}"
return ret
class TracepointArg(object):
"""Class that represents either an argument being passed or a field in a struct
"""
def __init__(self, type, var, c_format, name=None, to_prim_type=None, length_arg=None, copy_func=None):
def __init__(self, type, var, c_format=None, name=None, to_prim_type=None,
length_arg=None, copy_func=None):
"""Parameters:
- type: argument's C type.
@@ -126,7 +150,6 @@ class TracepointArg(object):
"""
assert isinstance(type, str)
assert isinstance(var, str)
assert isinstance(c_format, str)
self.type = type
self.var = var
@@ -138,10 +161,13 @@ class TracepointArg(object):
self.length_arg = length_arg
self.copy_func = copy_func
self.is_struct = False
if self.type == "str":
self.struct_member = f"char {self.name}[{length_arg} + 1]"
elif self.length_arg:
self.struct_member = f"{self.type} {self.name}[0]"
if self.length_arg and self.length_arg.isdigit():
self.struct_member = f"char {self.name}[{length_arg} + 1]"
else:
self.struct_member = f"char {self.name}[0]"
else:
self.struct_member = f"{self.type} {self.name}"
@@ -150,6 +176,12 @@ class TracepointArg(object):
else:
self.func_param = f"{self.type} {self.var}"
def value_expr(self, entry_name):
ret = f"{entry_name}->{self.name}"
if not self.is_struct and self.to_prim_type:
ret = self.to_prim_type.format(ret)
return ret
HEADERS = []
@@ -247,7 +279,7 @@ struct trace_${trace_name} {
% for arg in trace.tp_struct:
${arg.struct_member};
% endfor
% if len(trace.args) == 0:
% if len(trace.tp_struct) == 0:
#ifdef __cplusplus
/* avoid warnings about empty struct size mis-match in C vs C++..
* the size mis-match is harmless because (a) nothing will deref
@@ -385,53 +417,49 @@ ${trace_toggle_name}_config_variable(void)
*/
% if trace.can_generate_print():
static void __print_${trace_name}(FILE *out, const void *arg) {
% if len(trace.tp_struct) > 0:
const struct trace_${trace_name} *__entry =
(const struct trace_${trace_name} *)arg;
% if trace.tp_print is not None:
fprintf(out, "${trace.tp_print[0]}\\n"
% for arg in trace.tp_print[1:]:
% endif
% if trace.tp_print_custom is not None:
fprintf(out, "${trace.tp_print_custom[0]}\\n"
% for arg in trace.tp_print_custom[1:]:
, ${arg}
% endfor
% else:
fprintf(out, ""
% for arg in trace.tp_struct:
% for arg in trace.tp_print:
"${arg.name}=${arg.c_format}, "
% endfor
"\\n"
% for arg in trace.tp_struct:
% if arg.to_prim_type:
,${arg.to_prim_type.format('__entry->' + arg.name)}
% else:
,__entry->${arg.name}
% endif
% for arg in trace.tp_print:
,${arg.value_expr("__entry")}
% endfor
% endif
);
}
static void __print_json_${trace_name}(FILE *out, const void *arg) {
% if len(trace.tp_struct) > 0:
const struct trace_${trace_name} *__entry =
(const struct trace_${trace_name} *)arg;
% if trace.tp_print is not None:
fprintf(out, "\\"unstructured\\": \\"${trace.tp_print[0]}\\""
% for arg in trace.tp_print[1:]:
% endif
% if trace.tp_print_custom is not None:
fprintf(out, "\\"unstructured\\": \\"${trace.tp_print_custom[0]}\\""
% for arg in trace.tp_print_custom[1:]:
, ${arg}
% endfor
% else:
fprintf(out, ""
% for arg in trace.tp_struct:
% for arg in trace.tp_print:
"\\"${arg.name}\\": \\"${arg.c_format}\\""
% if arg != trace.tp_struct[-1]:
% if arg != trace.tp_print[-1]:
", "
% endif
% endfor
% for arg in trace.tp_struct:
% if arg.to_prim_type:
,${arg.to_prim_type.format('__entry->' + arg.name)}
% else:
,__entry->${arg.name}
% endif
% endfor
% for arg in trace.tp_print:
,${arg.value_expr("__entry")}
% endfor
% endif
);
}
@@ -446,16 +474,12 @@ __attribute__((format(printf, 3, 4))) void ${trace.tp_markers}(struct u_trace_co
static void __emit_label_${trace_name}(struct u_trace_context *utctx, void *cs, struct trace_${trace_name} *entry) {
${trace.tp_markers}(utctx, cs, "${trace_name}("
% for idx,arg in enumerate(trace.tp_struct):
% for idx,arg in enumerate(trace.tp_print):
"${"," if idx != 0 else ""}${arg.name}=${arg.c_format}"
% endfor
")"
% for arg in trace.tp_struct:
% if arg.to_prim_type:
,${arg.to_prim_type.format('entry->' + arg.name)}
% else:
,entry->${arg.name}
% endif
% for arg in trace.tp_print:
,${arg.value_expr('entry')}
% endfor
);
}
@@ -603,19 +627,15 @@ static void UNUSED
trace_payload_as_extra_${trace_name}(perfetto::protos::pbzero::GpuRenderStageEvent *event,
const struct trace_${trace_name} *payload)
{
% if all([trace.tp_perfetto, trace.tp_struct]) and len(trace.tp_struct) > 0:
% if trace.tp_perfetto is not None and len(trace.tp_print) > 0:
char buf[128];
% for arg in trace.tp_struct:
% for arg in trace.tp_print:
{
auto data = event->add_extra_data();
data->set_name("${arg.name}");
% if arg.to_prim_type:
sprintf(buf, "${arg.c_format}", ${arg.to_prim_type.format('payload->' + arg.name)});
% else:
sprintf(buf, "${arg.c_format}", payload->${arg.name});
% endif
sprintf(buf, "${arg.c_format}", ${arg.value_expr("payload")});
data->set_value(buf);
}