mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-23 10:14:13 +08:00
u_trace: add support for indirect data
Allows a driver to declare indirect arguments for its tracepoints and pass an address. u_trace will request a copy of the data which should be implemented on the command processor. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Co-Authored-by: Danylo Piliaiev <dpiliaiev@igalia.com> Reviewed-by: Danylo Piliaiev <dpiliaiev@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29944>
This commit is contained in:
parent
cb27b9541b
commit
0a17035b5c
@ -44,6 +44,9 @@ u_trace is controlled by environment variables:
|
|||||||
|
|
||||||
- For Turnip, ``cffdump`` can be used to view the markers in
|
- For Turnip, ``cffdump`` can be used to view the markers in
|
||||||
the trace.
|
the trace.
|
||||||
|
``indirects``
|
||||||
|
enables indirect data capture for some of the tracepoints (like
|
||||||
|
indirect draw count or indirect dispatch size)
|
||||||
|
|
||||||
.. envvar:: MESA_GPU_TRACEFILE
|
.. envvar:: MESA_GPU_TRACEFILE
|
||||||
|
|
||||||
|
@ -2521,10 +2521,13 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
|
|||||||
device->submit_count = 0;
|
device->submit_count = 0;
|
||||||
u_trace_context_init(&device->trace_context, device,
|
u_trace_context_init(&device->trace_context, device,
|
||||||
sizeof(uint64_t),
|
sizeof(uint64_t),
|
||||||
|
0,
|
||||||
tu_trace_create_buffer,
|
tu_trace_create_buffer,
|
||||||
tu_trace_destroy_buffer,
|
tu_trace_destroy_buffer,
|
||||||
TU_CALLX(device, tu_trace_record_ts),
|
TU_CALLX(device, tu_trace_record_ts),
|
||||||
tu_trace_read_ts,
|
tu_trace_read_ts,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
tu_trace_delete_flush_data);
|
tu_trace_delete_flush_data);
|
||||||
|
|
||||||
tu_breadcrumbs_init(device);
|
tu_breadcrumbs_init(device);
|
||||||
|
@ -474,7 +474,8 @@ tu_perfetto_submit(struct tu_device *dev,
|
|||||||
#define CREATE_EVENT_CALLBACK(event_name, stage_id) \
|
#define CREATE_EVENT_CALLBACK(event_name, stage_id) \
|
||||||
void tu_perfetto_start_##event_name( \
|
void tu_perfetto_start_##event_name( \
|
||||||
struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
|
struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
|
||||||
const void *flush_data, const struct trace_start_##event_name *payload) \
|
const void *flush_data, const struct trace_start_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
stage_start( \
|
stage_start( \
|
||||||
dev, ts_ns, stage_id, NULL, payload, sizeof(*payload), \
|
dev, ts_ns, stage_id, NULL, payload, sizeof(*payload), \
|
||||||
@ -483,7 +484,8 @@ tu_perfetto_submit(struct tu_device *dev,
|
|||||||
\
|
\
|
||||||
void tu_perfetto_end_##event_name( \
|
void tu_perfetto_end_##event_name( \
|
||||||
struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
|
struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
|
||||||
const void *flush_data, const struct trace_end_##event_name *payload) \
|
const void *flush_data, const struct trace_end_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
stage_end( \
|
stage_end( \
|
||||||
dev, ts_ns, stage_id, flush_data, payload, \
|
dev, ts_ns, stage_id, flush_data, payload, \
|
||||||
@ -510,7 +512,8 @@ tu_perfetto_start_cmd_buffer_annotation(
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_start_cmd_buffer_annotation *payload)
|
const struct trace_start_cmd_buffer_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
/* No extra func necessary, the only arg is in the end payload.*/
|
/* No extra func necessary, the only arg is in the end payload.*/
|
||||||
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, payload->str, payload,
|
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, payload->str, payload,
|
||||||
@ -523,7 +526,8 @@ tu_perfetto_end_cmd_buffer_annotation(
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_end_cmd_buffer_annotation *payload)
|
const struct trace_end_cmd_buffer_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
/* Pass the payload string as the app_event, which will appear right on the
|
/* Pass the payload string as the app_event, which will appear right on the
|
||||||
* event block, rather than as metadata inside.
|
* event block, rather than as metadata inside.
|
||||||
@ -538,7 +542,8 @@ tu_perfetto_start_cmd_buffer_annotation_rp(
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_start_cmd_buffer_annotation_rp *payload)
|
const struct trace_start_cmd_buffer_annotation_rp *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
/* No extra func necessary, the only arg is in the end payload.*/
|
/* No extra func necessary, the only arg is in the end payload.*/
|
||||||
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
|
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
|
||||||
@ -551,7 +556,8 @@ tu_perfetto_end_cmd_buffer_annotation_rp(
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_end_cmd_buffer_annotation_rp *payload)
|
const struct trace_end_cmd_buffer_annotation_rp *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
/* Pass the payload string as the app_event, which will appear right on the
|
/* Pass the payload string as the app_event, which will appear right on the
|
||||||
* event block, rather than as metadata inside.
|
* event block, rather than as metadata inside.
|
||||||
|
@ -62,16 +62,22 @@ void
|
|||||||
u_trace_pipe_context_init(struct u_trace_context *utctx,
|
u_trace_pipe_context_init(struct u_trace_context *utctx,
|
||||||
struct pipe_context *pctx,
|
struct pipe_context *pctx,
|
||||||
uint32_t timestamp_size_B,
|
uint32_t timestamp_size_B,
|
||||||
|
uint32_t max_indirect_size_B,
|
||||||
u_trace_record_ts record_timestamp,
|
u_trace_record_ts record_timestamp,
|
||||||
u_trace_read_ts read_timestamp,
|
u_trace_read_ts read_timestamp,
|
||||||
|
u_trace_capture_data capture_data,
|
||||||
|
u_trace_get_data get_data,
|
||||||
u_trace_delete_flush_data delete_flush_data)
|
u_trace_delete_flush_data delete_flush_data)
|
||||||
{
|
{
|
||||||
u_trace_context_init(utctx, pctx,
|
u_trace_context_init(utctx, pctx,
|
||||||
timestamp_size_B,
|
timestamp_size_B,
|
||||||
|
max_indirect_size_B,
|
||||||
u_trace_pipe_create_buffer,
|
u_trace_pipe_create_buffer,
|
||||||
u_trace_pipe_delete_buffer,
|
u_trace_pipe_delete_buffer,
|
||||||
record_timestamp,
|
record_timestamp,
|
||||||
read_timestamp,
|
read_timestamp,
|
||||||
|
capture_data,
|
||||||
|
get_data,
|
||||||
delete_flush_data);
|
delete_flush_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,11 @@ void
|
|||||||
u_trace_pipe_context_init(struct u_trace_context *utctx,
|
u_trace_pipe_context_init(struct u_trace_context *utctx,
|
||||||
struct pipe_context *pctx,
|
struct pipe_context *pctx,
|
||||||
uint32_t timestamp_size_B,
|
uint32_t timestamp_size_B,
|
||||||
|
uint32_t max_indirect_size_B,
|
||||||
u_trace_record_ts record_timestamp,
|
u_trace_record_ts record_timestamp,
|
||||||
u_trace_read_ts read_timestamp,
|
u_trace_read_ts read_timestamp,
|
||||||
|
u_trace_capture_data capture_data,
|
||||||
|
u_trace_get_data get_data,
|
||||||
u_trace_delete_flush_data delete_flush_data);
|
u_trace_delete_flush_data delete_flush_data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -718,8 +718,11 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
|
|||||||
fd_gpu_tracepoint_config_variable();
|
fd_gpu_tracepoint_config_variable();
|
||||||
u_trace_pipe_context_init(&ctx->trace_context, pctx,
|
u_trace_pipe_context_init(&ctx->trace_context, pctx,
|
||||||
sizeof(uint64_t),
|
sizeof(uint64_t),
|
||||||
|
0,
|
||||||
fd_trace_record_ts,
|
fd_trace_record_ts,
|
||||||
fd_trace_read_ts,
|
fd_trace_read_ts,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
fd_trace_delete_flush_data);
|
fd_trace_delete_flush_data);
|
||||||
|
|
||||||
fd_autotune_init(&ctx->autotune, screen->dev);
|
fd_autotune_init(&ctx->autotune, screen->dev);
|
||||||
|
@ -357,7 +357,8 @@ fd_perfetto_submit(struct fd_context *ctx)
|
|||||||
void
|
void
|
||||||
fd_start_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_render_pass *payload)
|
const struct trace_start_render_pass *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, SURFACE_STAGE_ID);
|
stage_start(pctx, ts_ns, SURFACE_STAGE_ID);
|
||||||
|
|
||||||
@ -378,7 +379,8 @@ fd_start_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_render_pass *payload)
|
const struct trace_end_render_pass *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, SURFACE_STAGE_ID);
|
stage_end(pctx, ts_ns, SURFACE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -386,7 +388,8 @@ fd_end_render_pass(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_binning_ib *payload)
|
const struct trace_start_binning_ib *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, BINNING_STAGE_ID);
|
stage_start(pctx, ts_ns, BINNING_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -394,7 +397,8 @@ fd_start_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_binning_ib *payload)
|
const struct trace_end_binning_ib *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, BINNING_STAGE_ID);
|
stage_end(pctx, ts_ns, BINNING_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -402,7 +406,8 @@ fd_end_binning_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_draw_ib *payload)
|
const struct trace_start_draw_ib *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(
|
stage_start(
|
||||||
pctx, ts_ns,
|
pctx, ts_ns,
|
||||||
@ -412,7 +417,8 @@ fd_start_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_draw_ib *payload)
|
const struct trace_end_draw_ib *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(
|
stage_end(
|
||||||
pctx, ts_ns,
|
pctx, ts_ns,
|
||||||
@ -422,7 +428,8 @@ fd_end_draw_ib(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_blit *payload)
|
const struct trace_start_blit *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, BLIT_STAGE_ID);
|
stage_start(pctx, ts_ns, BLIT_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -430,7 +437,8 @@ fd_start_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_blit *payload)
|
const struct trace_end_blit *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, BLIT_STAGE_ID);
|
stage_end(pctx, ts_ns, BLIT_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -438,7 +446,8 @@ fd_end_blit(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_compute *payload)
|
const struct trace_start_compute *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, COMPUTE_STAGE_ID);
|
stage_start(pctx, ts_ns, COMPUTE_STAGE_ID);
|
||||||
|
|
||||||
@ -458,7 +467,8 @@ fd_start_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_compute *payload)
|
const struct trace_end_compute *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, COMPUTE_STAGE_ID);
|
stage_end(pctx, ts_ns, COMPUTE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -466,7 +476,8 @@ fd_end_compute(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_clears *payload)
|
const struct trace_start_clears *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, CLEAR_STAGE_ID);
|
stage_start(pctx, ts_ns, CLEAR_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -474,7 +485,8 @@ fd_start_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_clears *payload)
|
const struct trace_end_clears *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, CLEAR_STAGE_ID);
|
stage_end(pctx, ts_ns, CLEAR_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -482,7 +494,8 @@ fd_end_clears(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_tile_loads *payload)
|
const struct trace_start_tile_loads *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, TILE_LOAD_STAGE_ID);
|
stage_start(pctx, ts_ns, TILE_LOAD_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -490,7 +503,8 @@ fd_start_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_tile_loads *payload)
|
const struct trace_end_tile_loads *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, TILE_LOAD_STAGE_ID);
|
stage_end(pctx, ts_ns, TILE_LOAD_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -498,7 +512,8 @@ fd_end_tile_loads(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_tile_stores *payload)
|
const struct trace_start_tile_stores *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, TILE_STORE_STAGE_ID);
|
stage_start(pctx, ts_ns, TILE_STORE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -506,7 +521,8 @@ fd_start_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_tile_stores *payload)
|
const struct trace_end_tile_stores *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, TILE_STORE_STAGE_ID);
|
stage_end(pctx, ts_ns, TILE_STORE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -514,7 +530,8 @@ fd_end_tile_stores(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_state_restore *payload)
|
const struct trace_start_state_restore *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, STATE_RESTORE_STAGE_ID);
|
stage_start(pctx, ts_ns, STATE_RESTORE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -522,7 +539,8 @@ fd_start_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_state_restore *payload)
|
const struct trace_end_state_restore *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, STATE_RESTORE_STAGE_ID);
|
stage_end(pctx, ts_ns, STATE_RESTORE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -530,7 +548,8 @@ fd_end_state_restore(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_vsc_overflow_test *payload)
|
const struct trace_start_vsc_overflow_test *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, VSC_OVERFLOW_STAGE_ID);
|
stage_start(pctx, ts_ns, VSC_OVERFLOW_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -538,7 +557,8 @@ fd_start_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_vsc_overflow_test *payload)
|
const struct trace_end_vsc_overflow_test *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, VSC_OVERFLOW_STAGE_ID);
|
stage_end(pctx, ts_ns, VSC_OVERFLOW_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -546,7 +566,8 @@ fd_end_vsc_overflow_test(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_start_prologue(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_start_prologue(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_start_prologue *payload)
|
const struct trace_start_prologue *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_start(pctx, ts_ns, PROLOGUE_STAGE_ID);
|
stage_start(pctx, ts_ns, PROLOGUE_STAGE_ID);
|
||||||
}
|
}
|
||||||
@ -554,7 +575,8 @@ fd_start_prologue(struct pipe_context *pctx, uint64_t ts_ns,
|
|||||||
void
|
void
|
||||||
fd_end_prologue(struct pipe_context *pctx, uint64_t ts_ns,
|
fd_end_prologue(struct pipe_context *pctx, uint64_t ts_ns,
|
||||||
uint16_t tp_idx, const void *flush_data,
|
uint16_t tp_idx, const void *flush_data,
|
||||||
const struct trace_end_prologue *payload)
|
const struct trace_end_prologue *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
stage_end(pctx, ts_ns, PROLOGUE_STAGE_ID);
|
stage_end(pctx, ts_ns, PROLOGUE_STAGE_ID);
|
||||||
}
|
}
|
||||||
|
@ -188,10 +188,13 @@ void iris_utrace_init(struct iris_context *ice)
|
|||||||
|
|
||||||
u_trace_context_init(&ice->ds.trace_context, &ice->ctx,
|
u_trace_context_init(&ice->ds.trace_context, &ice->ctx,
|
||||||
sizeof(union iris_utrace_timestamp),
|
sizeof(union iris_utrace_timestamp),
|
||||||
|
0,
|
||||||
iris_utrace_create_buffer,
|
iris_utrace_create_buffer,
|
||||||
iris_utrace_delete_buffer,
|
iris_utrace_delete_buffer,
|
||||||
iris_utrace_record_ts,
|
iris_utrace_record_ts,
|
||||||
iris_utrace_read_ts,
|
iris_utrace_read_ts,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
iris_utrace_delete_flush_data);
|
iris_utrace_delete_flush_data);
|
||||||
|
|
||||||
for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
|
for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
|
||||||
|
@ -260,7 +260,8 @@ extern "C" {
|
|||||||
#define CREATE_DUAL_EVENT_CALLBACK(event_name, stage) \
|
#define CREATE_DUAL_EVENT_CALLBACK(event_name, stage) \
|
||||||
void si_ds_begin_##event_name(struct si_ds_device *device, uint64_t ts_ns, uint16_t tp_idx, \
|
void si_ds_begin_##event_name(struct si_ds_device *device, uint64_t ts_ns, uint16_t tp_idx, \
|
||||||
const void *flush_data, \
|
const void *flush_data, \
|
||||||
const struct trace_si_begin_##event_name *payload) \
|
const struct trace_si_begin_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
const struct si_ds_flush_data *flush = (const struct si_ds_flush_data *) flush_data; \
|
const struct si_ds_flush_data *flush = (const struct si_ds_flush_data *) flush_data; \
|
||||||
begin_event(flush->queue, ts_ns, stage); \
|
begin_event(flush->queue, ts_ns, stage); \
|
||||||
@ -268,7 +269,8 @@ void si_ds_begin_##event_name(struct si_ds_device *device, uint64_t ts_ns, uint1
|
|||||||
\
|
\
|
||||||
void si_ds_end_##event_name(struct si_ds_device *device, uint64_t ts_ns, uint16_t tp_idx, \
|
void si_ds_end_##event_name(struct si_ds_device *device, uint64_t ts_ns, uint16_t tp_idx, \
|
||||||
const void *flush_data, \
|
const void *flush_data, \
|
||||||
const struct trace_si_end_##event_name *payload) \
|
const struct trace_si_end_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
const struct si_ds_flush_data *flush = (const struct si_ds_flush_data *) flush_data; \
|
const struct si_ds_flush_data *flush = (const struct si_ds_flush_data *) flush_data; \
|
||||||
end_event(flush->queue, ts_ns, stage, flush->submission_id, NULL, payload, \
|
end_event(flush->queue, ts_ns, stage, flush->submission_id, NULL, payload, \
|
||||||
|
@ -61,8 +61,9 @@ void si_utrace_init(struct si_context *sctx)
|
|||||||
|
|
||||||
si_ds_device_init(&sctx->ds, &sctx->screen->info, gpu_id, AMD_DS_API_OPENGL);
|
si_ds_device_init(&sctx->ds, &sctx->screen->info, gpu_id, AMD_DS_API_OPENGL);
|
||||||
u_trace_pipe_context_init(&sctx->ds.trace_context, &sctx->b,
|
u_trace_pipe_context_init(&sctx->ds.trace_context, &sctx->b,
|
||||||
sizeof(uint64_t), si_utrace_record_ts,
|
sizeof(uint64_t), 0, si_utrace_record_ts,
|
||||||
si_utrace_read_ts, si_utrace_delete_flush_data);
|
si_utrace_read_ts, NULL, NULL,
|
||||||
|
si_utrace_delete_flush_data);
|
||||||
|
|
||||||
si_ds_device_init_queue(&sctx->ds, &sctx->ds_queue, "%s", "render");
|
si_ds_device_init_queue(&sctx->ds, &sctx->ds_queue, "%s", "render");
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ send_descriptors(IntelRenderpassDataSource::TraceContext &ctx,
|
|||||||
sync_timestamp(ctx, device);
|
sync_timestamp(ctx, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*trace_payload_as_extra_func)(perfetto::protos::pbzero::GpuRenderStageEvent *, const void*);
|
typedef void (*trace_payload_as_extra_func)(perfetto::protos::pbzero::GpuRenderStageEvent *, const void*, const void *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
begin_event(struct intel_ds_queue *queue, uint64_t ts_ns,
|
begin_event(struct intel_ds_queue *queue, uint64_t ts_ns,
|
||||||
@ -258,7 +258,8 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
|
|||||||
uint32_t submission_id,
|
uint32_t submission_id,
|
||||||
uint16_t tracepoint_idx,
|
uint16_t tracepoint_idx,
|
||||||
const char *app_event,
|
const char *app_event,
|
||||||
const void* payload = nullptr,
|
const void *payload = nullptr,
|
||||||
|
const void *indirect_data = nullptr,
|
||||||
trace_payload_as_extra_func payload_as_extra = nullptr)
|
trace_payload_as_extra_func payload_as_extra = nullptr)
|
||||||
{
|
{
|
||||||
struct intel_ds_device *device = queue->device;
|
struct intel_ds_device *device = queue->device;
|
||||||
@ -280,7 +281,6 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
|
|||||||
if (!start_ns)
|
if (!start_ns)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
IntelRenderpassDataSource::Trace([=](IntelRenderpassDataSource::TraceContext tctx) {
|
IntelRenderpassDataSource::Trace([=](IntelRenderpassDataSource::TraceContext tctx) {
|
||||||
if (auto state = tctx.GetIncrementalState(); state->was_cleared) {
|
if (auto state = tctx.GetIncrementalState(); state->was_cleared) {
|
||||||
send_descriptors(tctx, queue->device);
|
send_descriptors(tctx, queue->device);
|
||||||
@ -317,7 +317,7 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
|
|||||||
event->set_submission_id(submission_id);
|
event->set_submission_id(submission_id);
|
||||||
|
|
||||||
if (payload && payload_as_extra) {
|
if (payload && payload_as_extra) {
|
||||||
payload_as_extra(event, payload);
|
payload_as_extra(event, payload, indirect_data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -384,7 +384,8 @@ extern "C" {
|
|||||||
uint64_t ts_ns, \
|
uint64_t ts_ns, \
|
||||||
uint16_t tp_idx, \
|
uint16_t tp_idx, \
|
||||||
const void *flush_data, \
|
const void *flush_data, \
|
||||||
const struct trace_intel_begin_##event_name *payload) \
|
const struct trace_intel_begin_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
const struct intel_ds_flush_data *flush = \
|
const struct intel_ds_flush_data *flush = \
|
||||||
(const struct intel_ds_flush_data *) flush_data; \
|
(const struct intel_ds_flush_data *) flush_data; \
|
||||||
@ -396,12 +397,13 @@ extern "C" {
|
|||||||
uint64_t ts_ns, \
|
uint64_t ts_ns, \
|
||||||
uint16_t tp_idx, \
|
uint16_t tp_idx, \
|
||||||
const void *flush_data, \
|
const void *flush_data, \
|
||||||
const struct trace_intel_end_##event_name *payload) \
|
const struct trace_intel_end_##event_name *payload, \
|
||||||
|
const void *indirect_data) \
|
||||||
{ \
|
{ \
|
||||||
const struct intel_ds_flush_data *flush = \
|
const struct intel_ds_flush_data *flush = \
|
||||||
(const struct intel_ds_flush_data *) flush_data; \
|
(const struct intel_ds_flush_data *) flush_data; \
|
||||||
end_event(flush->queue, ts_ns, stage, flush->submission_id, \
|
end_event(flush->queue, ts_ns, stage, flush->submission_id, \
|
||||||
tp_idx, NULL, payload, \
|
tp_idx, NULL, payload, indirect_data, \
|
||||||
(trace_payload_as_extra_func) \
|
(trace_payload_as_extra_func) \
|
||||||
&trace_payload_as_extra_intel_end_##event_name); \
|
&trace_payload_as_extra_intel_end_##event_name); \
|
||||||
} \
|
} \
|
||||||
@ -442,7 +444,8 @@ intel_ds_begin_cmd_buffer_annotation(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_begin_cmd_buffer_annotation *payload)
|
const struct trace_intel_begin_cmd_buffer_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
@ -454,12 +457,13 @@ intel_ds_end_cmd_buffer_annotation(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_end_cmd_buffer_annotation *payload)
|
const struct trace_intel_end_cmd_buffer_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_CMD_BUFFER,
|
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_CMD_BUFFER,
|
||||||
flush->submission_id, tp_idx, payload->str, NULL, NULL);
|
flush->submission_id, tp_idx, payload->str, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -467,7 +471,8 @@ intel_ds_begin_queue_annotation(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_begin_queue_annotation *payload)
|
const struct trace_intel_begin_queue_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
@ -479,12 +484,13 @@ intel_ds_end_queue_annotation(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_end_queue_annotation *payload)
|
const struct trace_intel_end_queue_annotation *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_QUEUE,
|
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_QUEUE,
|
||||||
flush->submission_id, tp_idx, payload->str, NULL, NULL);
|
flush->submission_id, tp_idx, payload->str, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -492,7 +498,8 @@ intel_ds_begin_stall(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_begin_stall *payload)
|
const struct trace_intel_begin_stall *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
@ -504,12 +511,13 @@ intel_ds_end_stall(struct intel_ds_device *device,
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_intel_end_stall *payload)
|
const struct trace_intel_end_stall *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
const struct intel_ds_flush_data *flush =
|
const struct intel_ds_flush_data *flush =
|
||||||
(const struct intel_ds_flush_data *) flush_data;
|
(const struct intel_ds_flush_data *) flush_data;
|
||||||
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_STALL,
|
end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_STALL,
|
||||||
flush->submission_id, tp_idx, NULL, payload,
|
flush->submission_id, tp_idx, NULL, payload, indirect_data,
|
||||||
(trace_payload_as_extra_func)custom_trace_payload_as_extra_end_stall);
|
(trace_payload_as_extra_func)custom_trace_payload_as_extra_end_stall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,10 +449,13 @@ anv_device_utrace_init(struct anv_device *device)
|
|||||||
u_trace_context_init(&device->ds.trace_context,
|
u_trace_context_init(&device->ds.trace_context,
|
||||||
&device->ds,
|
&device->ds,
|
||||||
device->utrace_timestamp_size,
|
device->utrace_timestamp_size,
|
||||||
|
0,
|
||||||
anv_utrace_create_buffer,
|
anv_utrace_create_buffer,
|
||||||
anv_utrace_destroy_buffer,
|
anv_utrace_destroy_buffer,
|
||||||
anv_utrace_record_ts,
|
anv_utrace_record_ts,
|
||||||
anv_utrace_read_ts,
|
anv_utrace_read_ts,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
anv_utrace_delete_submit);
|
anv_utrace_delete_submit);
|
||||||
|
|
||||||
for (uint32_t q = 0; q < device->queue_count; q++) {
|
for (uint32_t q = 0; q < device->queue_count; q++) {
|
||||||
|
@ -282,10 +282,13 @@ anv_device_utrace_init(struct anv_device *device)
|
|||||||
u_trace_context_init(&device->ds.trace_context,
|
u_trace_context_init(&device->ds.trace_context,
|
||||||
&device->ds,
|
&device->ds,
|
||||||
sizeof(uint64_t),
|
sizeof(uint64_t),
|
||||||
|
0,
|
||||||
anv_utrace_create_buffer,
|
anv_utrace_create_buffer,
|
||||||
anv_utrace_destroy_buffer,
|
anv_utrace_destroy_buffer,
|
||||||
anv_utrace_record_ts,
|
anv_utrace_record_ts,
|
||||||
anv_utrace_read_ts,
|
anv_utrace_read_ts,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
anv_utrace_delete_flush_data);
|
anv_utrace_delete_flush_data);
|
||||||
|
|
||||||
for (uint32_t q = 0; q < device->queue_count; q++) {
|
for (uint32_t q = 0; q < device->queue_count; q++) {
|
||||||
|
@ -91,6 +91,10 @@ struct u_trace_chunk {
|
|||||||
*/
|
*/
|
||||||
void *timestamps;
|
void *timestamps;
|
||||||
|
|
||||||
|
/* table of indirect data captured by u_trace
|
||||||
|
*/
|
||||||
|
void *indirects;
|
||||||
|
|
||||||
/* Array of u_trace_payload_buf referenced by traces[] elements.
|
/* Array of u_trace_payload_buf referenced by traces[] elements.
|
||||||
*/
|
*/
|
||||||
struct u_vector payloads;
|
struct u_vector payloads;
|
||||||
@ -100,6 +104,7 @@ struct u_trace_chunk {
|
|||||||
|
|
||||||
struct util_queue_fence fence;
|
struct util_queue_fence fence;
|
||||||
|
|
||||||
|
bool has_indirect;
|
||||||
bool last; /* this chunk is last in batch */
|
bool last; /* this chunk is last in batch */
|
||||||
bool eof; /* this chunk is last in frame, unless frame_nr is set */
|
bool eof; /* this chunk is last in frame, unless frame_nr is set */
|
||||||
uint32_t frame_nr; /* frame idx from the driver */
|
uint32_t frame_nr; /* frame idx from the driver */
|
||||||
@ -124,7 +129,8 @@ struct u_trace_printer {
|
|||||||
struct u_trace_chunk *chunk,
|
struct u_trace_chunk *chunk,
|
||||||
const struct u_trace_event *evt,
|
const struct u_trace_event *evt,
|
||||||
uint64_t ns,
|
uint64_t ns,
|
||||||
int32_t delta);
|
int32_t delta,
|
||||||
|
const void *indirect);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -156,12 +162,13 @@ print_txt_event(struct u_trace_context *utctx,
|
|||||||
struct u_trace_chunk *chunk,
|
struct u_trace_chunk *chunk,
|
||||||
const struct u_trace_event *evt,
|
const struct u_trace_event *evt,
|
||||||
uint64_t ns,
|
uint64_t ns,
|
||||||
int32_t delta)
|
int32_t delta,
|
||||||
|
const void *indirect)
|
||||||
{
|
{
|
||||||
if (evt->tp->print) {
|
if (evt->tp->print) {
|
||||||
fprintf(utctx->out, "%016" PRIu64 " %+9d: %s: ", ns, delta,
|
fprintf(utctx->out, "%016" PRIu64 " %+9d: %s: ", ns, delta,
|
||||||
evt->tp->name);
|
evt->tp->name);
|
||||||
evt->tp->print(utctx->out, evt->payload);
|
evt->tp->print(utctx->out, evt->payload, indirect);
|
||||||
} else {
|
} else {
|
||||||
fprintf(utctx->out, "%016" PRIu64 " %+9d: %s\n", ns, delta,
|
fprintf(utctx->out, "%016" PRIu64 " %+9d: %s\n", ns, delta,
|
||||||
evt->tp->name);
|
evt->tp->name);
|
||||||
@ -228,7 +235,8 @@ print_json_event(struct u_trace_context *utctx,
|
|||||||
struct u_trace_chunk *chunk,
|
struct u_trace_chunk *chunk,
|
||||||
const struct u_trace_event *evt,
|
const struct u_trace_event *evt,
|
||||||
uint64_t ns,
|
uint64_t ns,
|
||||||
int32_t delta)
|
int32_t delta,
|
||||||
|
const void *indirect)
|
||||||
{
|
{
|
||||||
if (utctx->event_nr != 0)
|
if (utctx->event_nr != 0)
|
||||||
fprintf(utctx->out, ",\n");
|
fprintf(utctx->out, ",\n");
|
||||||
@ -236,7 +244,7 @@ print_json_event(struct u_trace_context *utctx,
|
|||||||
fprintf(utctx->out, "\"time_ns\": \"%016" PRIu64 "\",\n", ns);
|
fprintf(utctx->out, "\"time_ns\": \"%016" PRIu64 "\",\n", ns);
|
||||||
fprintf(utctx->out, "\"params\": {");
|
fprintf(utctx->out, "\"params\": {");
|
||||||
if (evt->tp->print)
|
if (evt->tp->print)
|
||||||
evt->tp->print_json(utctx->out, evt->payload);
|
evt->tp->print_json(utctx->out, evt->payload, indirect);
|
||||||
fprintf(utctx->out, "}\n}\n");
|
fprintf(utctx->out, "}\n}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +293,8 @@ free_chunk(void *ptr)
|
|||||||
struct u_trace_chunk *chunk = ptr;
|
struct u_trace_chunk *chunk = ptr;
|
||||||
|
|
||||||
chunk->utctx->delete_buffer(chunk->utctx, chunk->timestamps);
|
chunk->utctx->delete_buffer(chunk->utctx, chunk->timestamps);
|
||||||
|
if (chunk->indirects)
|
||||||
|
chunk->utctx->delete_buffer(chunk->utctx, chunk->indirects);
|
||||||
|
|
||||||
/* Unref payloads attached to this chunk. */
|
/* Unref payloads attached to this chunk. */
|
||||||
struct u_trace_payload_buf **payload;
|
struct u_trace_payload_buf **payload;
|
||||||
@ -349,6 +359,12 @@ get_chunk(struct u_trace *ut, size_t payload_size)
|
|||||||
chunk->timestamps =
|
chunk->timestamps =
|
||||||
ut->utctx->create_buffer(ut->utctx,
|
ut->utctx->create_buffer(ut->utctx,
|
||||||
chunk->utctx->timestamp_size_bytes * TIMESTAMP_BUF_SIZE);
|
chunk->utctx->timestamp_size_bytes * TIMESTAMP_BUF_SIZE);
|
||||||
|
if (chunk->utctx->max_indirect_size_bytes &&
|
||||||
|
(chunk->utctx->enabled_traces & U_TRACE_TYPE_INDIRECTS)) {
|
||||||
|
chunk->indirects =
|
||||||
|
ut->utctx->create_buffer(ut->utctx,
|
||||||
|
chunk->utctx->max_indirect_size_bytes * TIMESTAMP_BUF_SIZE);
|
||||||
|
}
|
||||||
chunk->last = true;
|
chunk->last = true;
|
||||||
u_vector_init(&chunk->payloads, 4, sizeof(struct u_trace_payload_buf *));
|
u_vector_init(&chunk->payloads, 4, sizeof(struct u_trace_payload_buf *));
|
||||||
if (payload_size > 0) {
|
if (payload_size > 0) {
|
||||||
@ -369,6 +385,7 @@ static const struct debug_named_value config_control[] = {
|
|||||||
{ "perfetto", U_TRACE_TYPE_PERFETTO_ENV, "Enable perfetto" },
|
{ "perfetto", U_TRACE_TYPE_PERFETTO_ENV, "Enable perfetto" },
|
||||||
#endif
|
#endif
|
||||||
{ "markers", U_TRACE_TYPE_MARKERS, "Enable marker trace" },
|
{ "markers", U_TRACE_TYPE_MARKERS, "Enable marker trace" },
|
||||||
|
{ "indirects", U_TRACE_TYPE_INDIRECTS, "Enable indirect data capture" },
|
||||||
DEBUG_NAMED_VALUE_END
|
DEBUG_NAMED_VALUE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -436,10 +453,13 @@ void
|
|||||||
u_trace_context_init(struct u_trace_context *utctx,
|
u_trace_context_init(struct u_trace_context *utctx,
|
||||||
void *pctx,
|
void *pctx,
|
||||||
uint32_t timestamp_size_bytes,
|
uint32_t timestamp_size_bytes,
|
||||||
|
uint32_t max_indirect_size_bytes,
|
||||||
u_trace_create_buffer create_buffer,
|
u_trace_create_buffer create_buffer,
|
||||||
u_trace_delete_buffer delete_buffer,
|
u_trace_delete_buffer delete_buffer,
|
||||||
u_trace_record_ts record_timestamp,
|
u_trace_record_ts record_timestamp,
|
||||||
u_trace_read_ts read_timestamp,
|
u_trace_read_ts read_timestamp,
|
||||||
|
u_trace_capture_data capture_data,
|
||||||
|
u_trace_get_data get_data,
|
||||||
u_trace_delete_flush_data delete_flush_data)
|
u_trace_delete_flush_data delete_flush_data)
|
||||||
{
|
{
|
||||||
u_trace_state_init();
|
u_trace_state_init();
|
||||||
@ -449,9 +469,12 @@ u_trace_context_init(struct u_trace_context *utctx,
|
|||||||
utctx->create_buffer = create_buffer;
|
utctx->create_buffer = create_buffer;
|
||||||
utctx->delete_buffer = delete_buffer;
|
utctx->delete_buffer = delete_buffer;
|
||||||
utctx->record_timestamp = record_timestamp;
|
utctx->record_timestamp = record_timestamp;
|
||||||
|
utctx->capture_data = capture_data;
|
||||||
|
utctx->get_data = get_data;
|
||||||
utctx->read_timestamp = read_timestamp;
|
utctx->read_timestamp = read_timestamp;
|
||||||
utctx->delete_flush_data = delete_flush_data;
|
utctx->delete_flush_data = delete_flush_data;
|
||||||
utctx->timestamp_size_bytes = timestamp_size_bytes;
|
utctx->timestamp_size_bytes = timestamp_size_bytes;
|
||||||
|
utctx->max_indirect_size_bytes = max_indirect_size_bytes;
|
||||||
|
|
||||||
utctx->last_time_ns = 0;
|
utctx->last_time_ns = 0;
|
||||||
utctx->first_time_ns = 0;
|
utctx->first_time_ns = 0;
|
||||||
@ -460,6 +483,8 @@ u_trace_context_init(struct u_trace_context *utctx,
|
|||||||
utctx->event_nr = 0;
|
utctx->event_nr = 0;
|
||||||
utctx->start_of_frame = true;
|
utctx->start_of_frame = true;
|
||||||
|
|
||||||
|
utctx->dummy_indirect_data = calloc(1, max_indirect_size_bytes);
|
||||||
|
|
||||||
list_inithead(&utctx->flushed_trace_chunks);
|
list_inithead(&utctx->flushed_trace_chunks);
|
||||||
|
|
||||||
if (utctx->enabled_traces & U_TRACE_TYPE_PRINT) {
|
if (utctx->enabled_traces & U_TRACE_TYPE_PRINT) {
|
||||||
@ -515,6 +540,8 @@ u_trace_context_fini(struct u_trace_context *utctx)
|
|||||||
fflush(utctx->out);
|
fflush(utctx->out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (utctx->dummy_indirect_data);
|
||||||
|
|
||||||
if (!utctx->queue.jobs)
|
if (!utctx->queue.jobs)
|
||||||
return;
|
return;
|
||||||
util_queue_finish(&utctx->queue);
|
util_queue_finish(&utctx->queue);
|
||||||
@ -614,14 +641,26 @@ process_chunk(void *job, void *gdata, int thread_index)
|
|||||||
delta = 0;
|
delta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void *indirect_data = NULL;
|
||||||
|
if (evt->tp->indirect_sz > 0) {
|
||||||
|
if (utctx->enabled_traces & U_TRACE_TYPE_INDIRECTS) {
|
||||||
|
indirect_data = utctx->get_data(utctx, chunk->indirects,
|
||||||
|
utctx->max_indirect_size_bytes * idx,
|
||||||
|
evt->tp->indirect_sz);
|
||||||
|
} else {
|
||||||
|
indirect_data = utctx->dummy_indirect_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (utctx->out) {
|
if (utctx->out) {
|
||||||
utctx->out_printer->event(utctx, chunk, evt, ns, delta);
|
utctx->out_printer->event(utctx, chunk, evt, ns, delta, indirect_data);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
if (evt->tp->perfetto &&
|
if (evt->tp->perfetto &&
|
||||||
(p_atomic_read_relaxed(&utctx->enabled_traces) &
|
(p_atomic_read_relaxed(&utctx->enabled_traces) &
|
||||||
U_TRACE_TYPE_PERFETTO_ACTIVE)) {
|
U_TRACE_TYPE_PERFETTO_ACTIVE)) {
|
||||||
evt->tp->perfetto(utctx->pctx, ns, evt->tp->tp_idx, chunk->flush_data, evt->payload);
|
evt->tp->perfetto(utctx->pctx, ns, evt->tp->tp_idx, chunk->flush_data,
|
||||||
|
evt->payload, indirect_data);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -782,6 +821,15 @@ u_trace_clone_append(struct u_trace_iterator begin_it,
|
|||||||
begin_it.ut->utctx->timestamp_size_bytes * to_chunk->num_traces,
|
begin_it.ut->utctx->timestamp_size_bytes * to_chunk->num_traces,
|
||||||
begin_it.ut->utctx->timestamp_size_bytes * to_copy);
|
begin_it.ut->utctx->timestamp_size_bytes * to_copy);
|
||||||
|
|
||||||
|
if (from_chunk->has_indirect) {
|
||||||
|
copy_buffer(begin_it.ut->utctx, cmdstream,
|
||||||
|
from_chunk->indirects,
|
||||||
|
begin_it.ut->utctx->max_indirect_size_bytes * from_idx,
|
||||||
|
to_chunk->indirects,
|
||||||
|
begin_it.ut->utctx->max_indirect_size_bytes * to_chunk->num_traces,
|
||||||
|
begin_it.ut->utctx->max_indirect_size_bytes * to_copy);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&to_chunk->traces[to_chunk->num_traces],
|
memcpy(&to_chunk->traces[to_chunk->num_traces],
|
||||||
&from_chunk->traces[from_idx],
|
&from_chunk->traces[from_idx],
|
||||||
to_copy * sizeof(struct u_trace_event));
|
to_copy * sizeof(struct u_trace_event));
|
||||||
@ -845,7 +893,10 @@ void *
|
|||||||
u_trace_appendv(struct u_trace *ut,
|
u_trace_appendv(struct u_trace *ut,
|
||||||
void *cs,
|
void *cs,
|
||||||
const struct u_tracepoint *tp,
|
const struct u_tracepoint *tp,
|
||||||
unsigned variable_sz)
|
unsigned variable_sz,
|
||||||
|
unsigned n_indirects,
|
||||||
|
const struct u_trace_address *addresses,
|
||||||
|
const uint8_t *indirect_sizes_B)
|
||||||
{
|
{
|
||||||
assert(tp->payload_sz == ALIGN_NPOT(tp->payload_sz, 8));
|
assert(tp->payload_sz == ALIGN_NPOT(tp->payload_sz, 8));
|
||||||
|
|
||||||
@ -865,6 +916,16 @@ u_trace_appendv(struct u_trace *ut,
|
|||||||
ut->utctx->timestamp_size_bytes * tp_idx,
|
ut->utctx->timestamp_size_bytes * tp_idx,
|
||||||
tp->flags);
|
tp->flags);
|
||||||
|
|
||||||
|
if (ut->utctx->enabled_traces & U_TRACE_TYPE_INDIRECTS) {
|
||||||
|
for (unsigned i = 0; i < n_indirects; i++) {
|
||||||
|
ut->utctx->capture_data(ut, cs, chunk->indirects,
|
||||||
|
ut->utctx->max_indirect_size_bytes * tp_idx,
|
||||||
|
addresses[i].bo, addresses[i].offset,
|
||||||
|
indirect_sizes_B[i]);
|
||||||
|
}
|
||||||
|
chunk->has_indirect |= n_indirects > 0;
|
||||||
|
}
|
||||||
|
|
||||||
chunk->traces[tp_idx] = (struct u_trace_event) {
|
chunk->traces[tp_idx] = (struct u_trace_event) {
|
||||||
.tp = tp,
|
.tp = tp,
|
||||||
.payload = payload,
|
.payload = payload,
|
||||||
|
@ -79,6 +79,20 @@ struct u_trace_printer;
|
|||||||
*/
|
*/
|
||||||
#define U_TRACE_NO_TIMESTAMP ((uint64_t) 0)
|
#define U_TRACE_NO_TIMESTAMP ((uint64_t) 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address representation
|
||||||
|
*/
|
||||||
|
struct u_trace_address {
|
||||||
|
/**
|
||||||
|
* Pointer to a buffer object
|
||||||
|
*/
|
||||||
|
void *bo;
|
||||||
|
/**
|
||||||
|
* Offset inside the buffer object or address of bo is NULL
|
||||||
|
*/
|
||||||
|
uint64_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Driver provided callback to create a buffer which will be read by
|
* Driver provided callback to create a buffer which will be read by
|
||||||
* u_trace_read_ts function.
|
* u_trace_read_ts function.
|
||||||
@ -107,6 +121,24 @@ typedef void (*u_trace_record_ts)(struct u_trace *ut,
|
|||||||
uint64_t offset_B,
|
uint64_t offset_B,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver provided callback to capture indirect data.
|
||||||
|
*/
|
||||||
|
typedef void (*u_trace_capture_data)(struct u_trace *ut,
|
||||||
|
void *cs,
|
||||||
|
void *dst_buffer,
|
||||||
|
uint64_t dst_offset_B,
|
||||||
|
void *src_buffer,
|
||||||
|
uint64_t src_offset_B,
|
||||||
|
uint32_t size_B);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver provided callback to read back previously recorded indirect data.
|
||||||
|
*/
|
||||||
|
typedef const void *(*u_trace_get_data)(struct u_trace_context *utctx,
|
||||||
|
void *buffer,
|
||||||
|
uint64_t offset_B,
|
||||||
|
uint32_t size_B);
|
||||||
/**
|
/**
|
||||||
* Driver provided callback to read back a previously recorded timestamp.
|
* Driver provided callback to read back a previously recorded timestamp.
|
||||||
* If necessary, this should block until the GPU has finished writing back
|
* If necessary, this should block until the GPU has finished writing back
|
||||||
@ -130,6 +162,18 @@ typedef uint64_t (*u_trace_read_ts)(struct u_trace_context *utctx,
|
|||||||
uint64_t offset_B,
|
uint64_t offset_B,
|
||||||
void *flush_data);
|
void *flush_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver provided callback to create a buffer which will be read by
|
||||||
|
* u_trace_read_ts function.
|
||||||
|
*/
|
||||||
|
typedef void *(*u_trace_copy_data)(struct u_trace *ut,
|
||||||
|
void *cs,
|
||||||
|
void *dst,
|
||||||
|
uint64_t dst_offset_B,
|
||||||
|
void *src,
|
||||||
|
uint64_t src_offset_B,
|
||||||
|
uint64_t size_B);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Driver provided callback to delete flush data.
|
* Driver provided callback to delete flush data.
|
||||||
*/
|
*/
|
||||||
@ -142,6 +186,7 @@ enum u_trace_type {
|
|||||||
U_TRACE_TYPE_PERFETTO_ACTIVE = 1u << 2,
|
U_TRACE_TYPE_PERFETTO_ACTIVE = 1u << 2,
|
||||||
U_TRACE_TYPE_PERFETTO_ENV = 1u << 3,
|
U_TRACE_TYPE_PERFETTO_ENV = 1u << 3,
|
||||||
U_TRACE_TYPE_MARKERS = 1u << 4,
|
U_TRACE_TYPE_MARKERS = 1u << 4,
|
||||||
|
U_TRACE_TYPE_INDIRECTS = 1u << 5,
|
||||||
|
|
||||||
U_TRACE_TYPE_PRINT_JSON = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_JSON,
|
U_TRACE_TYPE_PRINT_JSON = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_JSON,
|
||||||
U_TRACE_TYPE_PERFETTO =
|
U_TRACE_TYPE_PERFETTO =
|
||||||
@ -170,11 +215,14 @@ struct u_trace_context {
|
|||||||
|
|
||||||
u_trace_create_buffer create_buffer;
|
u_trace_create_buffer create_buffer;
|
||||||
u_trace_delete_buffer delete_buffer;
|
u_trace_delete_buffer delete_buffer;
|
||||||
|
u_trace_capture_data capture_data;
|
||||||
|
u_trace_get_data get_data;
|
||||||
u_trace_record_ts record_timestamp;
|
u_trace_record_ts record_timestamp;
|
||||||
u_trace_read_ts read_timestamp;
|
u_trace_read_ts read_timestamp;
|
||||||
u_trace_delete_flush_data delete_flush_data;
|
u_trace_delete_flush_data delete_flush_data;
|
||||||
|
|
||||||
uint64_t timestamp_size_bytes;
|
uint64_t timestamp_size_bytes;
|
||||||
|
uint64_t max_indirect_size_bytes;
|
||||||
|
|
||||||
FILE *out;
|
FILE *out;
|
||||||
struct u_trace_printer *out_printer;
|
struct u_trace_printer *out_printer;
|
||||||
@ -201,6 +249,8 @@ struct u_trace_context {
|
|||||||
uint32_t event_nr;
|
uint32_t event_nr;
|
||||||
bool start_of_frame;
|
bool start_of_frame;
|
||||||
|
|
||||||
|
void *dummy_indirect_data;
|
||||||
|
|
||||||
/* list of unprocessed trace chunks in fifo order: */
|
/* list of unprocessed trace chunks in fifo order: */
|
||||||
struct list_head flushed_trace_chunks;
|
struct list_head flushed_trace_chunks;
|
||||||
};
|
};
|
||||||
@ -228,10 +278,13 @@ struct u_trace {
|
|||||||
void u_trace_context_init(struct u_trace_context *utctx,
|
void u_trace_context_init(struct u_trace_context *utctx,
|
||||||
void *pctx,
|
void *pctx,
|
||||||
uint32_t timestamp_size_bytes,
|
uint32_t timestamp_size_bytes,
|
||||||
|
uint32_t max_indirect_size_bytes,
|
||||||
u_trace_create_buffer create_buffer,
|
u_trace_create_buffer create_buffer,
|
||||||
u_trace_delete_buffer delete_buffer,
|
u_trace_delete_buffer delete_buffer,
|
||||||
u_trace_record_ts record_timestamp,
|
u_trace_record_ts record_timestamp,
|
||||||
u_trace_read_ts read_timestamp,
|
u_trace_read_ts read_timestamp,
|
||||||
|
u_trace_capture_data capture_data,
|
||||||
|
u_trace_get_data get_data,
|
||||||
u_trace_delete_flush_data delete_flush_data);
|
u_trace_delete_flush_data delete_flush_data);
|
||||||
void u_trace_context_fini(struct u_trace_context *utctx);
|
void u_trace_context_fini(struct u_trace_context *utctx);
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ class Tracepoint(object):
|
|||||||
def needs_storage(a):
|
def needs_storage(a):
|
||||||
if a.c_format is None:
|
if a.c_format is None:
|
||||||
return False
|
return False
|
||||||
|
if a.is_indirect:
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -81,6 +83,14 @@ class Tracepoint(object):
|
|||||||
self.has_variable_arg = True
|
self.has_variable_arg = True
|
||||||
break
|
break
|
||||||
self.tp_print_custom = tp_print
|
self.tp_print_custom = tp_print
|
||||||
|
|
||||||
|
# Compute the offset of each indirect argument
|
||||||
|
self.indirect_args = [x for x in args if x.is_indirect]
|
||||||
|
indirect_sizes = []
|
||||||
|
for indirect in self.indirect_args:
|
||||||
|
indirect.indirect_offset = ' + '.join(indirect_sizes) if len(indirect_sizes) > 0 else 0
|
||||||
|
indirect_sizes.append(f"sizeof({indirect.type}")
|
||||||
|
|
||||||
self.tp_perfetto = tp_perfetto
|
self.tp_perfetto = tp_perfetto
|
||||||
self.tp_markers = tp_markers
|
self.tp_markers = tp_markers
|
||||||
self.tp_flags = tp_flags
|
self.tp_flags = tp_flags
|
||||||
@ -105,7 +115,7 @@ class Tracepoint(object):
|
|||||||
class TracepointArgStruct():
|
class TracepointArgStruct():
|
||||||
"""Represents struct that is being passed as an argument
|
"""Represents struct that is being passed as an argument
|
||||||
"""
|
"""
|
||||||
def __init__(self, type, var, c_format=None, fields=[]):
|
def __init__(self, type, var, c_format=None, fields=[], is_indirect=False):
|
||||||
"""Parameters:
|
"""Parameters:
|
||||||
|
|
||||||
- type: argument's C type.
|
- type: argument's C type.
|
||||||
@ -117,17 +127,25 @@ class TracepointArgStruct():
|
|||||||
self.type = type
|
self.type = type
|
||||||
self.var = var
|
self.var = var
|
||||||
self.name = var
|
self.name = var
|
||||||
|
self.is_indirect = is_indirect
|
||||||
|
self.indirect_offset = 0
|
||||||
self.is_struct = True
|
self.is_struct = True
|
||||||
self.c_format = c_format
|
self.c_format = c_format
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
self.to_prim_type = None
|
self.to_prim_type = None
|
||||||
|
|
||||||
self.func_param = f"{self.type} {self.var}"
|
if self.is_indirect:
|
||||||
|
self.func_param = f"struct u_trace_address {self.var}"
|
||||||
|
else:
|
||||||
|
self.func_param = f"{self.type} {self.var}"
|
||||||
|
|
||||||
def value_expr(self, entry_name):
|
def value_expr(self, entry_name):
|
||||||
ret = None
|
ret = None
|
||||||
if self.is_struct:
|
if self.is_struct:
|
||||||
ret = ", ".join([f"{entry_name}->{self.name}.{f}" for f in self.fields])
|
if self.is_indirect:
|
||||||
|
ret = ", ".join([f"__{self.name}->{f}" for f in self.fields])
|
||||||
|
else:
|
||||||
|
ret = ", ".join([f"{entry_name}->{self.name}.{f}" for f in self.fields])
|
||||||
else:
|
else:
|
||||||
ret = f"{entry_name}->{self.name}"
|
ret = f"{entry_name}->{self.name}"
|
||||||
return ret
|
return ret
|
||||||
@ -136,7 +154,7 @@ class TracepointArg(object):
|
|||||||
"""Class that represents either an argument being passed or a field in a struct
|
"""Class that represents either an argument being passed or a field in a struct
|
||||||
"""
|
"""
|
||||||
def __init__(self, type, var, c_format=None, name=None, to_prim_type=None,
|
def __init__(self, type, var, c_format=None, name=None, to_prim_type=None,
|
||||||
length_arg=None, copy_func=None):
|
length_arg=None, copy_func=None, is_indirect=False):
|
||||||
"""Parameters:
|
"""Parameters:
|
||||||
|
|
||||||
- type: argument's C type.
|
- type: argument's C type.
|
||||||
@ -162,8 +180,12 @@ class TracepointArg(object):
|
|||||||
self.copy_func = copy_func
|
self.copy_func = copy_func
|
||||||
|
|
||||||
self.is_struct = False
|
self.is_struct = False
|
||||||
|
self.is_indirect = is_indirect
|
||||||
|
self.indirect_offset = 0
|
||||||
|
|
||||||
if self.type == "str":
|
if self.is_indirect:
|
||||||
|
pass
|
||||||
|
elif self.type == "str":
|
||||||
if self.length_arg and self.length_arg.isdigit():
|
if self.length_arg and self.length_arg.isdigit():
|
||||||
self.struct_member = f"char {self.name}[{length_arg} + 1]"
|
self.struct_member = f"char {self.name}[{length_arg} + 1]"
|
||||||
else:
|
else:
|
||||||
@ -171,13 +193,18 @@ class TracepointArg(object):
|
|||||||
else:
|
else:
|
||||||
self.struct_member = f"{self.type} {self.name}"
|
self.struct_member = f"{self.type} {self.name}"
|
||||||
|
|
||||||
if self.type == "str":
|
if self.is_indirect:
|
||||||
|
self.func_param = f"struct u_trace_address {self.var}"
|
||||||
|
elif self.type == "str":
|
||||||
self.func_param = f"const char *{self.var}"
|
self.func_param = f"const char *{self.var}"
|
||||||
else:
|
else:
|
||||||
self.func_param = f"{self.type} {self.var}"
|
self.func_param = f"{self.type} {self.var}"
|
||||||
|
|
||||||
def value_expr(self, entry_name):
|
def value_expr(self, entry_name):
|
||||||
ret = f"{entry_name}->{self.name}"
|
if self.is_indirect:
|
||||||
|
ret = f"*__{self.name}"
|
||||||
|
else:
|
||||||
|
ret = f"{entry_name}->{self.name}"
|
||||||
if not self.is_struct and self.to_prim_type:
|
if not self.is_struct and self.to_prim_type:
|
||||||
ret = self.to_prim_type.format(ret)
|
ret = self.to_prim_type.format(ret)
|
||||||
return ret
|
return ret
|
||||||
@ -298,7 +325,8 @@ void ${trace.tp_perfetto}(
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const struct trace_${trace_name} *payload);
|
const struct trace_${trace_name} *payload,
|
||||||
|
const void *indirect_data);
|
||||||
#endif
|
#endif
|
||||||
% endif
|
% endif
|
||||||
void __trace_${trace_name}(
|
void __trace_${trace_name}(
|
||||||
@ -416,11 +444,14 @@ ${trace_toggle_name}_config_variable(void)
|
|||||||
* ${trace_name}
|
* ${trace_name}
|
||||||
*/
|
*/
|
||||||
% if trace.can_generate_print():
|
% if trace.can_generate_print():
|
||||||
static void __print_${trace_name}(FILE *out, const void *arg) {
|
static void __print_${trace_name}(FILE *out, const void *arg, const void *indirect) {
|
||||||
% if len(trace.tp_struct) > 0:
|
% if len(trace.tp_struct) > 0:
|
||||||
const struct trace_${trace_name} *__entry =
|
const struct trace_${trace_name} *__entry =
|
||||||
(const struct trace_${trace_name} *)arg;
|
(const struct trace_${trace_name} *)arg;
|
||||||
% endif
|
% endif
|
||||||
|
% for arg in trace.indirect_args:
|
||||||
|
const ${arg.type} *__${arg.name} = (const ${arg.type} *) ((char *)indirect + ${arg.indirect_offset});
|
||||||
|
% endfor
|
||||||
% if trace.tp_print_custom is not None:
|
% if trace.tp_print_custom is not None:
|
||||||
fprintf(out, "${trace.tp_print_custom[0]}\\n"
|
fprintf(out, "${trace.tp_print_custom[0]}\\n"
|
||||||
% for arg in trace.tp_print_custom[1:]:
|
% for arg in trace.tp_print_custom[1:]:
|
||||||
@ -439,11 +470,14 @@ static void __print_${trace_name}(FILE *out, const void *arg) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __print_json_${trace_name}(FILE *out, const void *arg) {
|
static void __print_json_${trace_name}(FILE *out, const void *arg, const void *indirect) {
|
||||||
% if len(trace.tp_struct) > 0:
|
% if len(trace.tp_struct) > 0:
|
||||||
const struct trace_${trace_name} *__entry =
|
const struct trace_${trace_name} *__entry =
|
||||||
(const struct trace_${trace_name} *)arg;
|
(const struct trace_${trace_name} *)arg;
|
||||||
% endif
|
% endif
|
||||||
|
% for arg in trace.indirect_args:
|
||||||
|
const ${arg.type} *__${arg.var} = (const ${arg.type} *) ((char *)indirect + ${arg.indirect_offset});
|
||||||
|
% endfor
|
||||||
% if trace.tp_print_custom is not None:
|
% if trace.tp_print_custom is not None:
|
||||||
fprintf(out, "\\"unstructured\\": \\"${trace.tp_print_custom[0]}\\""
|
fprintf(out, "\\"unstructured\\": \\"${trace.tp_print_custom[0]}\\""
|
||||||
% for arg in trace.tp_print_custom[1:]:
|
% for arg in trace.tp_print_custom[1:]:
|
||||||
@ -475,26 +509,35 @@ __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) {
|
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}("
|
${trace.tp_markers}(utctx, cs, "${trace_name}("
|
||||||
% for idx,arg in enumerate(trace.tp_print):
|
% for idx,arg in enumerate(trace.tp_print):
|
||||||
|
% if not arg.is_indirect:
|
||||||
"${"," if idx != 0 else ""}${arg.name}=${arg.c_format}"
|
"${"," if idx != 0 else ""}${arg.name}=${arg.c_format}"
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
")"
|
")"
|
||||||
% for arg in trace.tp_print:
|
% for arg in trace.tp_print:
|
||||||
|
% if not arg.is_indirect:
|
||||||
,${arg.value_expr('entry')}
|
,${arg.value_expr('entry')}
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
% endif
|
% endif
|
||||||
static const struct u_tracepoint __tp_${trace_name} = {
|
static const struct u_tracepoint __tp_${trace_name} = {
|
||||||
ALIGN_POT(sizeof(struct trace_${trace_name}), 8), /* keep size 64b aligned */
|
|
||||||
"${trace_name}",
|
"${trace_name}",
|
||||||
|
ALIGN_POT(sizeof(struct trace_${trace_name}), 8), /* keep size 64b aligned */
|
||||||
|
0
|
||||||
|
% for arg in trace.indirect_args:
|
||||||
|
+ sizeof(${arg.type})
|
||||||
|
% endfor
|
||||||
|
,
|
||||||
${0 if len(trace.tp_flags) == 0 else " | ".join(trace.tp_flags)},
|
${0 if len(trace.tp_flags) == 0 else " | ".join(trace.tp_flags)},
|
||||||
${index},
|
${index},
|
||||||
__print_${trace_name},
|
__print_${trace_name},
|
||||||
__print_json_${trace_name},
|
__print_json_${trace_name},
|
||||||
% if trace.tp_perfetto is not None:
|
% if trace.tp_perfetto is not None:
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
(void (*)(void *pctx, uint64_t, uint16_t, const void *, const void *))${trace.tp_perfetto},
|
(void (*)(void *pctx, uint64_t, uint16_t, const void *, const void *, const void *))${trace.tp_perfetto},
|
||||||
#endif
|
#endif
|
||||||
% endif
|
% endif
|
||||||
};
|
};
|
||||||
@ -509,9 +552,20 @@ void __trace_${trace_name}(
|
|||||||
% endfor
|
% endfor
|
||||||
) {
|
) {
|
||||||
struct trace_${trace_name} entry;
|
struct trace_${trace_name} entry;
|
||||||
|
% if len(trace.indirect_args) > 0:
|
||||||
|
struct u_trace_address indirects[] = {
|
||||||
|
% for arg in trace.indirect_args:
|
||||||
|
${arg.var},
|
||||||
|
% endfor
|
||||||
|
};
|
||||||
|
uint8_t indirect_sizes[] = {
|
||||||
|
% for arg in trace.indirect_args:
|
||||||
|
sizeof(${arg.type}),
|
||||||
|
% endfor
|
||||||
|
};
|
||||||
|
% endif
|
||||||
UNUSED struct trace_${trace_name} *__entry =
|
UNUSED struct trace_${trace_name} *__entry =
|
||||||
enabled_traces & U_TRACE_TYPE_REQUIRE_QUEUING ?
|
enabled_traces & U_TRACE_TYPE_REQUIRE_QUEUING ?
|
||||||
% if trace.has_variable_arg:
|
|
||||||
(struct trace_${trace_name} *)u_trace_appendv(ut, ${"cs," if trace.need_cs_param else "NULL,"} &__tp_${trace_name},
|
(struct trace_${trace_name} *)u_trace_appendv(ut, ${"cs," if trace.need_cs_param else "NULL,"} &__tp_${trace_name},
|
||||||
0
|
0
|
||||||
% for arg in trace.tp_struct:
|
% for arg in trace.tp_struct:
|
||||||
@ -519,10 +573,13 @@ void __trace_${trace_name}(
|
|||||||
+ ${arg.length_arg}
|
+ ${arg.length_arg}
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
|
,
|
||||||
|
% if len(trace.indirect_args) > 0:
|
||||||
|
ARRAY_SIZE(indirects), indirects, indirect_sizes
|
||||||
|
% else:
|
||||||
|
0, NULL, NULL
|
||||||
|
% endif
|
||||||
) :
|
) :
|
||||||
% else:
|
|
||||||
(struct trace_${trace_name} *)u_trace_append(ut, ${"cs," if trace.need_cs_param else "NULL,"} &__tp_${trace_name}) :
|
|
||||||
% endif
|
|
||||||
&entry;
|
&entry;
|
||||||
% for arg in trace.tp_struct:
|
% for arg in trace.tp_struct:
|
||||||
% if arg.copy_func is None:
|
% if arg.copy_func is None:
|
||||||
@ -625,7 +682,8 @@ UNUSED static const char *${basename}_names[] = {
|
|||||||
% for trace_name, trace in TRACEPOINTS.items():
|
% for trace_name, trace in TRACEPOINTS.items():
|
||||||
static void UNUSED
|
static void UNUSED
|
||||||
trace_payload_as_extra_${trace_name}(perfetto::protos::pbzero::GpuRenderStageEvent *event,
|
trace_payload_as_extra_${trace_name}(perfetto::protos::pbzero::GpuRenderStageEvent *event,
|
||||||
const struct trace_${trace_name} *payload)
|
const struct trace_${trace_name} *payload,
|
||||||
|
const void *indirect_data)
|
||||||
{
|
{
|
||||||
% if trace.tp_perfetto is not None and len(trace.tp_print) > 0:
|
% if trace.tp_perfetto is not None and len(trace.tp_print) > 0:
|
||||||
char buf[128];
|
char buf[128];
|
||||||
@ -635,6 +693,9 @@ trace_payload_as_extra_${trace_name}(perfetto::protos::pbzero::GpuRenderStageEve
|
|||||||
auto data = event->add_extra_data();
|
auto data = event->add_extra_data();
|
||||||
data->set_name("${arg.name}");
|
data->set_name("${arg.name}");
|
||||||
|
|
||||||
|
% if arg.is_indirect:
|
||||||
|
const ${arg.type}* __${arg.var} = (const ${arg.type}*)((uint8_t *)indirect_data + ${arg.indirect_offset});
|
||||||
|
% endif
|
||||||
sprintf(buf, "${arg.c_format}", ${arg.value_expr("payload")});
|
sprintf(buf, "${arg.c_format}", ${arg.value_expr("payload")});
|
||||||
|
|
||||||
data->set_value(buf);
|
data->set_value(buf);
|
||||||
|
@ -43,8 +43,15 @@ extern "C" {
|
|||||||
* Tracepoint descriptor.
|
* Tracepoint descriptor.
|
||||||
*/
|
*/
|
||||||
struct u_tracepoint {
|
struct u_tracepoint {
|
||||||
unsigned payload_sz;
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
/**
|
||||||
|
* Size of the CPU data associated with this tracepoint.
|
||||||
|
*/
|
||||||
|
uint16_t payload_sz;
|
||||||
|
/**
|
||||||
|
* Size of the GPU data associated with this tracepoint.
|
||||||
|
*/
|
||||||
|
uint16_t indirect_sz;
|
||||||
/**
|
/**
|
||||||
* A bitfield of driver agnostic flags
|
* A bitfield of driver agnostic flags
|
||||||
*/
|
*/
|
||||||
@ -56,8 +63,8 @@ struct u_tracepoint {
|
|||||||
* to event->set_stage_iid().
|
* to event->set_stage_iid().
|
||||||
*/
|
*/
|
||||||
uint16_t tp_idx;
|
uint16_t tp_idx;
|
||||||
void (*print)(FILE *out, const void *payload);
|
void (*print)(FILE *out, const void *payload, const void *indirect);
|
||||||
void (*print_json)(FILE *out, const void *payload);
|
void (*print_json)(FILE *out, const void *payload, const void *indirect);
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
/**
|
/**
|
||||||
* Callback to emit a perfetto event, such as render-stage trace
|
* Callback to emit a perfetto event, such as render-stage trace
|
||||||
@ -66,7 +73,8 @@ struct u_tracepoint {
|
|||||||
uint64_t ts_ns,
|
uint64_t ts_ns,
|
||||||
uint16_t tp_idx,
|
uint16_t tp_idx,
|
||||||
const void *flush_data,
|
const void *flush_data,
|
||||||
const void *payload);
|
const void *payload,
|
||||||
|
const void *indirect);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,7 +85,10 @@ struct u_tracepoint {
|
|||||||
void *u_trace_appendv(struct u_trace *ut,
|
void *u_trace_appendv(struct u_trace *ut,
|
||||||
void *cs,
|
void *cs,
|
||||||
const struct u_tracepoint *tp,
|
const struct u_tracepoint *tp,
|
||||||
unsigned variable_sz);
|
unsigned variable_sz,
|
||||||
|
unsigned n_indirects,
|
||||||
|
const struct u_trace_address *addresses,
|
||||||
|
const uint8_t *indirect_sizes_B);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a trace event, returning pointer to buffer of tp->payload_sz
|
* Append a trace event, returning pointer to buffer of tp->payload_sz
|
||||||
@ -87,7 +98,7 @@ void *u_trace_appendv(struct u_trace *ut,
|
|||||||
static inline void *
|
static inline void *
|
||||||
u_trace_append(struct u_trace *ut, void *cs, const struct u_tracepoint *tp)
|
u_trace_append(struct u_trace *ut, void *cs, const struct u_tracepoint *tp)
|
||||||
{
|
{
|
||||||
return u_trace_appendv(ut, cs, tp, 0);
|
return u_trace_appendv(ut, cs, tp, 0, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -11,7 +11,8 @@ static int
|
|||||||
test_thread(void *_state)
|
test_thread(void *_state)
|
||||||
{
|
{
|
||||||
struct u_trace_context ctx = {};
|
struct u_trace_context ctx = {};
|
||||||
u_trace_context_init(&ctx, NULL, NULL, NULL, NULL, NULL, NULL);
|
u_trace_context_init(&ctx, NULL, 8, 0, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
u_trace_context_fini(&ctx);
|
u_trace_context_fini(&ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user