xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/rddecompiler.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Igalia S.L.
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include <assert.h>
7*61046927SAndroid Build Coastguard Worker #include <ctype.h>
8*61046927SAndroid Build Coastguard Worker #include <err.h>
9*61046927SAndroid Build Coastguard Worker #include <errno.h>
10*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
11*61046927SAndroid Build Coastguard Worker #include <getopt.h>
12*61046927SAndroid Build Coastguard Worker #include <signal.h>
13*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
14*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
15*61046927SAndroid Build Coastguard Worker #include <stdint.h>
16*61046927SAndroid Build Coastguard Worker #include <stdio.h>
17*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
18*61046927SAndroid Build Coastguard Worker #include <string.h>
19*61046927SAndroid Build Coastguard Worker #include <unistd.h>
20*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
21*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
22*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
23*61046927SAndroid Build Coastguard Worker #include <sys/wait.h>
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #include "adreno_common.xml.h"
28*61046927SAndroid Build Coastguard Worker #include "adreno_pm4.xml.h"
29*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker #include "a6xx.xml.h"
32*61046927SAndroid Build Coastguard Worker #include "common/freedreno_dev_info.h"
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
35*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
36*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
37*61046927SAndroid Build Coastguard Worker #include "util/rb_tree.h"
38*61046927SAndroid Build Coastguard Worker #include "util/set.h"
39*61046927SAndroid Build Coastguard Worker #include "util/u_vector.h"
40*61046927SAndroid Build Coastguard Worker #include "buffers.h"
41*61046927SAndroid Build Coastguard Worker #include "cffdec.h"
42*61046927SAndroid Build Coastguard Worker #include "disasm.h"
43*61046927SAndroid Build Coastguard Worker #include "io.h"
44*61046927SAndroid Build Coastguard Worker #include "rdutil.h"
45*61046927SAndroid Build Coastguard Worker #include "redump.h"
46*61046927SAndroid Build Coastguard Worker #include "rnnutil.h"
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker /* Decompiles a single cmdstream from .rd into compilable C source.
49*61046927SAndroid Build Coastguard Worker  * C source could be compiled using rdcompiler-meson.build as an example.
50*61046927SAndroid Build Coastguard Worker  *
51*61046927SAndroid Build Coastguard Worker  * For how-to see freedreno.rst
52*61046927SAndroid Build Coastguard Worker  */
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker static int handle_file(const char *filename, uint32_t submit_to_decompile);
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker static const char *levels[] = {
57*61046927SAndroid Build Coastguard Worker    "\t",
58*61046927SAndroid Build Coastguard Worker    "\t\t",
59*61046927SAndroid Build Coastguard Worker    "\t\t\t",
60*61046927SAndroid Build Coastguard Worker    "\t\t\t\t",
61*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t",
62*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t",
63*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t",
64*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t\t",
65*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t\t\t",
66*61046927SAndroid Build Coastguard Worker };
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker static void
printlvl(int lvl,const char * fmt,...)69*61046927SAndroid Build Coastguard Worker printlvl(int lvl, const char *fmt, ...)
70*61046927SAndroid Build Coastguard Worker {
71*61046927SAndroid Build Coastguard Worker    assert(lvl < ARRAY_SIZE(levels));
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    va_list args;
74*61046927SAndroid Build Coastguard Worker    va_start(args, fmt);
75*61046927SAndroid Build Coastguard Worker    fputs(levels[lvl], stdout);
76*61046927SAndroid Build Coastguard Worker    vprintf(fmt, args);
77*61046927SAndroid Build Coastguard Worker    va_end(args);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker static void
print_usage(const char * name)81*61046927SAndroid Build Coastguard Worker print_usage(const char *name)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker    /* clang-format off */
84*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "Usage:\n\n"
85*61046927SAndroid Build Coastguard Worker            "\t%s [OPTIONS]... FILE...\n\n"
86*61046927SAndroid Build Coastguard Worker            "Options:\n"
87*61046927SAndroid Build Coastguard Worker            "\t-s, --submit=№   - № of the submit to decompile\n"
88*61046927SAndroid Build Coastguard Worker            "\t--no-reg-bunch   - Use pkt4 for each reg in CP_CONTEXT_REG_BUNCH\n"
89*61046927SAndroid Build Coastguard Worker            "\t-h, --help       - show this message\n"
90*61046927SAndroid Build Coastguard Worker            , name);
91*61046927SAndroid Build Coastguard Worker    /* clang-format on */
92*61046927SAndroid Build Coastguard Worker    exit(2);
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker struct decompiler_options {
96*61046927SAndroid Build Coastguard Worker    int no_reg_bunch;
97*61046927SAndroid Build Coastguard Worker };
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker static struct decompiler_options options = {};
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker /* clang-format off */
102*61046927SAndroid Build Coastguard Worker static const struct option opts[] = {
103*61046927SAndroid Build Coastguard Worker       { "submit",       required_argument,   0, 's' },
104*61046927SAndroid Build Coastguard Worker       { "no-reg-bunch", no_argument,         &options.no_reg_bunch, 1 },
105*61046927SAndroid Build Coastguard Worker       { "help",         no_argument,         0, 'h' },
106*61046927SAndroid Build Coastguard Worker };
107*61046927SAndroid Build Coastguard Worker /* clang-format on */
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker int
main(int argc,char ** argv)110*61046927SAndroid Build Coastguard Worker main(int argc, char **argv)
111*61046927SAndroid Build Coastguard Worker {
112*61046927SAndroid Build Coastguard Worker    int ret = -1;
113*61046927SAndroid Build Coastguard Worker    int c;
114*61046927SAndroid Build Coastguard Worker    uint32_t submit_to_decompile = -1;
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    while ((c = getopt_long(argc, argv, "s:h", opts, NULL)) != -1) {
117*61046927SAndroid Build Coastguard Worker       switch (c) {
118*61046927SAndroid Build Coastguard Worker       case 0:
119*61046927SAndroid Build Coastguard Worker          /* option that set a flag, nothing to do */
120*61046927SAndroid Build Coastguard Worker          break;
121*61046927SAndroid Build Coastguard Worker       case 's':
122*61046927SAndroid Build Coastguard Worker          submit_to_decompile = strtoul(optarg, NULL, 0);
123*61046927SAndroid Build Coastguard Worker          break;
124*61046927SAndroid Build Coastguard Worker       case 'h':
125*61046927SAndroid Build Coastguard Worker       default:
126*61046927SAndroid Build Coastguard Worker          print_usage(argv[0]);
127*61046927SAndroid Build Coastguard Worker       }
128*61046927SAndroid Build Coastguard Worker    }
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker    if (submit_to_decompile == -1) {
131*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Submit to decompile has to be specified\n");
132*61046927SAndroid Build Coastguard Worker       print_usage(argv[0]);
133*61046927SAndroid Build Coastguard Worker    }
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    while (optind < argc) {
136*61046927SAndroid Build Coastguard Worker       ret = handle_file(argv[optind], submit_to_decompile);
137*61046927SAndroid Build Coastguard Worker       if (ret) {
138*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "error reading: %s\n", argv[optind]);
139*61046927SAndroid Build Coastguard Worker          break;
140*61046927SAndroid Build Coastguard Worker       }
141*61046927SAndroid Build Coastguard Worker       optind++;
142*61046927SAndroid Build Coastguard Worker    }
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker    if (ret)
145*61046927SAndroid Build Coastguard Worker       print_usage(argv[0]);
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker    return ret;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker static struct rnn *rnn;
151*61046927SAndroid Build Coastguard Worker static struct fd_dev_id dev_id;
152*61046927SAndroid Build Coastguard Worker static void *mem_ctx;
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker static struct set decompiled_shaders;
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker static void
init_rnn(const char * gpuname)157*61046927SAndroid Build Coastguard Worker init_rnn(const char *gpuname)
158*61046927SAndroid Build Coastguard Worker {
159*61046927SAndroid Build Coastguard Worker    rnn = rnn_new(true);
160*61046927SAndroid Build Coastguard Worker    rnn_load(rnn, gpuname);
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker const char *
pktname(unsigned opc)164*61046927SAndroid Build Coastguard Worker pktname(unsigned opc)
165*61046927SAndroid Build Coastguard Worker {
166*61046927SAndroid Build Coastguard Worker    return rnn_enumname(rnn, "adreno_pm4_type3_packets", opc);
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_shader(const char * name,uint32_t regbase,uint32_t * dwords,int level)170*61046927SAndroid Build Coastguard Worker decompile_shader(const char *name, uint32_t regbase, uint32_t *dwords, int level)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker    uint64_t gpuaddr = ((uint64_t)dwords[1] << 32) | dwords[0];
173*61046927SAndroid Build Coastguard Worker    gpuaddr &= 0xfffffffffffffff0;
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    /* Shader's iova is referenced in two places, so we have to remember it. */
176*61046927SAndroid Build Coastguard Worker    if (_mesa_set_search(&decompiled_shaders, &gpuaddr)) {
177*61046927SAndroid Build Coastguard Worker       printlvl(level, "emit_shader_iova(&ctx, cs, 0x%" PRIx64 ");\n", gpuaddr);
178*61046927SAndroid Build Coastguard Worker    } else {
179*61046927SAndroid Build Coastguard Worker       uint64_t *key = ralloc(mem_ctx, uint64_t);
180*61046927SAndroid Build Coastguard Worker       *key = gpuaddr;
181*61046927SAndroid Build Coastguard Worker       _mesa_set_add(&decompiled_shaders, key);
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker       void *buf = hostptr(gpuaddr);
184*61046927SAndroid Build Coastguard Worker       assert(buf);
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker       uint32_t sizedwords = hostlen(gpuaddr) / 4;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker       char *stream_data = NULL;
189*61046927SAndroid Build Coastguard Worker       size_t stream_size = 0;
190*61046927SAndroid Build Coastguard Worker       FILE *stream = open_memstream(&stream_data, &stream_size);
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker       try_disasm_a3xx(buf, sizedwords, 0, stream, fd_dev_gen(&dev_id) * 100);
193*61046927SAndroid Build Coastguard Worker       fclose(stream);
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker       printlvl(level, "{\n");
196*61046927SAndroid Build Coastguard Worker       printlvl(level + 1, "const char *source = R\"(\n");
197*61046927SAndroid Build Coastguard Worker       printf("%s", stream_data);
198*61046927SAndroid Build Coastguard Worker       printlvl(level + 1, ")\";\n");
199*61046927SAndroid Build Coastguard Worker       printlvl(level + 1, "upload_shader(&ctx, 0x%" PRIx64 ", source);\n", gpuaddr);
200*61046927SAndroid Build Coastguard Worker       printlvl(level + 1, "emit_shader_iova(&ctx, cs, 0x%" PRIx64 ");\n", gpuaddr);
201*61046927SAndroid Build Coastguard Worker       printlvl(level, "}\n");
202*61046927SAndroid Build Coastguard Worker       free(stream_data);
203*61046927SAndroid Build Coastguard Worker    }
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker    return 2;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker 
208*61046927SAndroid Build Coastguard Worker static struct {
209*61046927SAndroid Build Coastguard Worker    uint32_t regbase;
210*61046927SAndroid Build Coastguard Worker    uint32_t (*fxn)(const char *name, uint32_t regbase, uint32_t *dwords, int level);
211*61046927SAndroid Build Coastguard Worker } reg_a6xx[] = {
212*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_VS_OBJ_START, decompile_shader},
213*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_HS_OBJ_START, decompile_shader},
214*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_DS_OBJ_START, decompile_shader},
215*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_GS_OBJ_START, decompile_shader},
216*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_FS_OBJ_START, decompile_shader},
217*61046927SAndroid Build Coastguard Worker    {REG_A6XX_SP_CS_OBJ_START, decompile_shader},
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker    {0, NULL},
220*61046927SAndroid Build Coastguard Worker }, *type0_reg;
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_register(uint32_t regbase,uint32_t * dwords,uint16_t cnt,int level)223*61046927SAndroid Build Coastguard Worker decompile_register(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
224*61046927SAndroid Build Coastguard Worker {
225*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker    for (unsigned idx = 0; type0_reg[idx].regbase; idx++) {
228*61046927SAndroid Build Coastguard Worker       if (type0_reg[idx].regbase == regbase) {
229*61046927SAndroid Build Coastguard Worker          return type0_reg[idx].fxn(info->name, regbase, dwords, level);
230*61046927SAndroid Build Coastguard Worker       }
231*61046927SAndroid Build Coastguard Worker    }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    const uint32_t dword = *dwords;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    if (info && info->typeinfo) {
236*61046927SAndroid Build Coastguard Worker       char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, dword);
237*61046927SAndroid Build Coastguard Worker       printlvl(level, "/* pkt4: %s = %s */\n", info->name, decoded);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker       if (cnt == 0) {
240*61046927SAndroid Build Coastguard Worker          printlvl(level, "pkt(cs, 0x%x);\n", dword);
241*61046927SAndroid Build Coastguard Worker       } else {
242*61046927SAndroid Build Coastguard Worker #if 0
243*61046927SAndroid Build Coastguard Worker          char reg_name[33];
244*61046927SAndroid Build Coastguard Worker          char field_name[33];
245*61046927SAndroid Build Coastguard Worker          char reg_idx[33];
246*61046927SAndroid Build Coastguard Worker 
247*61046927SAndroid Build Coastguard Worker          /* reginfo doesn't return reg name in a compilable format, for now just
248*61046927SAndroid Build Coastguard Worker           * parse it into a compilable reg name.
249*61046927SAndroid Build Coastguard Worker           * TODO: Make RNN optionally return compilable reg name.
250*61046927SAndroid Build Coastguard Worker           */
251*61046927SAndroid Build Coastguard Worker          if (sscanf(info->name, "%32[A-Z0-6_][%32[x0-9]].%32s", reg_name,
252*61046927SAndroid Build Coastguard Worker                     reg_idx, field_name) != 3) {
253*61046927SAndroid Build Coastguard Worker             printlvl(level, "pkt4(cs, REG_%s_%s, (%u), %u);\n", rnn->variant,
254*61046927SAndroid Build Coastguard Worker                      info->name, cnt, dword);
255*61046927SAndroid Build Coastguard Worker          } else {
256*61046927SAndroid Build Coastguard Worker             printlvl(level, "pkt4(cs, REG_%s_%s_%s(%s), (%u), %u);\n",
257*61046927SAndroid Build Coastguard Worker                      rnn->variant, reg_name, field_name, reg_idx, cnt, dword);
258*61046927SAndroid Build Coastguard Worker          }
259*61046927SAndroid Build Coastguard Worker #else
260*61046927SAndroid Build Coastguard Worker          /* TODO: We don't have easy way to get chip generation prefix,
261*61046927SAndroid Build Coastguard Worker           * so just emit raw packet offset as a workaround.
262*61046927SAndroid Build Coastguard Worker           */
263*61046927SAndroid Build Coastguard Worker          printlvl(level, "pkt4(cs, 0x%04x, (%u), 0x%x);\n", regbase, cnt, dword);
264*61046927SAndroid Build Coastguard Worker #endif
265*61046927SAndroid Build Coastguard Worker       }
266*61046927SAndroid Build Coastguard Worker    } else {
267*61046927SAndroid Build Coastguard Worker       printlvl(level, "/* unknown pkt4 */\n");
268*61046927SAndroid Build Coastguard Worker       printlvl(level, "pkt4(cs, 0x%04x, (%u), 0x%x);\n", regbase, 1, dword);
269*61046927SAndroid Build Coastguard Worker    }
270*61046927SAndroid Build Coastguard Worker 
271*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    return 1;
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_register_reg_bunch(uint32_t regbase,uint32_t * dwords,uint16_t cnt,int level)277*61046927SAndroid Build Coastguard Worker decompile_register_reg_bunch(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
278*61046927SAndroid Build Coastguard Worker {
279*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
280*61046927SAndroid Build Coastguard Worker    const uint32_t dword = *dwords;
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker    if (info && info->typeinfo) {
283*61046927SAndroid Build Coastguard Worker       char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, dword);
284*61046927SAndroid Build Coastguard Worker       printlvl(level, "/* reg: %s = %s */\n", info->name, decoded);
285*61046927SAndroid Build Coastguard Worker    } else {
286*61046927SAndroid Build Coastguard Worker       printlvl(level, "/* unknown pkt4 */\n");
287*61046927SAndroid Build Coastguard Worker    }
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker    printlvl(level, "pkt(cs, 0x%04x);\n", regbase);
290*61046927SAndroid Build Coastguard Worker    printlvl(level, "pkt(cs, 0x%x);\n", dword);
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
293*61046927SAndroid Build Coastguard Worker 
294*61046927SAndroid Build Coastguard Worker    return 1;
295*61046927SAndroid Build Coastguard Worker }
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker static void
decompile_registers(uint32_t regbase,uint32_t * dwords,uint32_t sizedwords,int level)298*61046927SAndroid Build Coastguard Worker decompile_registers(uint32_t regbase, uint32_t *dwords, uint32_t sizedwords,
299*61046927SAndroid Build Coastguard Worker                     int level)
300*61046927SAndroid Build Coastguard Worker {
301*61046927SAndroid Build Coastguard Worker    if (!sizedwords)
302*61046927SAndroid Build Coastguard Worker       return;
303*61046927SAndroid Build Coastguard Worker    uint32_t consumed = decompile_register(regbase, dwords, sizedwords, level);
304*61046927SAndroid Build Coastguard Worker    sizedwords -= consumed;
305*61046927SAndroid Build Coastguard Worker    while (sizedwords > 0) {
306*61046927SAndroid Build Coastguard Worker       regbase += consumed;
307*61046927SAndroid Build Coastguard Worker       dwords += consumed;
308*61046927SAndroid Build Coastguard Worker       consumed = decompile_register(regbase, dwords, 0, level);
309*61046927SAndroid Build Coastguard Worker       sizedwords -= consumed;
310*61046927SAndroid Build Coastguard Worker    }
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker static void
decompile_domain(uint32_t pkt,uint32_t * dwords,uint32_t sizedwords,const char * dom_name,const char * packet_name,int level)314*61046927SAndroid Build Coastguard Worker decompile_domain(uint32_t pkt, uint32_t *dwords, uint32_t sizedwords,
315*61046927SAndroid Build Coastguard Worker                  const char *dom_name, const char *packet_name, int level)
316*61046927SAndroid Build Coastguard Worker {
317*61046927SAndroid Build Coastguard Worker    struct rnndomain *dom;
318*61046927SAndroid Build Coastguard Worker    int i;
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    dom = rnn_finddomain(rnn->db, dom_name);
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker    printlvl(level, "pkt7(cs, %s, %u);\n", packet_name, sizedwords);
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker    if (pkt == CP_LOAD_STATE6_FRAG || pkt == CP_LOAD_STATE6_GEOM) {
325*61046927SAndroid Build Coastguard Worker       enum a6xx_state_type state_type =
326*61046927SAndroid Build Coastguard Worker          (dwords[0] & CP_LOAD_STATE6_0_STATE_TYPE__MASK) >>
327*61046927SAndroid Build Coastguard Worker          CP_LOAD_STATE6_0_STATE_TYPE__SHIFT;
328*61046927SAndroid Build Coastguard Worker       enum a6xx_state_src state_src =
329*61046927SAndroid Build Coastguard Worker          (dwords[0] & CP_LOAD_STATE6_0_STATE_SRC__MASK) >>
330*61046927SAndroid Build Coastguard Worker          CP_LOAD_STATE6_0_STATE_SRC__SHIFT;
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker       /* TODO: decompile all other state */
333*61046927SAndroid Build Coastguard Worker       if (state_type == ST6_SHADER && state_src == SS6_INDIRECT) {
334*61046927SAndroid Build Coastguard Worker          printlvl(level, "pkt(cs, 0x%x);\n", dwords[0]);
335*61046927SAndroid Build Coastguard Worker          decompile_shader(NULL, 0, dwords + 1, level);
336*61046927SAndroid Build Coastguard Worker          return;
337*61046927SAndroid Build Coastguard Worker       }
338*61046927SAndroid Build Coastguard Worker    }
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords; i++) {
341*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = NULL;
342*61046927SAndroid Build Coastguard Worker       if (dom) {
343*61046927SAndroid Build Coastguard Worker          info = rnndec_decodeaddr(rnn->vc, dom, i, 0);
344*61046927SAndroid Build Coastguard Worker       }
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker       char *decoded;
347*61046927SAndroid Build Coastguard Worker       if (!(info && info->typeinfo)) {
348*61046927SAndroid Build Coastguard Worker          printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
349*61046927SAndroid Build Coastguard Worker          continue;
350*61046927SAndroid Build Coastguard Worker       }
351*61046927SAndroid Build Coastguard Worker       uint64_t value = dwords[i];
352*61046927SAndroid Build Coastguard Worker       bool reg64 = info->typeinfo->high >= 32 && i < sizedwords - 1;
353*61046927SAndroid Build Coastguard Worker       if (reg64) {
354*61046927SAndroid Build Coastguard Worker          value |= (uint64_t)dwords[i + 1] << 32;
355*61046927SAndroid Build Coastguard Worker       }
356*61046927SAndroid Build Coastguard Worker       decoded = rnndec_decodeval(rnn->vc, info->typeinfo, value);
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker       printlvl(level, "/* %s */\n", decoded);
359*61046927SAndroid Build Coastguard Worker       printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
360*61046927SAndroid Build Coastguard Worker       if (reg64) {
361*61046927SAndroid Build Coastguard Worker          printlvl(level, "pkt(cs, 0x%x);\n", dwords[i + 1]);
362*61046927SAndroid Build Coastguard Worker          i++;
363*61046927SAndroid Build Coastguard Worker       }
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker       free(decoded);
366*61046927SAndroid Build Coastguard Worker       free(info->name);
367*61046927SAndroid Build Coastguard Worker       free(info);
368*61046927SAndroid Build Coastguard Worker    }
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker static void
decompile_commands(uint32_t * dwords,uint32_t sizedwords,int level,uint32_t * cond_count)372*61046927SAndroid Build Coastguard Worker decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level, uint32_t *cond_count)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker    int dwords_left = sizedwords;
375*61046927SAndroid Build Coastguard Worker    uint32_t count = 0; /* dword count including packet header */
376*61046927SAndroid Build Coastguard Worker    uint32_t val;
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker    if (!dwords) {
379*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "NULL cmd buffer!\n");
380*61046927SAndroid Build Coastguard Worker       return;
381*61046927SAndroid Build Coastguard Worker    }
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker    while (dwords_left > 0) {
384*61046927SAndroid Build Coastguard Worker       if (pkt_is_regwrite(dwords[0], &val, &count)) {
385*61046927SAndroid Build Coastguard Worker          assert(val < 0xffff);
386*61046927SAndroid Build Coastguard Worker          decompile_registers(val, dwords + 1, count - 1, level);
387*61046927SAndroid Build Coastguard Worker       } else if (pkt_is_opcode(dwords[0], &val, &count)) {
388*61046927SAndroid Build Coastguard Worker          if (val == CP_INDIRECT_BUFFER) {
389*61046927SAndroid Build Coastguard Worker             uint64_t ibaddr;
390*61046927SAndroid Build Coastguard Worker             uint32_t ibsize;
391*61046927SAndroid Build Coastguard Worker             ibaddr = dwords[1];
392*61046927SAndroid Build Coastguard Worker             ibaddr |= ((uint64_t)dwords[2]) << 32;
393*61046927SAndroid Build Coastguard Worker             ibsize = dwords[3];
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker             printlvl(level, "{\n");
396*61046927SAndroid Build Coastguard Worker             printlvl(level + 1, "begin_ib();\n");
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker             uint32_t *ptr = hostptr(ibaddr);
399*61046927SAndroid Build Coastguard Worker             decompile_commands(ptr, ibsize, level + 1, NULL);
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker             printlvl(level + 1, "end_ib();\n");
402*61046927SAndroid Build Coastguard Worker             printlvl(level, "}\n");
403*61046927SAndroid Build Coastguard Worker          } else if (val == CP_SET_DRAW_STATE) {
404*61046927SAndroid Build Coastguard Worker             for (int i = 1; i < count; i += 3) {
405*61046927SAndroid Build Coastguard Worker                uint32_t state_count = dwords[i] & 0xffff;
406*61046927SAndroid Build Coastguard Worker                if (state_count != 0) {
407*61046927SAndroid Build Coastguard Worker                   uint32_t unchanged = dwords[i] & (~0xffff);
408*61046927SAndroid Build Coastguard Worker                   uint64_t ibaddr = dwords[i + 1];
409*61046927SAndroid Build Coastguard Worker                   ibaddr |= ((uint64_t)dwords[i + 2]) << 32;
410*61046927SAndroid Build Coastguard Worker 
411*61046927SAndroid Build Coastguard Worker                   printlvl(level, "{\n");
412*61046927SAndroid Build Coastguard Worker                   printlvl(level + 1, "begin_draw_state();\n");
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker                   uint32_t *ptr = hostptr(ibaddr);
415*61046927SAndroid Build Coastguard Worker                   decompile_commands(ptr, state_count, level + 1, NULL);
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker                   printlvl(level + 1, "end_draw_state(%u);\n", unchanged);
418*61046927SAndroid Build Coastguard Worker                   printlvl(level, "}\n");
419*61046927SAndroid Build Coastguard Worker                } else {
420*61046927SAndroid Build Coastguard Worker                   decompile_domain(val, dwords + i, 3, "CP_SET_DRAW_STATE",
421*61046927SAndroid Build Coastguard Worker                                    "CP_SET_DRAW_STATE", level);
422*61046927SAndroid Build Coastguard Worker                }
423*61046927SAndroid Build Coastguard Worker             }
424*61046927SAndroid Build Coastguard Worker          } else if (val == CP_CONTEXT_REG_BUNCH || val == CP_CONTEXT_REG_BUNCH2) {
425*61046927SAndroid Build Coastguard Worker             uint32_t *dw = dwords + 1;
426*61046927SAndroid Build Coastguard Worker             uint32_t cnt = count - 1;
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker             if (val == CP_CONTEXT_REG_BUNCH2) {
429*61046927SAndroid Build Coastguard Worker                if (options.no_reg_bunch) {
430*61046927SAndroid Build Coastguard Worker                   printlvl(level, "// CP_CONTEXT_REG_BUNCH2\n");
431*61046927SAndroid Build Coastguard Worker                   printlvl(level, "{\n");
432*61046927SAndroid Build Coastguard Worker                } else {
433*61046927SAndroid Build Coastguard Worker                   printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH2", cnt);
434*61046927SAndroid Build Coastguard Worker                   printlvl(level, "{\n");
435*61046927SAndroid Build Coastguard Worker                   printlvl(level + 1, "pkt(cs, 0x%x);\n", dw[0]);
436*61046927SAndroid Build Coastguard Worker                   printlvl(level + 1, "pkt(cs, 0x%x);\n", dw[1]);
437*61046927SAndroid Build Coastguard Worker                }
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker                dw += 2;
440*61046927SAndroid Build Coastguard Worker                cnt -= 2;
441*61046927SAndroid Build Coastguard Worker             } else {
442*61046927SAndroid Build Coastguard Worker                if (options.no_reg_bunch) {
443*61046927SAndroid Build Coastguard Worker                   printlvl(level, "// CP_CONTEXT_REG_BUNCH\n");
444*61046927SAndroid Build Coastguard Worker                   printlvl(level, "{\n");
445*61046927SAndroid Build Coastguard Worker                } else {
446*61046927SAndroid Build Coastguard Worker                   printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH", cnt);
447*61046927SAndroid Build Coastguard Worker                   printlvl(level, "{\n");
448*61046927SAndroid Build Coastguard Worker                }
449*61046927SAndroid Build Coastguard Worker             }
450*61046927SAndroid Build Coastguard Worker 
451*61046927SAndroid Build Coastguard Worker             for (uint32_t i = 0; i < cnt; i += 2) {
452*61046927SAndroid Build Coastguard Worker                if (options.no_reg_bunch) {
453*61046927SAndroid Build Coastguard Worker                   decompile_register(dw[i], &dw[i + 1], 1, level + 1);
454*61046927SAndroid Build Coastguard Worker                } else {
455*61046927SAndroid Build Coastguard Worker                   decompile_register_reg_bunch(dw[i], &dw[i + 1], 1, level + 1);
456*61046927SAndroid Build Coastguard Worker                }
457*61046927SAndroid Build Coastguard Worker             }
458*61046927SAndroid Build Coastguard Worker             printlvl(level, "}\n");
459*61046927SAndroid Build Coastguard Worker          } else if (val == CP_COND_REG_EXEC) {
460*61046927SAndroid Build Coastguard Worker             const char *packet_name = pktname(val);
461*61046927SAndroid Build Coastguard Worker             const char *dom_name = packet_name;
462*61046927SAndroid Build Coastguard Worker             uint32_t cond_count = dwords[count - 1];
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker             decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name, level);
465*61046927SAndroid Build Coastguard Worker 
466*61046927SAndroid Build Coastguard Worker             printlvl(level, "{\n");
467*61046927SAndroid Build Coastguard Worker             printlvl(level + 1, "/* BEGIN COND (%d DWORDS) */\n", cond_count);
468*61046927SAndroid Build Coastguard Worker 
469*61046927SAndroid Build Coastguard Worker             decompile_commands(dwords + count, cond_count, level + 1, &cond_count);
470*61046927SAndroid Build Coastguard Worker             count += cond_count;
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker             printlvl(level + 1, "/* END COND */\n");
473*61046927SAndroid Build Coastguard Worker             printlvl(level, "}\n");
474*61046927SAndroid Build Coastguard Worker          } else if (val == CP_NOP) {
475*61046927SAndroid Build Coastguard Worker             /* Prop will often use NOP past the end of cond execs
476*61046927SAndroid Build Coastguard Worker              * which basically create an else path for the cond exec
477*61046927SAndroid Build Coastguard Worker              */
478*61046927SAndroid Build Coastguard Worker             const char *packet_name = pktname(val);
479*61046927SAndroid Build Coastguard Worker             const char *dom_name = packet_name;
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker             if (count > dwords_left) {
482*61046927SAndroid Build Coastguard Worker                int else_cond_count = count - dwords_left;
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker                assert(cond_count);
485*61046927SAndroid Build Coastguard Worker                *cond_count += else_cond_count;
486*61046927SAndroid Build Coastguard Worker 
487*61046927SAndroid Build Coastguard Worker                printlvl(level, "pkt7(cs, %s, %u);\n", packet_name, count - 1);
488*61046927SAndroid Build Coastguard Worker                for (int i = 1; i < dwords_left; i++) {
489*61046927SAndroid Build Coastguard Worker                   printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
490*61046927SAndroid Build Coastguard Worker                }
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker                printlvl(level, "/* TO ELSE COND */\n");
493*61046927SAndroid Build Coastguard Worker                printlvl(level - 1, "}\n");
494*61046927SAndroid Build Coastguard Worker 
495*61046927SAndroid Build Coastguard Worker                printlvl(level - 1, "{\n");
496*61046927SAndroid Build Coastguard Worker                printlvl(level, "/* ELSE COND (%d DWORDS) */\n", else_cond_count);
497*61046927SAndroid Build Coastguard Worker                decompile_commands(dwords + dwords_left, else_cond_count, level, NULL);
498*61046927SAndroid Build Coastguard Worker 
499*61046927SAndroid Build Coastguard Worker                return;
500*61046927SAndroid Build Coastguard Worker             } else {
501*61046927SAndroid Build Coastguard Worker                decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name,
502*61046927SAndroid Build Coastguard Worker                                 level);
503*61046927SAndroid Build Coastguard Worker             }
504*61046927SAndroid Build Coastguard Worker          } else {
505*61046927SAndroid Build Coastguard Worker             const char *packet_name = pktname(val);
506*61046927SAndroid Build Coastguard Worker             const char *dom_name = packet_name;
507*61046927SAndroid Build Coastguard Worker             if (packet_name) {
508*61046927SAndroid Build Coastguard Worker                /* special hack for two packets that decode the same way
509*61046927SAndroid Build Coastguard Worker                 * on a6xx:
510*61046927SAndroid Build Coastguard Worker                 */
511*61046927SAndroid Build Coastguard Worker                if (!strcmp(packet_name, "CP_LOAD_STATE6_FRAG") ||
512*61046927SAndroid Build Coastguard Worker                    !strcmp(packet_name, "CP_LOAD_STATE6_GEOM"))
513*61046927SAndroid Build Coastguard Worker                   dom_name = "CP_LOAD_STATE6";
514*61046927SAndroid Build Coastguard Worker                decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name,
515*61046927SAndroid Build Coastguard Worker                                 level);
516*61046927SAndroid Build Coastguard Worker             } else {
517*61046927SAndroid Build Coastguard Worker                errx(1, "unknown pkt7 %u", val);
518*61046927SAndroid Build Coastguard Worker             }
519*61046927SAndroid Build Coastguard Worker          }
520*61046927SAndroid Build Coastguard Worker       } else {
521*61046927SAndroid Build Coastguard Worker          errx(1, "unknown packet %u", dwords[0]);
522*61046927SAndroid Build Coastguard Worker       }
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker       dwords += count;
525*61046927SAndroid Build Coastguard Worker       dwords_left -= count;
526*61046927SAndroid Build Coastguard Worker    }
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker    if (dwords_left < 0)
529*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "**** this ain't right!! dwords_left=%d\n", dwords_left);
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker static void
emit_header()533*61046927SAndroid Build Coastguard Worker emit_header()
534*61046927SAndroid Build Coastguard Worker {
535*61046927SAndroid Build Coastguard Worker    if (!dev_id.gpu_id && !dev_id.chip_id)
536*61046927SAndroid Build Coastguard Worker       return;
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker    static bool emitted = false;
539*61046927SAndroid Build Coastguard Worker    if (emitted)
540*61046927SAndroid Build Coastguard Worker       return;
541*61046927SAndroid Build Coastguard Worker    emitted = true;
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker    switch (fd_dev_gen(&dev_id)) {
544*61046927SAndroid Build Coastguard Worker    case 6:
545*61046927SAndroid Build Coastguard Worker       init_rnn("a6xx");
546*61046927SAndroid Build Coastguard Worker       break;
547*61046927SAndroid Build Coastguard Worker    case 7:
548*61046927SAndroid Build Coastguard Worker       init_rnn("a7xx");
549*61046927SAndroid Build Coastguard Worker       break;
550*61046927SAndroid Build Coastguard Worker    default:
551*61046927SAndroid Build Coastguard Worker       errx(-1, "unsupported gpu: %u", dev_id.gpu_id);
552*61046927SAndroid Build Coastguard Worker    }
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker    printf("#include \"decode/rdcompiler-utils.h\"\n"
555*61046927SAndroid Build Coastguard Worker           "int main(int argc, char **argv)\n"
556*61046927SAndroid Build Coastguard Worker           "{\n"
557*61046927SAndroid Build Coastguard Worker           "\tstruct replay_context ctx;\n"
558*61046927SAndroid Build Coastguard Worker           "\tstruct fd_dev_id dev_id = {%u, 0x%" PRIx64 "};\n"
559*61046927SAndroid Build Coastguard Worker           "\treplay_context_init(&ctx, &dev_id, argc, argv);\n"
560*61046927SAndroid Build Coastguard Worker           "\tstruct cmdstream *cs = ctx.submit_cs;\n\n",
561*61046927SAndroid Build Coastguard Worker           dev_id.gpu_id, dev_id.chip_id);
562*61046927SAndroid Build Coastguard Worker }
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker static inline uint32_t
u64_hash(const void * key)565*61046927SAndroid Build Coastguard Worker u64_hash(const void *key)
566*61046927SAndroid Build Coastguard Worker {
567*61046927SAndroid Build Coastguard Worker    return _mesa_hash_data(key, sizeof(uint64_t));
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker 
570*61046927SAndroid Build Coastguard Worker static inline bool
u64_compare(const void * key1,const void * key2)571*61046927SAndroid Build Coastguard Worker u64_compare(const void *key1, const void *key2)
572*61046927SAndroid Build Coastguard Worker {
573*61046927SAndroid Build Coastguard Worker    return memcmp(key1, key2, sizeof(uint64_t)) == 0;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker 
576*61046927SAndroid Build Coastguard Worker static int
handle_file(const char * filename,uint32_t submit_to_decompile)577*61046927SAndroid Build Coastguard Worker handle_file(const char *filename, uint32_t submit_to_decompile)
578*61046927SAndroid Build Coastguard Worker {
579*61046927SAndroid Build Coastguard Worker    struct io *io;
580*61046927SAndroid Build Coastguard Worker    int submit = 0;
581*61046927SAndroid Build Coastguard Worker    bool needs_reset = false;
582*61046927SAndroid Build Coastguard Worker    struct rd_parsed_section ps = {0};
583*61046927SAndroid Build Coastguard Worker 
584*61046927SAndroid Build Coastguard Worker    if (!strcmp(filename, "-"))
585*61046927SAndroid Build Coastguard Worker       io = io_openfd(0);
586*61046927SAndroid Build Coastguard Worker    else
587*61046927SAndroid Build Coastguard Worker       io = io_open(filename);
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker    if (!io) {
590*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "could not open: %s\n", filename);
591*61046927SAndroid Build Coastguard Worker       return -1;
592*61046927SAndroid Build Coastguard Worker    }
593*61046927SAndroid Build Coastguard Worker 
594*61046927SAndroid Build Coastguard Worker    type0_reg = reg_a6xx;
595*61046927SAndroid Build Coastguard Worker    mem_ctx = ralloc_context(NULL);
596*61046927SAndroid Build Coastguard Worker    _mesa_set_init(&decompiled_shaders, mem_ctx, u64_hash, u64_compare);
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker    struct {
599*61046927SAndroid Build Coastguard Worker       unsigned int len;
600*61046927SAndroid Build Coastguard Worker       uint64_t gpuaddr;
601*61046927SAndroid Build Coastguard Worker    } gpuaddr = {0};
602*61046927SAndroid Build Coastguard Worker 
603*61046927SAndroid Build Coastguard Worker    while (parse_rd_section(io, &ps)) {
604*61046927SAndroid Build Coastguard Worker       switch (ps.type) {
605*61046927SAndroid Build Coastguard Worker       case RD_TEST:
606*61046927SAndroid Build Coastguard Worker       case RD_VERT_SHADER:
607*61046927SAndroid Build Coastguard Worker       case RD_FRAG_SHADER:
608*61046927SAndroid Build Coastguard Worker       case RD_CMD:
609*61046927SAndroid Build Coastguard Worker          /* no-op */
610*61046927SAndroid Build Coastguard Worker          break;
611*61046927SAndroid Build Coastguard Worker       case RD_GPUADDR:
612*61046927SAndroid Build Coastguard Worker          if (needs_reset) {
613*61046927SAndroid Build Coastguard Worker             reset_buffers();
614*61046927SAndroid Build Coastguard Worker             needs_reset = false;
615*61046927SAndroid Build Coastguard Worker          }
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker          parse_addr(ps.buf, ps.sz, &gpuaddr.len, &gpuaddr.gpuaddr);
618*61046927SAndroid Build Coastguard Worker          break;
619*61046927SAndroid Build Coastguard Worker       case RD_BUFFER_CONTENTS:
620*61046927SAndroid Build Coastguard Worker          add_buffer(gpuaddr.gpuaddr, gpuaddr.len, ps.buf);
621*61046927SAndroid Build Coastguard Worker          ps.buf = NULL;
622*61046927SAndroid Build Coastguard Worker          break;
623*61046927SAndroid Build Coastguard Worker       case RD_CMDSTREAM_ADDR: {
624*61046927SAndroid Build Coastguard Worker          unsigned int sizedwords;
625*61046927SAndroid Build Coastguard Worker          uint64_t gpuaddr;
626*61046927SAndroid Build Coastguard Worker          parse_addr(ps.buf, ps.sz, &sizedwords, &gpuaddr);
627*61046927SAndroid Build Coastguard Worker 
628*61046927SAndroid Build Coastguard Worker          if (submit == submit_to_decompile) {
629*61046927SAndroid Build Coastguard Worker             decompile_commands(hostptr(gpuaddr), sizedwords, 0, NULL);
630*61046927SAndroid Build Coastguard Worker          }
631*61046927SAndroid Build Coastguard Worker 
632*61046927SAndroid Build Coastguard Worker          needs_reset = true;
633*61046927SAndroid Build Coastguard Worker          submit++;
634*61046927SAndroid Build Coastguard Worker          break;
635*61046927SAndroid Build Coastguard Worker       }
636*61046927SAndroid Build Coastguard Worker       case RD_GPU_ID: {
637*61046927SAndroid Build Coastguard Worker          dev_id.gpu_id = parse_gpu_id(ps.buf);
638*61046927SAndroid Build Coastguard Worker          if (fd_dev_info_raw(&dev_id))
639*61046927SAndroid Build Coastguard Worker             emit_header();
640*61046927SAndroid Build Coastguard Worker          break;
641*61046927SAndroid Build Coastguard Worker       }
642*61046927SAndroid Build Coastguard Worker       case RD_CHIP_ID: {
643*61046927SAndroid Build Coastguard Worker          dev_id.chip_id = parse_chip_id(ps.buf);
644*61046927SAndroid Build Coastguard Worker          if (fd_dev_info_raw(&dev_id))
645*61046927SAndroid Build Coastguard Worker             emit_header();
646*61046927SAndroid Build Coastguard Worker          break;
647*61046927SAndroid Build Coastguard Worker       }
648*61046927SAndroid Build Coastguard Worker       default:
649*61046927SAndroid Build Coastguard Worker          break;
650*61046927SAndroid Build Coastguard Worker       }
651*61046927SAndroid Build Coastguard Worker    }
652*61046927SAndroid Build Coastguard Worker 
653*61046927SAndroid Build Coastguard Worker    printf("\treplay_context_finish(&ctx);\n}");
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker    io_close(io);
656*61046927SAndroid Build Coastguard Worker    fflush(stdout);
657*61046927SAndroid Build Coastguard Worker 
658*61046927SAndroid Build Coastguard Worker    if (ps.ret < 0) {
659*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "corrupt file\n");
660*61046927SAndroid Build Coastguard Worker    }
661*61046927SAndroid Build Coastguard Worker    return 0;
662*61046927SAndroid Build Coastguard Worker }
663