diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c index 68539c44cb0..ee0c7986ea5 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.c @@ -30,7 +30,6 @@ #include "freedreno_blitter.h" #include "freedreno_fence.h" -#include "freedreno_log.h" #include "freedreno_resource.h" #include "freedreno_tracepoints.h" @@ -820,8 +819,6 @@ handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info) fd_batch_set_stage(batch, FD_STAGE_BLIT); - fd_log_stream(batch, stream, util_dump_blit_info(stream, info)); - emit_setup(batch); trace_start_blit(&batch->trace, info->src.resource->target, info->dst.resource->target); @@ -830,16 +827,12 @@ handle_rgba_blit(struct fd_context *ctx, const struct pipe_blit_info *info) (info->dst.resource->target == PIPE_BUFFER)) { assert(fd_resource(info->src.resource)->layout.tile_mode == TILE6_LINEAR); assert(fd_resource(info->dst.resource)->layout.tile_mode == TILE6_LINEAR); - fd_log(batch, "START BLIT (BUFFER)"); emit_blit_buffer(ctx, batch->draw, info); - fd_log(batch, "END BLIT (BUFFER)"); } else { /* I don't *think* we need to handle blits between buffer <-> !buffer */ debug_assert(info->src.resource->target != PIPE_BUFFER); debug_assert(info->dst.resource->target != PIPE_BUFFER); - fd_log(batch, "START BLIT (TEXTURE)"); emit_blit_texture(ctx, batch->draw, info); - fd_log(batch, "END BLIT (TEXTURE)"); } trace_end_blit(&batch->trace); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_compute.c b/src/gallium/drivers/freedreno/a6xx/fd6_compute.c index 27146a4fe06..39528f19dc7 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_compute.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_compute.c @@ -28,7 +28,6 @@ #include "util/u_dump.h" #include "u_tracepoints.h" -#include "freedreno_log.h" #include "freedreno_resource.h" #include "freedreno_tracepoints.h" @@ -197,9 +196,6 @@ fd6_launch_grid(struct fd_context *ctx, const struct pipe_grid_info *info) trace_grid_info(&ctx->batch->trace, info); trace_start_compute(&ctx->batch->trace); - fd_log(ctx->batch, "COMPUTE: START"); - fd_log_stream(ctx->batch, stream, util_dump_grid_info(stream, info)); - if (info->indirect) { struct fd_resource *rsc = fd_resource(info->indirect); @@ -219,12 +215,9 @@ fd6_launch_grid(struct fd_context *ctx, const struct pipe_grid_info *info) trace_end_compute(&ctx->batch->trace); - fd_log(ctx->batch, "COMPUTE: END"); OUT_WFI5(ring); - fd_log(ctx->batch, ".."); fd6_cache_flush(ctx->batch, ring); - fd_log(ctx->batch, ".."); } void diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 1da9e06183d..f552ba009dd 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -32,7 +32,6 @@ #include "util/format/u_format.h" #include "util/u_viewport.h" -#include "freedreno_log.h" #include "freedreno_resource.h" #include "freedreno_state.h" #include "freedreno_tracepoints.h" @@ -1176,7 +1175,6 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring) //struct fd_context *ctx = batch->ctx; if (!batch->nondraw) { - fd_log(batch, "START RESTORE"); trace_start_state_restore(&batch->trace); } @@ -1296,7 +1294,6 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring) if (!batch->nondraw) { trace_end_state_restore(&batch->trace); - fd_log(batch, "END RESTORE"); } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 42271d92220..c7105b05274 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -34,7 +34,6 @@ #include "util/format/u_format.h" #include "freedreno_draw.h" -#include "freedreno_log.h" #include "freedreno_state.h" #include "freedreno_resource.h" #include "freedreno_tracepoints.h" @@ -577,11 +576,9 @@ emit_binning_pass(struct fd_batch *batch) A6XX_SP_TP_WINDOW_OFFSET_Y(0)); /* emit IB to binning drawcmds: */ - fd_log(batch, "GMEM: START BINNING IB"); trace_start_binning_ib(&batch->trace); fd6_emit_ib(ring, batch->draw); trace_end_binning_ib(&batch->trace); - fd_log(batch, "GMEM: END BINNING IB"); fd_reset_wfi(batch); @@ -601,11 +598,9 @@ emit_binning_pass(struct fd_batch *batch) OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); - fd_log(batch, "START VSC OVERFLOW TEST"); trace_start_vsc_overflow_test(&batch->trace); emit_vsc_overflow_test(batch); trace_end_vsc_overflow_test(&batch->trace); - fd_log(batch, "END VSC OVERFLOW TEST"); OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); OUT_RING(ring, 0x0); @@ -662,11 +657,9 @@ fd6_emit_tile_init(struct fd_batch *batch) fd6_emit_lrz_flush(ring); if (batch->prologue) { - fd_log(batch, "START PROLOGUE"); trace_start_prologue(&batch->trace); fd6_emit_ib(ring, batch->prologue); trace_end_prologue(&batch->trace); - fd_log(batch, "END PROLOGUE"); } fd6_cache_inv(batch, ring); @@ -1125,7 +1118,6 @@ fd6_emit_tile_renderprep(struct fd_batch *batch, const struct fd_tile *tile) if (!batch->tile_setup) return; - fd_log(batch, "TILE: START CLEAR/RESTORE"); trace_start_clear_restore(&batch->trace, batch->fast_cleared); if (batch->fast_cleared || !use_hw_binning(batch)) { fd6_emit_ib(batch->gmem, batch->tile_setup); @@ -1133,7 +1125,6 @@ fd6_emit_tile_renderprep(struct fd_batch *batch, const struct fd_tile *tile) emit_conditional_ib(batch, tile, batch->tile_setup); } trace_end_clear_restore(&batch->trace); - fd_log(batch, "TILE: END CLEAR/RESTORE"); } static void @@ -1253,7 +1244,6 @@ fd6_emit_tile_gmem2mem(struct fd_batch *batch, const struct fd_tile *tile) OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE)); emit_marker6(ring, 7); - fd_log(batch, "TILE: START RESOLVE"); trace_start_resolve(&batch->trace); if (batch->fast_cleared || !use_hw_binning(batch)) { fd6_emit_ib(batch->gmem, batch->tile_fini); @@ -1261,7 +1251,6 @@ fd6_emit_tile_gmem2mem(struct fd_batch *batch, const struct fd_tile *tile) emit_conditional_ib(batch, tile, batch->tile_fini); } trace_end_resolve(&batch->trace); - fd_log(batch, "TILE: END RESOLVE"); } static void @@ -1373,13 +1362,11 @@ fd6_emit_sysmem_prep(struct fd_batch *batch) if (batch->prologue) { if (!batch->nondraw) { - fd_log(batch, "START PROLOGUE"); trace_start_prologue(&batch->trace); } fd6_emit_ib(ring, batch->prologue); if (!batch->nondraw) { trace_end_prologue(&batch->trace); - fd_log(batch, "END PROLOGUE"); } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_query.c b/src/gallium/drivers/freedreno/a6xx/fd6_query.c index 2e13fa61ce3..21c4b0e31a9 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_query.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_query.c @@ -201,7 +201,7 @@ timestamp_pause(struct fd_acc_query *aq, struct fd_batch *batch) /* We captured a timestamp in timestamp_resume(), nothing to do here. */ } -/* timestamp logging for fd_log(): */ +/* timestamp logging for u_trace: */ static void record_timestamp(struct fd_ringbuffer *ring, struct fd_bo *bo, unsigned offset) { diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c index 7526b913f61..e2e3d975cdd 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.c +++ b/src/gallium/drivers/freedreno/freedreno_batch.c @@ -110,8 +110,6 @@ batch_init(struct fd_batch *batch) util_dynarray_init(&batch->samples, NULL); - list_inithead(&batch->log_chunks); - u_trace_init(&batch->trace, &ctx->trace_context); batch->last_timestamp_cmd = NULL; } @@ -224,8 +222,6 @@ batch_fini(struct fd_batch *batch) } util_dynarray_fini(&batch->samples); - assert(list_is_empty(&batch->log_chunks)); - u_trace_fini(&batch->trace); } diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index 275888bc1a7..64b944d65e0 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -246,8 +246,6 @@ struct fd_batch { uint32_t tessparam_size; struct fd_ringbuffer *tess_addrs_constobj; - - struct list_head log_chunks; /* list of unflushed log chunks in fifo order */ }; struct fd_batch * fd_batch_create(struct fd_context *ctx, bool nondraw); diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 84dfbc89a9f..5e0d4e226fc 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -28,7 +28,6 @@ #include "freedreno_blitter.h" #include "freedreno_draw.h" #include "freedreno_fence.h" -#include "freedreno_log.h" #include "freedreno_program.h" #include "freedreno_resource.h" #include "freedreno_texture.h" @@ -39,12 +38,6 @@ #include "freedreno_util.h" #include "util/u_upload_mgr.h" -#if DETECT_OS_ANDROID -#include "util/u_process.h" -#include -#include -#endif - static void fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep, unsigned flags) @@ -113,9 +106,6 @@ out: fd_batch_reference(&batch, NULL); - if (flags & PIPE_FLUSH_END_OF_FRAME) - fd_log_eof(ctx); - u_trace_context_process(&ctx->trace_context, !!(flags & PIPE_FLUSH_END_OF_FRAME)); } @@ -302,9 +292,6 @@ fd_context_destroy(struct pipe_context *pctx) list_del(&ctx->node); fd_screen_unlock(ctx->screen); - fd_log_process(ctx, true); - assert(list_is_empty(&ctx->log_chunks)); - fd_fence_ref(&ctx->last_fence, NULL); if (ctx->in_fence_fd != -1) @@ -596,7 +583,6 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, list_inithead(&ctx->hw_active_queries); list_inithead(&ctx->acc_active_queries); - list_inithead(&ctx->log_chunks); fd_screen_lock(ctx->screen); ctx->seqno = ++screen->ctx_seqno; @@ -605,29 +591,9 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, ctx->current_scissor = &ctx->disabled_scissor; - ctx->log_out = stdout; - u_trace_context_init(&ctx->trace_context, pctx, fd_trace_record_ts, fd_trace_read_ts); - if ((fd_mesa_debug & FD_DBG_LOG) && - !(ctx->record_timestamp && ctx->ts_to_ns)) { - printf("logging not supported!\n"); - fd_mesa_debug &= ~FD_DBG_LOG; - } - -#if DETECT_OS_ANDROID - if (fd_mesa_debug & FD_DBG_LOG) { - static unsigned idx = 0; - char *p; - asprintf(&p, "/data/fdlog/%s-%d.log", util_get_process_name(), idx++); - - FILE *f = fopen(p, "w"); - if (f) - ctx->log_out = f; - } -#endif - return pctx; fail: diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index b2e5cbbadc3..785345ff36a 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -441,10 +441,6 @@ struct fd_context { void (*record_timestamp)(struct fd_ringbuffer *ring, struct fd_bo *bo, unsigned offset); uint64_t (*ts_to_ns)(uint64_t ts); - struct list_head log_chunks; /* list of flushed log chunks in fifo order */ - unsigned frame_nr; /* frame counter (for fd_log) */ - FILE *log_out; - /* * Common pre-cooked VBO state (used for a3xx and later): */ diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index ce72eb9557b..3a0e1060f39 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -37,7 +37,6 @@ #include "freedreno_gmem.h" #include "freedreno_context.h" #include "freedreno_fence.h" -#include "freedreno_log.h" #include "freedreno_resource.h" #include "freedreno_query_hw.h" #include "freedreno_tracepoints.h" @@ -589,8 +588,6 @@ render_tiles(struct fd_batch *batch, struct fd_gmem_stateobj *gmem) for (i = 0; i < (gmem->nbins_x * gmem->nbins_y); i++) { struct fd_tile *tile = &gmem->tile[i]; - fd_log(batch, "bin_h=%d, yoff=%d, bin_w=%d, xoff=%d", - tile->bin_h, tile->yoff, tile->bin_w, tile->xoff); trace_start_tile(&batch->trace, tile->bin_h, tile->yoff, tile->bin_w, tile->xoff); @@ -606,7 +603,6 @@ render_tiles(struct fd_batch *batch, struct fd_gmem_stateobj *gmem) ctx->query_prepare_tile(batch, i, batch->gmem); /* emit IB to drawcmds: */ - fd_log(batch, "TILE[%d]: START DRAW IB", i); trace_start_draw_ib(&batch->trace); if (ctx->emit_tile) { ctx->emit_tile(batch, tile); @@ -614,7 +610,6 @@ render_tiles(struct fd_batch *batch, struct fd_gmem_stateobj *gmem) ctx->screen->emit_ib(batch->gmem, batch->draw); } trace_end_draw_ib(&batch->trace); - fd_log(batch, "TILE[%d]: END DRAW IB", i); fd_reset_wfi(batch); /* emit gmem2mem to transfer tile back to system memory: */ @@ -638,7 +633,6 @@ render_sysmem(struct fd_batch *batch) ctx->query_prepare_tile(batch, 0, batch->gmem); if (!batch->nondraw) { - fd_log(batch, "SYSMEM: START DRAW IB"); trace_start_draw_ib(&batch->trace); } /* emit IB to drawcmds: */ @@ -646,7 +640,6 @@ render_sysmem(struct fd_batch *batch) if (!batch->nondraw) { trace_end_draw_ib(&batch->trace); - fd_log(batch, "SYSMEM: END DRAW IB"); } fd_reset_wfi(batch); @@ -669,7 +662,6 @@ flush_ring(struct fd_batch *batch) ×tamp); fd_fence_populate(batch->fence, timestamp, out_fence_fd); - fd_log_flush(batch); } void @@ -689,9 +681,6 @@ fd_gmem_render_tiles(struct fd_batch *batch) if (batch->cleared || batch->gmem_reason || ((batch->num_draws > 5) && !batch->blit) || (pfb->samples > 1)) { - fd_log(batch, "GMEM: cleared=%x, gmem_reason=%x, num_draws=%u, samples=%u", - batch->cleared, batch->gmem_reason, batch->num_draws, - pfb->samples); } else if (!(fd_mesa_debug & FD_DBG_NOBYPASS)) { sysmem = true; } @@ -726,24 +715,11 @@ fd_gmem_render_tiles(struct fd_batch *batch) ctx->stats.batch_total++; - if (unlikely(fd_mesa_debug & FD_DBG_LOG) && !batch->nondraw) { - fd_log_stream(batch, stream, util_dump_framebuffer_state(stream, pfb)); - for (unsigned i = 0; i < pfb->nr_cbufs; i++) { - fd_log_stream(batch, stream, util_dump_surface(stream, pfb->cbufs[i])); - } - fd_log_stream(batch, stream, util_dump_surface(stream, pfb->zsbuf)); - } - if (batch->nondraw) { DBG("%p: rendering non-draw", batch); render_sysmem(batch); ctx->stats.batch_nondraw++; } else if (sysmem) { - fd_log(batch, "%p: rendering sysmem %ux%u (%s/%s), num_draws=%u", - batch, pfb->width, pfb->height, - util_format_short_name(pipe_surface_format(pfb->cbufs[0])), - util_format_short_name(pipe_surface_format(pfb->zsbuf)), - batch->num_draws); trace_render_sysmem(&batch->trace); if (ctx->query_prepare) ctx->query_prepare(batch, 1); @@ -752,10 +728,6 @@ fd_gmem_render_tiles(struct fd_batch *batch) } else { struct fd_gmem_stateobj *gmem = lookup_gmem_state(batch, false, false); batch->gmem_state = gmem; - fd_log(batch, "%p: rendering %dx%d tiles %ux%u (%s/%s)", - batch, pfb->width, pfb->height, gmem->nbins_x, gmem->nbins_y, - util_format_short_name(pipe_surface_format(pfb->cbufs[0])), - util_format_short_name(pipe_surface_format(pfb->zsbuf))); trace_render_gmem(&batch->trace, gmem->nbins_x, gmem->nbins_y, gmem->bin_w, gmem->bin_h); if (ctx->query_prepare) diff --git a/src/gallium/drivers/freedreno/freedreno_log.c b/src/gallium/drivers/freedreno/freedreno_log.c deleted file mode 100644 index ad4c49eb2ec..00000000000 --- a/src/gallium/drivers/freedreno/freedreno_log.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include - -#include "freedreno_log.h" -#include "freedreno_batch.h" -#include "freedreno_context.h" - -#include "util/u_fifo.h" - -/* A simple(ish) logging mechanism with timestamps recorded at the - * corresponding point in the cmdstream. The overall design is based - * on fd_log_chunk's, which buffer up up to 'msgs_per_chunk' log msgs - * and track an associated bo containing timestamps written from the - * GPU. - * - * The fd_batch tracks a list of fd_log_chunk's. When fd_log() is - * called, msgs are pushed into the last (most recent) chunk until - * it is full, at which point a new chunk is created. And cmds are - * inserted into the cmdstream to record the GPU timestamp that - * corresponds with the log msg. - * - * When the batch is flushed, the list of log chunks is transferred - * to the end of fd_context's list of chunks, and we attempt to pop - * chunks from the from of the list if their timestamp bo is idle (ie. - * the GPU has finished the batch that was writing the timestamps). - * - * NOTE: this is only appropriate for IB1 (ie. "gmem" level) cmdstream, - * the IB2 (draw/binning) cmdstream can be executed multiple times, - * which this mechanism is not designed to support. Other existing - * GL level queries (time-elapsed, amd-perfcntrs) are more appropriate - * for profiling at that level. - */ - -enum { - bo_size = 0x1000, - msgs_per_chunk = bo_size / sizeof(uint64_t), -}; - -struct fd_log_chunk { - struct list_head node; - - unsigned num_msgs; - struct util_fifo *msg_fifo; - - /* list of recorded 64b timestamps */ - struct fd_bo *timestamps_bo; - - bool last; /* this chunk is last in submit */ - bool eof; /* this chunk is last in frame */ - uint32_t *ring_cur; -}; - -static struct fd_log_chunk * -get_chunk(struct fd_batch *batch) -{ - struct fd_log_chunk *chunk; - - /* do we currently have a non-full chunk to append msgs to? */ - if (!list_is_empty(&batch->log_chunks)) { - chunk = list_last_entry(&batch->log_chunks, - 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: */ - chunk = calloc(1, sizeof(*chunk)); - 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); - - return chunk; -} - -static void -free_chunk(struct fd_log_chunk *chunk) -{ - assert(chunk->msg_fifo->num == 0); - u_fifo_destroy(chunk->msg_fifo); - fd_bo_del(chunk->timestamps_bo); - list_del(&chunk->node); - 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, struct times *t) -{ - /* 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); - unsigned n = 0; - char *msg; - - while (u_fifo_pop(chunk->msg_fifo, (void **)&msg)) { - uint64_t ts = timestamps[n++]; - uint64_t ns = ctx->ts_to_ns(ts); - int32_t delta; - - if (!t->first_time_ns) - t->first_time_ns = ns; - - if (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 = t->last_time_ns; - delta = 0; - } - - fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n", - ts, ns, delta, msg); - free(msg); - - } - - 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++); -} - -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); - - unsigned flags = DRM_FREEDRENO_PREP_READ; - if (!wait) - flags |= DRM_FREEDRENO_PREP_NOSYNC; - - int ret = fd_bo_cpu_prep(chunk->timestamps_bo, ctx->pipe, flags); - if (ret) - break; - - 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); -} - -void -fd_log_flush(struct fd_batch *batch) -{ - /* transfer batch's log chunks to context: */ - list_splicetail(&batch->log_chunks, &batch->ctx->log_chunks); - list_inithead(&batch->log_chunks); -} - -void -_fd_log(struct fd_batch *batch, const char *fmt, ...) -{ - struct fd_context *ctx = batch->ctx; - struct fd_ringbuffer *ring = batch->nondraw ? batch->draw : batch->gmem; - struct fd_log_chunk *chunk = get_chunk(batch); - char *msg; - - va_list ap; - va_start(ap, fmt); - if (vasprintf(&msg, fmt, ap) < 0) { - va_end(ap); - return; - } - va_end(ap); - - u_fifo_add(chunk->msg_fifo, msg); - - assert(ctx->record_timestamp); - - /* If nothing else has been emitted to the ring since the last log msg, - * skip emitting another timestamp. - */ - if (ring->cur == chunk->ring_cur) { - uint64_t *ts = fd_bo_map(chunk->timestamps_bo); - /* zero signifies an invalid timestamp to process_chunk(), so it - * will use the last valid timestamp for this msg instead. - */ - ts[chunk->num_msgs] = 0; - } else { - ctx->record_timestamp(ring, chunk->timestamps_bo, - chunk->num_msgs * sizeof(uint64_t)); - } - - chunk->num_msgs++; - chunk->ring_cur = ring->cur; -} - -void fd_log_eof(struct fd_context *ctx) -{ - if (!(fd_mesa_debug & FD_DBG_LOG)) - return; - - if (list_is_empty(&ctx->log_chunks)) { - fprintf(ctx->log_out, "WARNING: no log chunks!\n"); - return; - } - - struct fd_log_chunk *last_chunk = list_last_entry(&ctx->log_chunks, - struct fd_log_chunk, node); - last_chunk->eof = true; - - /* and process any chunks that are now idle/ready: */ - fd_log_process(ctx, false); -} diff --git a/src/gallium/drivers/freedreno/freedreno_log.h b/src/gallium/drivers/freedreno/freedreno_log.h deleted file mode 100644 index ea5e22eaaff..00000000000 --- a/src/gallium/drivers/freedreno/freedreno_log.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef FREEDRENO_LOG_H_ -#define FREEDRENO_LOG_H_ - -#include "freedreno_util.h" - -struct fd_batch; -struct fd_context; - -void fd_log_process(struct fd_context *ctx, bool wait); -void fd_log_flush(struct fd_batch *batch); -void _fd_log(struct fd_batch *batch, const char *fmt, ...) - _util_printf_format(2, 3); - -/* macro wrapper so that arguments are not evaluated when logging is not - * enabled: - */ -#define fd_log(__batch, __fmt, ...) \ - do { \ - if (unlikely(fd_mesa_debug & FD_DBG_LOG)) { \ - _fd_log(__batch, __fmt, ##__VA_ARGS__); \ - } else { \ - DBG(__fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -/* A variant of fd_log() which provides a FILE* stream to write the - * log msg into, mostly to make u_dump_state stuff useful - */ -#define fd_log_stream(__batch, __stream, __exp) \ - do { \ - if (unlikely(fd_mesa_debug & FD_DBG_LOG)) { \ - char buf[1024]; \ - FILE *__stream = fmemopen(buf, sizeof(buf), "w"); \ - __exp; \ - fclose(__stream); \ - _fd_log(__batch, "%s", buf); \ - } \ - } while (0) - -void fd_log_eof(struct fd_context *ctx); - -#endif /* FREEDRENO_LOG_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 4bbd5bb0547..c104b84e833 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -72,7 +72,7 @@ static const struct debug_named_value debug_options[] = { {"noscis", FD_DBG_NOSCIS, "Disable scissor optimization"}, {"direct", FD_DBG_DIRECT, "Force inline (SS_DIRECT) state loads"}, {"nobypass", FD_DBG_NOBYPASS, "Disable GMEM bypass"}, - {"log", FD_DBG_LOG, "Enable GPU timestamp based logging (a6xx+)"}, + /* BIT(7) */ {"nobin", FD_DBG_NOBIN, "Disable hw binning"}, {"nogmem", FD_DBG_NOGMEM, "Disable GMEM rendering (bypass only)"}, /* BIT(10) */ diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 0ae200b1968..f9196924265 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -68,7 +68,7 @@ enum fd_debug_flag { FD_DBG_NOSCIS = BITFIELD_BIT(4), FD_DBG_DIRECT = BITFIELD_BIT(5), FD_DBG_NOBYPASS = BITFIELD_BIT(6), - FD_DBG_LOG = BITFIELD_BIT(7), + /* BIT(7) */ FD_DBG_NOBIN = BITFIELD_BIT(8), FD_DBG_NOGMEM = BITFIELD_BIT(9), /* BIT(10) */ diff --git a/src/gallium/drivers/freedreno/log-parser.py b/src/gallium/drivers/freedreno/log-parser.py deleted file mode 100755 index 76e0ca9f1f2..00000000000 --- a/src/gallium/drivers/freedreno/log-parser.py +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env python3 - -import re -import sys -import gzip -import io - - -class GMEMPass: - def __init__(self): - self.cleared = None - self.gmem_reason = None - self.num_draws = None - self.samples = None - - self.width = None - self.height = None - self.nbinx = None - self.nbiny = None - - self.formats = [] # format per MRT + zsbuf - self.lrz_clear_time = 0 - self.binning_time = 0 - self.restore_clear_time = 0 - self.draw_time = 0 - self.resolve_time = 0 - self.elapsed_time = 0 - -def dump_gmem_passes(gmem_passes, blit_time, sysmem_time, total_time): - i = 0 - lrz_clear_time = 0 - binning_time = 0 - restore_clear_time = 0 - draw_time = 0 - resolve_time = 0 - elapsed_time = 0 - for gmem in gmem_passes: - print(" GMEM[{}]: {}x{} ({}x{} tiles), {} draws, lrz clear: {:,} ns, binning: {:,} ns, restore/clear: {:,} ns, draw: {:,} ns, resolve: {:,} ns, total: {:,} ns, rt/zs: {}".format( - i, gmem.width, gmem.height, gmem.nbinx, gmem.nbiny, gmem.num_draws, - gmem.lrz_clear_time, gmem.binning_time, gmem.restore_clear_time, - gmem.draw_time, gmem.resolve_time, gmem.elapsed_time, - ", ".join(gmem.formats) - )) - lrz_clear_time += gmem.lrz_clear_time - binning_time += gmem.binning_time - restore_clear_time += gmem.restore_clear_time - draw_time += gmem.draw_time - resolve_time += gmem.resolve_time - elapsed_time += gmem.elapsed_time - i += 1 - - print(" TOTAL: lrz clear: {:,} ns ({}%), binning: {:,} ns ({}%), restore/clear: {:,} ns ({}%), draw: {:,} ns ({}%), resolve: {:,} ns ({}%), blit: {:,} ns ({}%), sysmem: {:,} ns ({}%), total: {:,} ns\n".format( - lrz_clear_time, 100.0 * lrz_clear_time / total_time, - binning_time, 100.0 * binning_time / total_time, - restore_clear_time, 100.0 * restore_clear_time / total_time, - draw_time, 100.0 * draw_time / total_time, - resolve_time, 100.0 * resolve_time / total_time, - blit_time, 100.0 * blit_time / total_time, - sysmem_time, 100.0 * sysmem_time / total_time, - total_time - )) - -def main(): - filename = sys.argv[1] - if filename.endswith(".gz"): - file = gzip.open(filename, "r") - file = io.TextIOWrapper(file) - else: - file = open(filename, "r") - lines = file.read().split('\n') - - compute_match = re.compile(r"COMPUTE: START") - gmem_start_match = re.compile(r": GMEM: cleared=(\S+), gmem_reason=(\S+), num_draws=(\S+), samples=(\S+)") - gmem_match = re.compile(r": rendering (\S+)x(\S+) tiles (\S+)x(\S+)") - gmem_surf_match = re.compile(r": {format = (\S+),") - gmem_lrz_clear_match = re.compile(r"\+(\S+): END LRZ CLEAR") - gmem_binning_match = re.compile(r"\+(\S+): GMEM: END BINNING IB") - gmem_restore_clear_match = re.compile(r"\+(\S+): TILE: END CLEAR/RESTORE") - gmem_draw_match = re.compile(r"\+(\S+): TILE\[\S+\]: END DRAW IB") - gmem_resolve_match = re.compile(r"\+(\S+): TILE: END RESOLVE") - sysmem_match = re.compile(r": rendering sysmem (\S+)x(\S+)") - blit_match = re.compile(r": END BLIT") - elapsed_match = re.compile(r"ELAPSED: (\S+) ns") - eof_match = re.compile(r"END OF FRAME (\S+)") - - # Times in ns: - times_blit = [] - times_sysmem = [] - times_gmem = [] - times_compute = [] - times = None - gmem_passes = [] # set of GMEM passes in frame - gmem = None # current GMEM pass - - # Helper to set the appropriate times table for the current pass, - # which is expected to only happen once for a given render pass - def set_times(t): - nonlocal times - if times is not None: - print("expected times to not be set yet") - times = t - - for line in lines: - match = re.search(compute_match, line) - if match is not None: - set_times(times_compute) - continue - - match = re.search(gmem_start_match, line) - if match is not None: - if gmem is not None: - print("expected gmem to not be set yet") - set_times(times_gmem) - gmem = GMEMPass() - gmem.cleared = match.group(1) - gmem.gmem_reason = match.group(2) - gmem.num_draws = match.group(3) - gmem.samples = match.group(4) - - if gmem is not None: - match = re.search(gmem_match, line) - if match is not None: - gmem.width = int(match.group(1)) - gmem.height = int(match.group(2)) - gmem.nbinx = int(match.group(3)) - gmem.nbiny = int(match.group(4)) - continue - - match = re.search(gmem_surf_match, line) - if match is not None: - gmem.formats.append(match.group(1)) - continue - - match = re.search(gmem_lrz_clear_match, line) - if match is not None: - gmem.lrz_clear_time += int(match.group(1)) - continue - - match = re.search(gmem_binning_match, line) - if match is not None: - gmem.binning_time += int(match.group(1)) - continue - - match = re.search(gmem_restore_clear_match, line) - if match is not None: - gmem.restore_clear_time += int(match.group(1)) - continue - - match = re.search(gmem_draw_match, line) - if match is not None: - gmem.draw_time += int(match.group(1)) - continue - - match = re.search(gmem_resolve_match, line) - if match is not None: - gmem.resolve_time += int(match.group(1)) - continue - - - match = re.search(sysmem_match, line) - if match is not None: - set_times(times_sysmem) - continue - - match = re.search(blit_match, line) - if match is not None: - set_times(times_blit) - continue - - match = re.search(eof_match, line) - if match is not None: - frame_nr = int(match.group(1)) - print("FRAME[{}]: {} blits ({:,} ns), {} SYSMEM ({:,} ns), {} GMEM ({:,} ns), {} COMPUTE ({:,} ns)".format( - frame_nr, - len(times_blit), sum(times_blit), - len(times_sysmem), sum(times_sysmem), - len(times_gmem), sum(times_gmem), - len(times_compute), sum(times_compute) - )) - if len(gmem_passes) > 0: - total_time = sum(times_blit) + sum(times_sysmem) + sum(times_gmem) + sum(times_compute) - dump_gmem_passes(gmem_passes, sum(times_blit), sum(times_sysmem), total_time) - times_blit = [] - times_sysmem = [] - times_gmem = [] - times = None - gmem_passes = [] - times_compute = [] - gmem = None - continue - - match = re.search(elapsed_match, line) - if match is not None: - time = int(match.group(1)) - #print("ELAPSED: " + str(time) + " ns") - times.append(time) - times = None - if gmem is not None: - gmem.elapsed_time = time - gmem_passes.append(gmem) - gmem = None - continue - - -if __name__ == "__main__": - main() - diff --git a/src/gallium/drivers/freedreno/meson.build b/src/gallium/drivers/freedreno/meson.build index 667783fe80d..ccbae9b2cdb 100644 --- a/src/gallium/drivers/freedreno/meson.build +++ b/src/gallium/drivers/freedreno/meson.build @@ -33,8 +33,6 @@ files_libfreedreno = files( 'freedreno_fence.h', 'freedreno_gmem.c', 'freedreno_gmem.h', - 'freedreno_log.c', - 'freedreno_log.h', 'freedreno_program.c', 'freedreno_program.h', 'freedreno_query.c',