freedreno/cffdec: Add option to dump bindless descriptors

cffdump --bindless would dump bindless descriptors. We don't know
what exactly is in the descriptors, so we dump all interpretations
for each of them.

Example:
    set[1]:
    UBO[0]:
        { BASE_LO = 0x23806420 }
        { BASE_HI = 0xc | SIZE = 0x2 }
    STORAGE/TEXEL/IMAGE[0]:
        { TILE_MODE = TILE6_LINEAR | SWIZ_X = A6XX_TEX_Z | SWIZ_Y = A6XX_TEX_X | SWIZ_Z = A6XX_TEX_Y | SWIZ_W = A6XX_TEX_W | MIPLVLS = 0 | SAMPLES = MSAA_ONE | FMT = FMT6_R8_G8B8_2PLANE_420_UNORM | SWAP = WZYX }
        { WIDTH = 12 | HEIGHT = 8 }
        { STRUCTSIZETEXELS = 1024 | STARTOFFSETTEXELS = 0 | PITCHALIGN = 1 | PITCH = 128 | TYPE = A6XX_TEX_2D }
        { ARRAY_PITCH = 4096 | MIN_LAYERSZ = 0 }
        { BASE_LO = 0xa5000 }
        { BASE_HI = 0x1 | DEPTH = 1 }
        { MIN_LOD_CLAMP = 0.000000 | PLANE_PITCH = 128 }
        { FLAG_LO = 0xa6000 }
        { FLAG_HI = 0x1 }
        { FLAG_BUFFER_ARRAY_PITCH = 327680 | 0xa0000 }
        { FLAG_BUFFER_PITCH = 64 | FLAG_BUFFER_LOGW = 0 | FLAG_BUFFER_LOGH = 0 }
        { 11 = 0 }
        { 12 = 0 }
        { 13 = 0 }
        { 14 = 0 }
        { 15 = 0 }
    SAMPLER[0]:
        { XY_MAG = A6XX_TEX_NEAREST | XY_MIN = A6XX_TEX_NEAREST | WRAP_S = A6XX_TEX_CLAMP_TO_EDGE | WRAP_T = A6XX_TEX_MIRROR_CLAMP | WRAP_R = A6XX_TEX_MIRROR_CLAMP | ANISO = A6XX_TEX_ANISO_2 | LOD_BIAS = 4.437500 }
        { COMPARE_FUNC = FUNC_GEQUAL | MAX_LOD = 4.000000 | MIN_LOD = 0.000000 }
        { REDUCTION_MODE = A6XX_REDUCTION_MODE_MIN | BCOLOR = 0x400080 }
        { 3 = 0x1 }

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31632>
This commit is contained in:
Danylo Piliaiev 2024-10-14 15:32:52 +02:00 committed by Marge Bot
parent e2e9dd4f21
commit 6d6d5b869c
3 changed files with 79 additions and 3 deletions

View File

@ -1490,6 +1490,67 @@ dump_tex_const(uint32_t *texconst, int num_unit, int level)
}
}
static void
dump_bindless_descriptors(bool is_compute, int level)
{
if (!options->dump_bindless)
return;
printl(2, "%sdraw[%i] bindless descriptors\n", levels[level], draw_count);
for (unsigned i = 0; i < 128; i++) {
static char reg_name[64];
if (is_compute) {
sprintf(reg_name, "SP_CS_BINDLESS_BASE[%u].DESCRIPTOR", i);
} else {
sprintf(reg_name, "SP_BINDLESS_BASE[%u].DESCRIPTOR", i);
}
const unsigned base_reg = regbase(reg_name);
if (!base_reg)
break;
printl(2, "%sset[%u]:\n", levels[level + 1], i);
uint64_t ext_src_addr;
if (is_64b()) {
const unsigned reg = base_reg + i * 2;
if (!reg_written(reg))
continue;
ext_src_addr = reg_val(reg) & 0xfffffffc;
ext_src_addr |= ((uint64_t)reg_val(reg + 1)) << 32;
} else {
const unsigned reg = base_reg + i;
if (!reg_written(reg))
continue;
ext_src_addr = reg_val(reg) & 0xfffffffc;
}
uint32_t *contents = NULL;
if (ext_src_addr)
contents = hostptr(ext_src_addr);
if (!contents)
continue;
unsigned length = hostlen(ext_src_addr);
unsigned desc_count = length / (16 * sizeof(uint32_t));
for (unsigned desc_idx = 0; desc_idx < desc_count; desc_idx++) {
printl(2, "%sUBO[%u]:\n", levels[level + 1], desc_idx);
dump_domain(contents, 2, level + 2, "A6XX_UBO");
printl(2, "%sSTORAGE/TEXEL/IMAGE[%u]:\n", levels[level + 1], desc_idx);
dump_tex_const(contents, 1, level);
printl(2, "%sSAMPLER[%u]:\n", levels[level + 1], desc_idx);
dump_tex_samp(contents, STATE_SRC_BINDLESS, 1, level);
contents += 16;
}
}
}
static void
cp_load_state(uint32_t *dwords, uint32_t sizedwords, int level)
{
@ -2027,8 +2088,10 @@ cp_draw_indx(uint32_t *dwords, uint32_t sizedwords, int level)
}
/* don't bother dumping registers for the dummy draw_indx's.. */
if (num_indices > 0)
if (num_indices > 0) {
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
needs_wfi = true;
}
@ -2069,8 +2132,10 @@ cp_draw_indx_2(uint32_t *dwords, uint32_t sizedwords, int level)
}
/* don't bother dumping registers for the dummy draw_indx's.. */
if (num_indices > 0)
if (num_indices > 0) {
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
}
static void
@ -2083,8 +2148,10 @@ cp_draw_indx_offset(uint32_t *dwords, uint32_t sizedwords, int level)
print_mode(level);
/* don't bother dumping registers for the dummy draw_indx's.. */
if (num_indices > 0)
if (num_indices > 0) {
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
}
static void
@ -2108,6 +2175,7 @@ cp_draw_indx_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
addr = dwords[3];
dump_gpuaddr_size(addr, level, 0x10, 2);
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
@ -2123,6 +2191,7 @@ cp_draw_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
addr = (((uint64_t)dwords[2] & 0x1ffff) << 32) | dwords[1];
dump_gpuaddr_size(addr, level, 0x10, 2);
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
@ -2182,6 +2251,7 @@ cp_draw_indirect_multi(uint32_t *dwords, uint32_t sizedwords, int level)
}
}
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
@ -2193,6 +2263,7 @@ cp_draw_auto(uint32_t *dwords, uint32_t sizedwords, int level)
do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), 0);
print_mode(level);
dump_bindless_descriptors(false, level);
dump_register_summary(level);
}
@ -2619,6 +2690,7 @@ static void
cp_exec_cs(uint32_t *dwords, uint32_t sizedwords, int level)
{
do_query("compute", 0);
dump_bindless_descriptors(true, level);
dump_register_summary(level);
}
@ -2637,6 +2709,7 @@ cp_exec_cs_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
dump_gpuaddr_size(addr, level, 0x10, 2);
do_query("compute", 0);
dump_bindless_descriptors(true, level);
dump_register_summary(level);
}

View File

@ -35,6 +35,7 @@ struct cffdec_options {
int summary;
int allregs;
int dump_textures;
int dump_bindless;
int decode_markers;
char *script;

View File

@ -67,6 +67,7 @@ print_usage(const char *name)
"\t-D, --draw=N - decode only draw N\n"
"\t-e, --exe=NAME - only decode cmdstream from named process\n"
"\t--textures - dump texture contents (if possible)\n"
"\t--bindless - dump bindless descriptors contents (if possible)\n"
"\t-L, --script=LUA - run specified lua script to analyze state\n"
"\t-q, --query=REG - query mode, dump only specified query registers on\n"
"\t each draw; multiple --query/-q args can be given to\n"
@ -104,6 +105,7 @@ static const struct option opts[] = {
{ "no-pager", no_argument, &interactive, 0 },
{ "pager", no_argument, &interactive, 1 },
{ "textures", no_argument, &options.dump_textures, 1 },
{ "bindless", no_argument, &options.dump_bindless, 1 },
{ "show-compositor", no_argument, &show_comp, 1 },
{ "query-all", no_argument, &options.query_mode, QUERY_ALL },
{ "query-written", no_argument, &options.query_mode, QUERY_WRITTEN },