From: Bas Nieuwenhuizen Date: Sun, 1 Jan 2017 15:47:12 +0000 (+0100) Subject: ac/debug: Dump indirect buffers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8cb60c7dd3cb608615d3e5f89ad4198c0babdb3d;p=mesa.git ac/debug: Dump indirect buffers. 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 Reviewed-by: Marek Olšák Reviewed-by: Dave Airlie --- diff --git a/src/amd/common/ac_debug.c b/src/amd/common/ac_debug.c index d068492885e..f91e448a47f 100644 --- a/src/amd/common/ac_debug.c +++ b/src/amd/common/ac_debug.c @@ -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 */ diff --git a/src/amd/common/ac_debug.h b/src/amd/common/ac_debug.h index f72b67a8456..63ac4fa84d1 100644 --- a/src/amd/common/ac_debug.h +++ b/src/amd/common/ac_debug.h @@ -35,9 +35,12 @@ #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 diff --git a/src/amd/common/sid.h b/src/amd/common/sid.h index fc21a184cb0..285cfbfb62f 100644 --- a/src/amd/common/sid.h +++ b/src/amd/common/sid.h @@ -133,7 +133,9 @@ #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 diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 99b16192bcd..f7707f6c793 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -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) diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c index 43fc9c1f3e0..cc3617f1659 100644 --- a/src/gallium/drivers/radeonsi/si_debug.c +++ b/src/gallium/drivers/radeonsi/si_debug.c @@ -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)