ac/debug: Dump indirect buffers.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Sun, 1 Jan 2017 15:47:12 +0000 (16:47 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 9 Jan 2017 20:44:08 +0000 (21:44 +0100)
This is for handling chained command buffers and secondary command
buffers. It doesn't handle the trace id for secondary command buffers
yet, but I don't think that is possible in general with just writes,
as we could call a secondary command buffer multiple times.

I think this is good enough for now, as the most useful case is the
chaining when we grow an IB.

Signed-off-by: Bas Nieuwenhuizen <basni@google.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/common/ac_debug.c
src/amd/common/ac_debug.h
src/amd/common/sid.h
src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c
src/gallium/drivers/radeonsi/si_debug.c

index d068492885eae0589905fefb57f393d2d8d6cadb..f91e448a47f28cfe4690cd7a170e1f7861ec276d 100644 (file)
@@ -139,7 +139,9 @@ static void ac_parse_set_reg_packet(FILE *f, uint32_t *ib, unsigned count,
 }
 
 static uint32_t *ac_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
-                                 int trace_id, enum chip_class chip_class)
+                                 int trace_id, enum chip_class chip_class,
+                                 ac_debug_addr_callback addr_callback,
+                                 void *addr_callback_data)
 {
        unsigned count = PKT_COUNT_G(ib[0]);
        unsigned op = PKT3_IT_OPCODE_G(ib[0]);
@@ -258,6 +260,17 @@ static uint32_t *ac_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
                ac_dump_reg(f, R_3F0_IB_BASE_LO, ib[1], ~0);
                ac_dump_reg(f, R_3F1_IB_BASE_HI, ib[2], ~0);
                ac_dump_reg(f, R_3F2_CONTROL, ib[3], ~0);
+
+               if (addr_callback) {
+                       uint64_t addr = ((uint64_t)ib[2] << 32) | ib[1];
+                       void *data = addr_callback(addr_callback_data, addr);
+                       const char *name = G_3F2_CHAIN(ib[3]) ? "chained" : "nested";
+
+                       if (data)
+                               ac_parse_ib(f, data,  G_3F2_IB_SIZE(ib[3]),
+                                           trace_id, name, chip_class,
+                                           addr_callback, addr_callback_data);
+               }
                break;
        case PKT3_CLEAR_STATE:
        case PKT3_INCREMENT_DE_COUNTER:
@@ -320,9 +333,13 @@ static uint32_t *ac_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
  * \param chip_class   chip class
  * \param trace_id     the last trace ID that is known to have been reached
  *                     and executed by the CP, typically read from a buffer
+ * \param addr_callback Get a mapped pointer of the IB at a given address. Can
+ *                      be NULL.
+ * \param addr_callback_data user data for addr_callback
  */
 void ac_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id,
-                const char *name, enum chip_class chip_class)
+                const char *name, enum chip_class chip_class,
+                ac_debug_addr_callback addr_callback, void *addr_callback_data)
 {
        fprintf(f, "------------------ %s begin ------------------\n", name);
 
@@ -332,7 +349,8 @@ void ac_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id,
                switch (type) {
                case 3:
                        ib = ac_parse_packet3(f, ib, &num_dw, trace_id,
-                                             chip_class);
+                                             chip_class, addr_callback,
+                                             addr_callback_data);
                        break;
                case 2:
                        /* type-2 nop */
index f72b67a8456fb26e22ed6e52782e9c2f7ee7be85..63ac4fa84d18c09e0906b177c0f45bc108d45df5 100644 (file)
 #define AC_IS_TRACE_POINT(x)            (((x) & 0xcafe0000) == 0xcafe0000)
 #define AC_GET_TRACE_POINT_ID(x)        ((x) & 0xffff)
 
+typedef void *(*ac_debug_addr_callback)(void *data, uint64_t addr);
+
 void ac_dump_reg(FILE *file, unsigned offset, uint32_t value,
                 uint32_t field_mask);
 void ac_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id,
-                const char *name, enum chip_class chip_class);
+                const char *name, enum chip_class chip_class,
+                ac_debug_addr_callback addr_callback, void *addr_callback_data);
 
 #endif
index fc21a184cb0965e4986b3fb9c7412c313f6e26fb..285cfbfb62f07aa9d6d5899575a7536b95069bcd 100644 (file)
 #define   R_3F1_IB_BASE_HI                     0x3F1
 #define   R_3F2_CONTROL                        0x3F2
 #define     S_3F2_IB_SIZE(x)                   (((unsigned)(x) & 0xfffff) << 0)
+#define     G_3F2_IB_SIZE(x)                   (((unsigned)(x) >> 0) & 0xfffff)
 #define     S_3F2_CHAIN(x)                     (((unsigned)(x) & 0x1) << 20)
+#define     G_3F2_CHAIN(x)                     (((unsigned)(x) >> 20) & 0x1)
 #define     S_3F2_VALID(x)                     (((unsigned)(x) & 0x1) << 23)
 
 #define PKT3_COPY_DATA                        0x40
index 99b16192bcda2b4316613545f6199f8aebed4425..f7707f6c7931969c380b5f25c370571a991dda87 100644 (file)
@@ -777,8 +777,9 @@ static int radv_amdgpu_winsys_cs_submit(struct radeon_winsys_ctx *_ctx,
 }
 
 
-static void *radv_amdgpu_winsys_get_cpu_addr(struct radv_amdgpu_cs *cs, uint64_t addr)
+static void *radv_amdgpu_winsys_get_cpu_addr(void *_cs, uint64_t addr)
 {
+       struct radv_amdgpu_cs *cs = (struct radv_amdgpu_cs *)_cs;
        void *ret = NULL;
        for (unsigned i = 0; i <= cs->num_old_ib_buffers; ++i) {
                struct radv_amdgpu_winsys_bo *bo;
@@ -801,7 +802,8 @@ static void radv_amdgpu_winsys_cs_dump(struct radeon_winsys_cs *_cs,
 
        ac_parse_ib(file,
                    radv_amdgpu_winsys_get_cpu_addr(cs, cs->ib.ib_mc_address),
-                   cs->ib.size, trace_id,  "main IB", cs->ws->info.chip_class);
+                   cs->ib.size, trace_id,  "main IB", cs->ws->info.chip_class,
+                   radv_amdgpu_winsys_get_cpu_addr, cs);
 }
 
 static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws)
index 43fc9c1f3e03a626c879e18de4e336fb912cb11d..cc3617f16592a8dd5f6d59153239e81d5a0ad8cf 100644 (file)
@@ -221,15 +221,18 @@ static void si_dump_last_ib(struct si_context *sctx, FILE *f)
 
        if (sctx->init_config)
                ac_parse_ib(f, sctx->init_config->pm4, sctx->init_config->ndw,
-                           -1, "IB2: Init config", sctx->b.chip_class);
+                           -1, "IB2: Init config", sctx->b.chip_class,
+                           NULL, NULL);
 
        if (sctx->init_config_gs_rings)
                ac_parse_ib(f, sctx->init_config_gs_rings->pm4,
                            sctx->init_config_gs_rings->ndw,
-                           -1, "IB2: Init GS rings", sctx->b.chip_class);
+                           -1, "IB2: Init GS rings", sctx->b.chip_class,
+                           NULL, NULL);
 
        ac_parse_ib(f, sctx->last_gfx.ib, sctx->last_gfx.num_dw,
-                   last_trace_id, "IB", sctx->b.chip_class);
+                   last_trace_id, "IB", sctx->b.chip_class,
+                    NULL, NULL);
 }
 
 static const char *priority_to_string(enum radeon_bo_priority priority)