mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
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:
parent
e3bbd1688b
commit
c22f894bd1
3 changed files with 116 additions and 21 deletions
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -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(§ion_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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue