From ca505303a72970f40792f16d79eedab35b27b6ed Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 6 Sep 2013 12:47:18 -0400 Subject: [PATCH] freedreno: emit markers to scratch registers Emit markers by writing to scratch registers in order to "triangulate" gpu lockup position from post-mortem register dump. By comparing register values in post-mortem dump to command-stream, it is possible to narrow down which DRAW_INDX caused the lockup. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 2 ++ .../drivers/freedreno/freedreno_draw.h | 10 ++++++++++ .../drivers/freedreno/freedreno_util.c | 2 ++ .../drivers/freedreno/freedreno_util.h | 19 +++++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index 6b8ea02f693..d4e07af72d3 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -342,6 +342,8 @@ fd3_emit_state(struct fd_context *ctx, uint32_t dirty) { struct fd_ringbuffer *ring = ctx->ring; + emit_marker(ring, 5); + if (dirty & FD_DIRTY_SAMPLE_MASK) { OUT_PKT0(ring, REG_A3XX_RB_MSAA_CONTROL, 1); OUT_RING(ring, A3XX_RB_MSAA_CONTROL_DISABLE | diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h index 7fb0abe2111..cf83a360325 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.h +++ b/src/gallium/drivers/freedreno/freedreno_draw.h @@ -51,6 +51,14 @@ fd_draw(struct fd_context *ctx, enum pc_di_primtype primtype, { struct fd_ringbuffer *ring = ctx->ring; + /* for debug after a lock up, write a unique counter value + * to scratch7 for each draw, to make it easier to match up + * register dumps to cmdstream. The combination of IB + * (scratch6) and DRAW is enough to "triangulate" the + * particular draw that caused lockup. + */ + emit_marker(ring, 7); + OUT_PKT3(ring, CP_DRAW_INDX, idx_bo ? 5 : 3); OUT_RING(ring, 0x00000000); /* viz query info. */ OUT_RING(ring, DRAW(primtype, src_sel, @@ -60,6 +68,8 @@ fd_draw(struct fd_context *ctx, enum pc_di_primtype primtype, OUT_RELOC(ring, idx_bo, idx_offset, 0, 0); OUT_RING (ring, idx_size); } + + emit_marker(ring, 7); } #endif /* FREEDRENO_DRAW_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_util.c b/src/gallium/drivers/freedreno/freedreno_util.c index 0462e5fb515..7056edd2c15 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.c +++ b/src/gallium/drivers/freedreno/freedreno_util.c @@ -31,6 +31,8 @@ #include "freedreno_util.h" +unsigned marker_cnt; + enum adreno_rb_depth_format fd_pipe2depth(enum pipe_format format) { diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 047c62f1565..f8672339cff 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -94,6 +94,7 @@ pipe_surface_format(struct pipe_surface *psurf) #define LOG_DWORDS 0 +static inline void emit_marker(struct fd_ringbuffer *ring, int scratch_idx); static inline void OUT_RING(struct fd_ringbuffer *ring, uint32_t data) @@ -175,9 +176,27 @@ static inline void OUT_IB(struct fd_ringbuffer *ring, struct fd_ringmarker *start, struct fd_ringmarker *end) { + /* for debug after a lock up, write a unique counter value + * to scratch6 for each IB, to make it easier to match up + * register dumps to cmdstream. The combination of IB and + * DRAW (scratch7) is enough to "triangulate" the particular + * draw that caused lockup. + */ + emit_marker(ring, 6); + OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2); fd_ringbuffer_emit_reloc_ring(ring, start, end); OUT_RING(ring, fd_ringmarker_dwords(start, end)); + + emit_marker(ring, 6); +} + +static inline void +emit_marker(struct fd_ringbuffer *ring, int scratch_idx) +{ + extern unsigned marker_cnt; + OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG0 + scratch_idx, 1); + OUT_RING(ring, ++marker_cnt); } #endif /* FREEDRENO_UTIL_H_ */ -- 2.30.2