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 <robclark@freedesktop.org>
This commit is contained in:
@@ -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 |
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include "freedreno_util.h"
|
||||
|
||||
unsigned marker_cnt;
|
||||
|
||||
enum adreno_rb_depth_format
|
||||
fd_pipe2depth(enum pipe_format format)
|
||||
{
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user