freedreno: emit markers to scratch registers
authorRob Clark <robclark@freedesktop.org>
Fri, 6 Sep 2013 16:47:18 +0000 (12:47 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 14 Sep 2013 17:31:58 +0000 (13:31 -0400)
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 <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/freedreno_draw.h
src/gallium/drivers/freedreno/freedreno_util.c
src/gallium/drivers/freedreno/freedreno_util.h

index 6b8ea02f6933df919d760083dad2b848b2c5939e..d4e07af72d365c2555f84aa0a6cf4975fad34376 100644 (file)
@@ -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 |
index 7fb0abe21117ffb827b4c14321972128c2137d89..cf83a360325d6ff3e7643efe570b7e3ab1ab6987 100644 (file)
@@ -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_ */
index 0462e5fb5155b7115bc3b8a163b8ba5dee6d16db..7056edd2c15682c3908ec344bf9a17696d5bd1e3 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "freedreno_util.h"
 
+unsigned marker_cnt;
+
 enum adreno_rb_depth_format
 fd_pipe2depth(enum pipe_format format)
 {
index 047c62f1565848c8b9d45ea2cf0c3cd2d41ecaa5..f8672339cfff87ef5f00545d9546f1b391c0bc20 100644 (file)
@@ -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_ */