freedreno/rddecompiler: Update to handle a7xx

Also make rdcompiler compilable for Android.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25005>
This commit is contained in:
Danylo Piliaiev 2023-05-24 15:01:10 +02:00 committed by Marge Bot
parent e3bbd1688b
commit c22f894bd1
3 changed files with 116 additions and 21 deletions

View file

@ -4,22 +4,30 @@
# Before compiling, create "subprojects" directory and create a link
# to mesa there.
project('generate_rd', ['c'], default_options : ['c_std=c11'])
project('generate_rd', ['c', 'cpp'], default_options : ['c_std=c11', 'cpp_std=c++17'])
mesa_proj = subproject('mesa',
default_options : ['gallium-drivers=',
'dri-drivers=',
'glx=disabled',
'vulkan-drivers=',
'tools=freedreno'])
mesa_options = ['gallium-drivers=',
'vulkan-drivers=',
'glx=disabled',
'tools=freedreno']
add_project_arguments(mesa_proj.get_variable('pre_args'), language : ['c'])
if host_machine.system() == 'android'
mesa_options += ['platforms=android',
'platform-sdk-version=28',
'android-stub=true']
endif
mesa_proj = subproject('mesa', default_options : mesa_options)
add_project_arguments(mesa_proj.get_variable('pre_args'), language : ['c', 'cpp'])
add_project_arguments(mesa_proj.get_variable('c_args'), language : ['c'])
add_project_arguments(mesa_proj.get_variable('c_cpp_args'), language : ['c', 'cpp'])
add_project_arguments(mesa_proj.get_variable('cpp_args'), language : ['cpp'])
generate_rd = executable(
'generate_rd',
[
'generate_rd.c'
'generate_rd.cc'
],
include_directories: [
mesa_proj.get_variable('inc_freedreno'),

View file

@ -110,7 +110,7 @@ struct rd_section {
static struct cmdstream *
cs_alloc(struct replay_context *ctx, uint32_t size)
{
struct cmdstream *cs = calloc(1, sizeof(struct cmdstream));
struct cmdstream *cs = (struct cmdstream *) calloc(1, sizeof(struct cmdstream));
cs->mem = (uint32_t *)calloc(1, size);
cs->total_size = size / sizeof(uint32_t);
cs->cur = 0;
@ -129,7 +129,8 @@ rd_write_cs_buffer(FILE *out, struct cmdstream *cs)
if (cs->cur == 0)
return;
const uint32_t packet[] = {(uint32_t)cs->iova, cs->cur * sizeof(uint32_t),
const uint32_t packet[] = {(uint32_t)cs->iova,
(uint32_t)(cs->cur * sizeof(uint32_t)),
(uint32_t)(cs->iova >> 32)};
struct rd_section section_address = {.type = RD_GPUADDR,
.size = sizeof(packet)};
@ -137,7 +138,7 @@ rd_write_cs_buffer(FILE *out, struct cmdstream *cs)
fwrite(packet, sizeof(packet), 1, out);
struct rd_section section_contents = {.type = RD_BUFFER_CONTENTS,
.size = cs->cur * sizeof(uint32_t)};
.size = uint32_t(cs->cur * sizeof(uint32_t))};
fwrite(&section_contents, sizeof(section_contents), 1, out);
fwrite(cs->mem, sizeof(uint32_t), cs->cur, out);
@ -222,8 +223,9 @@ replay_context_init(struct replay_context *ctx, struct fd_dev_id *dev_id,
ctx->state_cs = cs_alloc(ctx, 2 * 1024 * 1024);
ctx->shader_cs = cs_alloc(ctx, 8 * 1024 * 1024);
struct ir3_compiler_options options{};
ctx->compiler =
ir3_compiler_create(NULL, dev_id, &(struct ir3_compiler_options){});
ir3_compiler_create(NULL, dev_id, &options);
ctx->compiled_shaders = _mesa_hash_table_u64_create(ctx->mem_ctx);
}
@ -271,7 +273,7 @@ upload_shader(struct replay_context *ctx, uint64_t id, const char *source)
static void
emit_shader_iova(struct replay_context *ctx, struct cmdstream *cs, uint64_t id)
{
uint64_t *shader_iova =
uint64_t *shader_iova = (uint64_t *)
_mesa_hash_table_u64_search(ctx->compiled_shaders, id);
pkt_qw(cs, *shader_iova);
}

View file

@ -85,16 +85,24 @@ print_usage(const char *name)
"\t%s [OPTSIONS]... FILE...\n\n"
"Options:\n"
"\t-s, --submit=№ - № of the submit to decompile\n"
"\t--no-reg-bunch - Use pkt4 for each reg in CP_CONTEXT_REG_BUNCH\n"
"\t-h, --help - show this message\n"
, name);
/* clang-format on */
exit(2);
}
struct decompiler_options {
int no_reg_bunch;
};
static struct decompiler_options options = {};
/* clang-format off */
static const struct option opts[] = {
{ "submit", required_argument, 0, 's' },
{ "help", no_argument, 0, 'h' },
{ "submit", required_argument, 0, 's' },
{ "no-reg-bunch", no_argument, &options.no_reg_bunch, 1 },
{ "help", no_argument, 0, 'h' },
};
/* clang-format on */
@ -231,6 +239,7 @@ decompile_register(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
if (cnt == 0) {
printlvl(level, "pkt(cs, %u);\n", dword);
} else {
#if 0
char reg_name[33];
char field_name[33];
char reg_idx[33];
@ -247,10 +256,16 @@ decompile_register(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
printlvl(level, "pkt4(cs, REG_%s_%s_%s(%s), (%u), %u);\n",
rnn->variant, reg_name, field_name, reg_idx, cnt, dword);
}
#else
/* TODO: We don't have easy way to get chip generation prefix,
* so just emit raw packet offset as a workaround.
*/
printlvl(level, "pkt4(cs, 0x%04x, (%u), %u);\n", regbase, cnt, dword);
#endif
}
} else {
printlvl(level, "/* unknown pkt4 */\n");
printlvl(level, "pkt4(cs, %u, (%u), %u);\n", regbase, cnt, dword);
printlvl(level, "pkt4(cs, 0x%04x, (%u), %u);\n", regbase, 1, dword);
}
rnn_reginfo_free(info);
@ -258,6 +273,27 @@ decompile_register(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
return 1;
}
static uint32_t
decompile_register_reg_bunch(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
{
struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
const uint32_t dword = *dwords;
if (info && info->typeinfo) {
char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, dword);
printlvl(level, "/* reg: %s = %s */\n", info->name, decoded);
} else {
printlvl(level, "/* unknown pkt4 */\n");
}
printlvl(level, "pkt(cs, 0x%04x);\n", regbase);
printlvl(level, "pkt(cs, %u);\n", dword);
rnn_reginfo_free(info);
return 1;
}
static void
decompile_registers(uint32_t regbase, uint32_t *dwords, uint32_t sizedwords,
int level)
@ -313,14 +349,18 @@ decompile_domain(uint32_t pkt, uint32_t *dwords, uint32_t sizedwords,
continue;
}
uint64_t value = dwords[i];
if (info->typeinfo->high >= 32 && i < sizedwords - 1) {
bool reg64 = info->typeinfo->high >= 32 && i < sizedwords - 1;
if (reg64) {
value |= (uint64_t)dwords[i + 1] << 32;
i++; /* skip the next dword since we're printing it now */
}
decoded = rnndec_decodeval(rnn->vc, info->typeinfo, value);
printlvl(level, "/* %s */\n", decoded);
printlvl(level, "pkt(cs, %u);\n", dwords[i]);
if (reg64) {
printlvl(level, "pkt(cs, %u);\n", dwords[i + 1]);
i++;
}
free(decoded);
free(info->name);
@ -383,6 +423,41 @@ decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level)
"CP_SET_DRAW_STATE", level);
}
}
} else if (val == CP_CONTEXT_REG_BUNCH || val == CP_CONTEXT_REG_BUNCH2) {
uint32_t *dw = dwords + 1;
uint32_t cnt = count - 1;
if (val == CP_CONTEXT_REG_BUNCH2) {
if (options.no_reg_bunch) {
printlvl(level, "// CP_CONTEXT_REG_BUNCH2\n");
printlvl(level, "{\n");
} else {
printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH2", cnt);
printlvl(level, "{\n");
printlvl(level + 1, "pkt(cs, %u);\n", dw[0]);
printlvl(level + 1, "pkt(cs, %u);\n", dw[1]);
}
dw += 2;
cnt -= 2;
} else {
if (options.no_reg_bunch) {
printlvl(level, "// CP_CONTEXT_REG_BUNCH\n");
printlvl(level, "{\n");
} else {
printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH", cnt);
printlvl(level, "{\n");
}
}
for (uint32_t i = 0; i < cnt; i += 2) {
if (options.no_reg_bunch) {
decompile_register(dw[i], &dw[i + 1], 1, level + 1);
} else {
decompile_register_reg_bunch(dw[i], &dw[i + 1], 1, level + 1);
}
}
printlvl(level, "}\n");
} else {
const char *packet_name = pktname(val);
const char *dom_name = packet_name;
@ -414,7 +489,7 @@ decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level)
static void
emit_header()
{
if (!dev_id.gpu_id || !dev_id.chip_id)
if (!dev_id.gpu_id && !dev_id.chip_id)
return;
static bool emitted = false;
@ -422,6 +497,17 @@ emit_header()
return;
emitted = true;
switch (fd_dev_gen(&dev_id)) {
case 6:
init_rnn("a6xx");
break;
case 7:
init_rnn("a7xx");
break;
default:
errx(-1, "unsupported gpu: %u", dev_id.gpu_id);
}
printf("#include \"decode/rdcompiler-utils.h\"\n"
"int main(int argc, char **argv)\n"
"{\n"
@ -462,7 +548,6 @@ handle_file(const char *filename, uint32_t submit_to_decompile)
return -1;
}
init_rnn("a6xx");
type0_reg = reg_a6xx;
mem_ctx = ralloc_context(NULL);
_mesa_set_init(&decompiled_shaders, mem_ctx, u64_hash, u64_compare);