mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 23:00:11 +01:00
freedreno: Remove fd_log()
Now that it is superceeded by u_trace Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7818>
This commit is contained in:
parent
d5bc39c9d0
commit
03e7c93b82
16 changed files with 3 additions and 641 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#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:
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue