diff options
author | Rob Clark <[email protected]> | 2020-04-10 08:27:54 -0700 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-04-10 19:29:54 +0000 |
commit | 7aa6720ba4ea8dc107c7b363bcb2a1811a25dc71 (patch) | |
tree | 99ef7b41f1ab1d6625286a3a8f14c503f7f9249d /src/gallium/drivers/freedreno/freedreno_log.c | |
parent | 7aa55f5acbcf7fa472805fd2c155a5cc0b9cb2a8 (diff) |
freedreno/log: better decoding for multiple chunks per batch
For larger render targets or smaller GMEM size, we could end up needing
multiple chunks of tracepoints per batch. But we still want to decode
the traces as single batch. So we need a bit of a state across
process_chunk() calls to accumulate timestamp information.
Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4510>
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_log.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_log.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_log.c b/src/gallium/drivers/freedreno/freedreno_log.c index 81160f86a92..8970e40189e 100644 --- a/src/gallium/drivers/freedreno/freedreno_log.c +++ b/src/gallium/drivers/freedreno/freedreno_log.c @@ -68,7 +68,8 @@ struct fd_log_chunk { /* list of recorded 64b timestamps */ struct fd_bo *timestamps_bo; - bool eof; + bool last; /* this chunk is last in submit */ + bool eof; /* this chunk is last in frame */ uint32_t *ring_cur; }; @@ -83,6 +84,10 @@ get_chunk(struct fd_batch *batch) struct fd_log_chunk, node); if (chunk->num_msgs < msgs_per_chunk) return chunk; + /* we need to expand to add another chunk to the batch, so + * the current one is no longer the last one of the batch: + */ + chunk->last = false; } /* .. if not, then create a new one: */ @@ -90,6 +95,7 @@ get_chunk(struct fd_batch *batch) chunk->msg_fifo = u_fifo_create(msgs_per_chunk); chunk->timestamps_bo = fd_bo_new(batch->ctx->screen->dev, bo_size, DRM_FREEDRENO_GEM_TYPE_KMEM, "timestamps"); + chunk->last = true; list_addtail(&chunk->node, &batch->log_chunks); @@ -106,14 +112,22 @@ free_chunk(struct fd_log_chunk *chunk) free(chunk); } +/* state to accumulate time across N chunks associated with a single batch: */ +struct times { + uint64_t last_time_ns; + uint64_t first_time_ns; +}; + static void -process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk) +process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk, struct times *t) { - fprintf(ctx->log_out, "+----- TS -----+ +----- NS -----+ +-- Δ --+ +----- MSG -----\n"); + /* For first chunk of batch, accumulated times will be zerod: */ + if (!t->last_time_ns) { + fprintf(ctx->log_out, + "+----- TS -----+ +----- NS -----+ +-- Δ --+ +----- MSG -----\n"); + } uint64_t *timestamps = fd_bo_map(chunk->timestamps_bo); - uint64_t last_time_ns = 0; - uint64_t first_time_ns = 0; unsigned n = 0; char *msg; @@ -122,26 +136,31 @@ process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk) uint64_t ns = ctx->ts_to_ns(ts); int32_t delta; - if (!first_time_ns) - first_time_ns = ns; + if (!t->first_time_ns) + t->first_time_ns = ns; if (ns) { - delta = last_time_ns ? ns - last_time_ns : 0; - last_time_ns = ns; + delta = t->last_time_ns ? ns - t->last_time_ns : 0; + t->last_time_ns = ns; } else { /* we skipped recording the timestamp, so it should be * the same as last msg: */ - ns = last_time_ns; + ns = t->last_time_ns; delta = 0; } - fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n", ts, ns, delta, msg); + fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n", + ts, ns, delta, msg); free(msg); } - fprintf(ctx->log_out, "ELAPSED: %"PRIu64" ns\n", last_time_ns - first_time_ns); + if (chunk->last) { + fprintf(ctx->log_out, "ELAPSED: %"PRIu64" ns\n", + t->last_time_ns - t->first_time_ns); + memset(t, 0, sizeof(*t)); + } if (chunk->eof) fprintf(ctx->log_out, "END OF FRAME %u\n", ctx->frame_nr++); @@ -150,6 +169,8 @@ process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk) void fd_log_process(struct fd_context *ctx, bool wait) { + struct times times = {0}; + while (!list_is_empty(&ctx->log_chunks)) { struct fd_log_chunk *chunk = list_first_entry(&ctx->log_chunks, struct fd_log_chunk, node); @@ -162,10 +183,17 @@ fd_log_process(struct fd_context *ctx, bool wait) if (ret) break; - process_chunk(ctx, chunk); + process_chunk(ctx, chunk, ×); free_chunk(chunk); } + /* We expect that the last processed chunk was the last in it's + * batch, which should reset the times: + */ + if (times.last_time_ns) { + fprintf(ctx->log_out, "WARNING: last processed chunk not last in batch?"); + } + fflush(ctx->log_out); } |