xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/cffdec.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2012 Rob Clark <[email protected]>
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 <inttypes.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/stat.h>
21*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
22*61046927SAndroid Build Coastguard Worker #include <sys/wait.h>
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include "buffers.h"
27*61046927SAndroid Build Coastguard Worker #include "cffdec.h"
28*61046927SAndroid Build Coastguard Worker #include "disasm.h"
29*61046927SAndroid Build Coastguard Worker #include "redump.h"
30*61046927SAndroid Build Coastguard Worker #include "rnnutil.h"
31*61046927SAndroid Build Coastguard Worker #include "script.h"
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker /* ************************************************************************* */
34*61046927SAndroid Build Coastguard Worker /* originally based on kernel recovery dump code: */
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker static const struct cffdec_options *options;
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker static bool needs_wfi = false;
39*61046927SAndroid Build Coastguard Worker static bool summary = false;
40*61046927SAndroid Build Coastguard Worker static bool in_summary = false;
41*61046927SAndroid Build Coastguard Worker static int vertices;
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker static inline unsigned
regcnt(void)44*61046927SAndroid Build Coastguard Worker regcnt(void)
45*61046927SAndroid Build Coastguard Worker {
46*61046927SAndroid Build Coastguard Worker    if (options->info->chip >= 5)
47*61046927SAndroid Build Coastguard Worker       return 0x3ffff;
48*61046927SAndroid Build Coastguard Worker    else
49*61046927SAndroid Build Coastguard Worker       return 0x7fff;
50*61046927SAndroid Build Coastguard Worker }
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker static int
is_64b(void)53*61046927SAndroid Build Coastguard Worker is_64b(void)
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker    return options->info->chip >= 5;
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker static int draws[4];
59*61046927SAndroid Build Coastguard Worker static struct {
60*61046927SAndroid Build Coastguard Worker    uint64_t base;
61*61046927SAndroid Build Coastguard Worker    uint32_t size; /* in dwords */
62*61046927SAndroid Build Coastguard Worker    /* Generally cmdstream consists of multiple IB calls to different
63*61046927SAndroid Build Coastguard Worker     * buffers, which are themselves often re-used for each tile.  The
64*61046927SAndroid Build Coastguard Worker     * triggered flag serves two purposes to help make it more clear
65*61046927SAndroid Build Coastguard Worker     * what part of the cmdstream is before vs after the the GPU hang:
66*61046927SAndroid Build Coastguard Worker     *
67*61046927SAndroid Build Coastguard Worker     * 1) if in IB2 we are passed the point within the IB2 buffer where
68*61046927SAndroid Build Coastguard Worker     *    the GPU hung, but IB1 is not passed the point within its
69*61046927SAndroid Build Coastguard Worker     *    buffer where the GPU had hung, then we know the GPU hang
70*61046927SAndroid Build Coastguard Worker     *    happens on a future use of that IB2 buffer.
71*61046927SAndroid Build Coastguard Worker     *
72*61046927SAndroid Build Coastguard Worker     * 2) if in an IB1 or IB2 buffer that is not the one where the GPU
73*61046927SAndroid Build Coastguard Worker     *    hung, but we've already passed the trigger point at the same
74*61046927SAndroid Build Coastguard Worker     *    IB level, we know that we are passed the point where the GPU
75*61046927SAndroid Build Coastguard Worker     *    had hung.
76*61046927SAndroid Build Coastguard Worker     *
77*61046927SAndroid Build Coastguard Worker     * So this is a one way switch, false->true.  And a higher #'d
78*61046927SAndroid Build Coastguard Worker     * IB level isn't considered triggered unless the lower #'d IB
79*61046927SAndroid Build Coastguard Worker     * level is.
80*61046927SAndroid Build Coastguard Worker     */
81*61046927SAndroid Build Coastguard Worker    bool triggered : 1;
82*61046927SAndroid Build Coastguard Worker    bool base_seen : 1;
83*61046927SAndroid Build Coastguard Worker } ibs[4];
84*61046927SAndroid Build Coastguard Worker static int ib;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker static int draw_count;
87*61046927SAndroid Build Coastguard Worker static int current_draw_count;
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker /* query mode.. to handle symbolic register name queries, we need to
90*61046927SAndroid Build Coastguard Worker  * defer parsing query string until after gpu_id is know and rnn db
91*61046927SAndroid Build Coastguard Worker  * loaded:
92*61046927SAndroid Build Coastguard Worker  */
93*61046927SAndroid Build Coastguard Worker static int *queryvals;
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker static bool
quiet(int lvl)96*61046927SAndroid Build Coastguard Worker quiet(int lvl)
97*61046927SAndroid Build Coastguard Worker {
98*61046927SAndroid Build Coastguard Worker    if ((options->draw_filter != -1) &&
99*61046927SAndroid Build Coastguard Worker        (options->draw_filter != current_draw_count))
100*61046927SAndroid Build Coastguard Worker       return true;
101*61046927SAndroid Build Coastguard Worker    if ((lvl >= 3) && (summary || options->querystrs || options->script))
102*61046927SAndroid Build Coastguard Worker       return true;
103*61046927SAndroid Build Coastguard Worker    if ((lvl >= 2) && (options->querystrs || options->script))
104*61046927SAndroid Build Coastguard Worker       return true;
105*61046927SAndroid Build Coastguard Worker    return false;
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker void
printl(int lvl,const char * fmt,...)109*61046927SAndroid Build Coastguard Worker printl(int lvl, const char *fmt, ...)
110*61046927SAndroid Build Coastguard Worker {
111*61046927SAndroid Build Coastguard Worker    va_list args;
112*61046927SAndroid Build Coastguard Worker    if (quiet(lvl))
113*61046927SAndroid Build Coastguard Worker       return;
114*61046927SAndroid Build Coastguard Worker    va_start(args, fmt);
115*61046927SAndroid Build Coastguard Worker    vprintf(fmt, args);
116*61046927SAndroid Build Coastguard Worker    va_end(args);
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker static const char *levels[] = {
120*61046927SAndroid Build Coastguard Worker    "\t",
121*61046927SAndroid Build Coastguard Worker    "\t\t",
122*61046927SAndroid Build Coastguard Worker    "\t\t\t",
123*61046927SAndroid Build Coastguard Worker    "\t\t\t\t",
124*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t",
125*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t",
126*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t",
127*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t\t",
128*61046927SAndroid Build Coastguard Worker    "\t\t\t\t\t\t\t\t\t",
129*61046927SAndroid Build Coastguard Worker    "x",
130*61046927SAndroid Build Coastguard Worker    "x",
131*61046927SAndroid Build Coastguard Worker    "x",
132*61046927SAndroid Build Coastguard Worker    "x",
133*61046927SAndroid Build Coastguard Worker    "x",
134*61046927SAndroid Build Coastguard Worker    "x",
135*61046927SAndroid Build Coastguard Worker };
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker enum state_src_t {
138*61046927SAndroid Build Coastguard Worker    STATE_SRC_DIRECT,
139*61046927SAndroid Build Coastguard Worker    STATE_SRC_INDIRECT,
140*61046927SAndroid Build Coastguard Worker    STATE_SRC_BINDLESS,
141*61046927SAndroid Build Coastguard Worker };
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker /* SDS (CP_SET_DRAW_STATE) helpers: */
144*61046927SAndroid Build Coastguard Worker static void load_all_groups(int level);
145*61046927SAndroid Build Coastguard Worker static void disable_all_groups(void);
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker static void dump_tex_samp(uint32_t *texsamp, enum state_src_t src, int num_unit,
148*61046927SAndroid Build Coastguard Worker                           int level);
149*61046927SAndroid Build Coastguard Worker static void dump_tex_const(uint32_t *texsamp, int num_unit, int level);
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker static bool
highlight_gpuaddr(uint64_t gpuaddr)152*61046927SAndroid Build Coastguard Worker highlight_gpuaddr(uint64_t gpuaddr)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker    if (!options->ibs[ib].base)
155*61046927SAndroid Build Coastguard Worker       return false;
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker    if ((ib > 0) && options->ibs[ib - 1].base &&
158*61046927SAndroid Build Coastguard Worker        !(ibs[ib - 1].triggered || ibs[ib - 1].base_seen))
159*61046927SAndroid Build Coastguard Worker       return false;
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker    if (ibs[ib].base_seen)
162*61046927SAndroid Build Coastguard Worker       return false;
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker    if (ibs[ib].triggered)
165*61046927SAndroid Build Coastguard Worker       return options->color;
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker    if (options->ibs[ib].base != ibs[ib].base)
168*61046927SAndroid Build Coastguard Worker       return false;
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker    uint64_t start = ibs[ib].base + 4 * (ibs[ib].size - options->ibs[ib].rem);
171*61046927SAndroid Build Coastguard Worker    uint64_t end = ibs[ib].base + 4 * ibs[ib].size;
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    bool triggered = (start <= gpuaddr) && (gpuaddr <= end);
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    if (triggered && (ib < 2) && options->ibs[ib + 1].crash_found) {
176*61046927SAndroid Build Coastguard Worker       ibs[ib].base_seen = true;
177*61046927SAndroid Build Coastguard Worker       return false;
178*61046927SAndroid Build Coastguard Worker    }
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    ibs[ib].triggered |= triggered;
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    if (triggered)
183*61046927SAndroid Build Coastguard Worker       printf("ESTIMATED CRASH LOCATION!\n");
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    return triggered & options->color;
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker static void
dump_hex(uint32_t * dwords,uint32_t sizedwords,int level)189*61046927SAndroid Build Coastguard Worker dump_hex(uint32_t *dwords, uint32_t sizedwords, int level)
190*61046927SAndroid Build Coastguard Worker {
191*61046927SAndroid Build Coastguard Worker    int i, j;
192*61046927SAndroid Build Coastguard Worker    int lastzero = 1;
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    if (quiet(2))
195*61046927SAndroid Build Coastguard Worker       return;
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    bool highlight = highlight_gpuaddr(gpuaddr(dwords) + 4 * sizedwords - 1);
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords; i += 8) {
200*61046927SAndroid Build Coastguard Worker       int zero = 1;
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker       /* always show first row: */
203*61046927SAndroid Build Coastguard Worker       if (i == 0)
204*61046927SAndroid Build Coastguard Worker          zero = 0;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       for (j = 0; (j < 8) && (i + j < sizedwords) && zero; j++)
207*61046927SAndroid Build Coastguard Worker          if (dwords[i + j])
208*61046927SAndroid Build Coastguard Worker             zero = 0;
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker       if (zero && !lastzero)
211*61046927SAndroid Build Coastguard Worker          printf("*\n");
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker       lastzero = zero;
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker       if (zero)
216*61046927SAndroid Build Coastguard Worker          continue;
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker       uint64_t addr = gpuaddr(&dwords[i]);
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker       if (highlight)
221*61046927SAndroid Build Coastguard Worker          printf("\x1b[0;1;31m");
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker       if (is_64b()) {
224*61046927SAndroid Build Coastguard Worker          printf("%016" PRIx64 ":%s", addr, levels[level]);
225*61046927SAndroid Build Coastguard Worker       } else {
226*61046927SAndroid Build Coastguard Worker          printf("%08x:%s", (uint32_t)addr, levels[level]);
227*61046927SAndroid Build Coastguard Worker       }
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker       if (highlight)
230*61046927SAndroid Build Coastguard Worker          printf("\x1b[0m");
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker       printf("%04x:", i * 4);
233*61046927SAndroid Build Coastguard Worker 
234*61046927SAndroid Build Coastguard Worker       for (j = 0; (j < 8) && (i + j < sizedwords); j++) {
235*61046927SAndroid Build Coastguard Worker          printf(" %08x", dwords[i + j]);
236*61046927SAndroid Build Coastguard Worker       }
237*61046927SAndroid Build Coastguard Worker 
238*61046927SAndroid Build Coastguard Worker       printf("\n");
239*61046927SAndroid Build Coastguard Worker    }
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker static void
dump_float(float * dwords,uint32_t sizedwords,int level)243*61046927SAndroid Build Coastguard Worker dump_float(float *dwords, uint32_t sizedwords, int level)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker    int i;
246*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords; i++) {
247*61046927SAndroid Build Coastguard Worker       if ((i % 8) == 0) {
248*61046927SAndroid Build Coastguard Worker          if (is_64b()) {
249*61046927SAndroid Build Coastguard Worker             printf("%016" PRIx64 ":%s", gpuaddr(dwords), levels[level]);
250*61046927SAndroid Build Coastguard Worker          } else {
251*61046927SAndroid Build Coastguard Worker             printf("%08x:%s", (uint32_t)gpuaddr(dwords), levels[level]);
252*61046927SAndroid Build Coastguard Worker          }
253*61046927SAndroid Build Coastguard Worker       } else {
254*61046927SAndroid Build Coastguard Worker          printf(" ");
255*61046927SAndroid Build Coastguard Worker       }
256*61046927SAndroid Build Coastguard Worker       printf("%8f", *(dwords++));
257*61046927SAndroid Build Coastguard Worker       if ((i % 8) == 7)
258*61046927SAndroid Build Coastguard Worker          printf("\n");
259*61046927SAndroid Build Coastguard Worker    }
260*61046927SAndroid Build Coastguard Worker    if (i % 8)
261*61046927SAndroid Build Coastguard Worker       printf("\n");
262*61046927SAndroid Build Coastguard Worker }
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker /* I believe the surface format is low bits:
265*61046927SAndroid Build Coastguard Worker #define RB_COLOR_INFO__COLOR_FORMAT_MASK                   0x0000000fL
266*61046927SAndroid Build Coastguard Worker comments in sys2gmem_tex_const indicate that address is [31:12], but
267*61046927SAndroid Build Coastguard Worker looks like at least some of the bits above the format have different meaning..
268*61046927SAndroid Build Coastguard Worker */
269*61046927SAndroid Build Coastguard Worker static void
parse_dword_addr(uint32_t dword,uint32_t * gpuaddr,uint32_t * flags,uint32_t mask)270*61046927SAndroid Build Coastguard Worker parse_dword_addr(uint32_t dword, uint32_t *gpuaddr, uint32_t *flags,
271*61046927SAndroid Build Coastguard Worker                  uint32_t mask)
272*61046927SAndroid Build Coastguard Worker {
273*61046927SAndroid Build Coastguard Worker    assert(!is_64b()); /* this is only used on a2xx */
274*61046927SAndroid Build Coastguard Worker    *gpuaddr = dword & ~mask;
275*61046927SAndroid Build Coastguard Worker    *flags = dword & mask;
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker static uint32_t type0_reg_vals[0x3ffff + 1];
279*61046927SAndroid Build Coastguard Worker static uint8_t type0_reg_rewritten[sizeof(type0_reg_vals) /
280*61046927SAndroid Build Coastguard Worker                                    8]; /* written since last draw */
281*61046927SAndroid Build Coastguard Worker static uint8_t type0_reg_written[sizeof(type0_reg_vals) / 8];
282*61046927SAndroid Build Coastguard Worker static uint32_t lastvals[ARRAY_SIZE(type0_reg_vals)];
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker static bool
reg_rewritten(uint32_t regbase)285*61046927SAndroid Build Coastguard Worker reg_rewritten(uint32_t regbase)
286*61046927SAndroid Build Coastguard Worker {
287*61046927SAndroid Build Coastguard Worker    return !!(type0_reg_rewritten[regbase / 8] & (1 << (regbase % 8)));
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker bool
reg_written(uint32_t regbase)291*61046927SAndroid Build Coastguard Worker reg_written(uint32_t regbase)
292*61046927SAndroid Build Coastguard Worker {
293*61046927SAndroid Build Coastguard Worker    return !!(type0_reg_written[regbase / 8] & (1 << (regbase % 8)));
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker static void
clear_rewritten(void)297*61046927SAndroid Build Coastguard Worker clear_rewritten(void)
298*61046927SAndroid Build Coastguard Worker {
299*61046927SAndroid Build Coastguard Worker    memset(type0_reg_rewritten, 0, sizeof(type0_reg_rewritten));
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker static void
clear_written(void)303*61046927SAndroid Build Coastguard Worker clear_written(void)
304*61046927SAndroid Build Coastguard Worker {
305*61046927SAndroid Build Coastguard Worker    memset(type0_reg_written, 0, sizeof(type0_reg_written));
306*61046927SAndroid Build Coastguard Worker    clear_rewritten();
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker uint32_t
reg_lastval(uint32_t regbase)310*61046927SAndroid Build Coastguard Worker reg_lastval(uint32_t regbase)
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker    return lastvals[regbase];
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker 
315*61046927SAndroid Build Coastguard Worker static void
clear_lastvals(void)316*61046927SAndroid Build Coastguard Worker clear_lastvals(void)
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker    memset(lastvals, 0, sizeof(lastvals));
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker uint32_t
reg_val(uint32_t regbase)322*61046927SAndroid Build Coastguard Worker reg_val(uint32_t regbase)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker    return type0_reg_vals[regbase];
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker void
reg_set(uint32_t regbase,uint32_t val)328*61046927SAndroid Build Coastguard Worker reg_set(uint32_t regbase, uint32_t val)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker    assert(regbase < regcnt());
331*61046927SAndroid Build Coastguard Worker    type0_reg_vals[regbase] = val;
332*61046927SAndroid Build Coastguard Worker    type0_reg_written[regbase / 8] |= (1 << (regbase % 8));
333*61046927SAndroid Build Coastguard Worker    type0_reg_rewritten[regbase / 8] |= (1 << (regbase % 8));
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker static void
reg_dump_scratch(const char * name,uint32_t dword,int level)337*61046927SAndroid Build Coastguard Worker reg_dump_scratch(const char *name, uint32_t dword, int level)
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker    unsigned r;
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker    if (quiet(3))
342*61046927SAndroid Build Coastguard Worker       return;
343*61046927SAndroid Build Coastguard Worker 
344*61046927SAndroid Build Coastguard Worker    r = regbase("CP_SCRATCH[0].REG");
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker    // if not, try old a2xx/a3xx version:
347*61046927SAndroid Build Coastguard Worker    if (!r)
348*61046927SAndroid Build Coastguard Worker       r = regbase("CP_SCRATCH_REG0");
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker    if (!r)
351*61046927SAndroid Build Coastguard Worker       return;
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker    printf("%s:%u,%u,%u,%u\n", levels[level], reg_val(r + 4), reg_val(r + 5),
354*61046927SAndroid Build Coastguard Worker           reg_val(r + 6), reg_val(r + 7));
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker static void
dump_gpuaddr_size(uint64_t gpuaddr,int level,int sizedwords,int quietlvl)358*61046927SAndroid Build Coastguard Worker dump_gpuaddr_size(uint64_t gpuaddr, int level, int sizedwords, int quietlvl)
359*61046927SAndroid Build Coastguard Worker {
360*61046927SAndroid Build Coastguard Worker    void *buf;
361*61046927SAndroid Build Coastguard Worker 
362*61046927SAndroid Build Coastguard Worker    if (quiet(quietlvl))
363*61046927SAndroid Build Coastguard Worker       return;
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker    buf = hostptr(gpuaddr);
366*61046927SAndroid Build Coastguard Worker    if (buf) {
367*61046927SAndroid Build Coastguard Worker       dump_hex(buf, sizedwords, level + 1);
368*61046927SAndroid Build Coastguard Worker    }
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker static void
dump_gpuaddr(uint64_t gpuaddr,int level)372*61046927SAndroid Build Coastguard Worker dump_gpuaddr(uint64_t gpuaddr, int level)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker    dump_gpuaddr_size(gpuaddr, level, 64, 3);
375*61046927SAndroid Build Coastguard Worker }
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker static void
reg_dump_gpuaddr(const char * name,uint32_t dword,int level)378*61046927SAndroid Build Coastguard Worker reg_dump_gpuaddr(const char *name, uint32_t dword, int level)
379*61046927SAndroid Build Coastguard Worker {
380*61046927SAndroid Build Coastguard Worker    dump_gpuaddr(dword, level);
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker uint32_t gpuaddr_lo;
384*61046927SAndroid Build Coastguard Worker static void
reg_gpuaddr_lo(const char * name,uint32_t dword,int level)385*61046927SAndroid Build Coastguard Worker reg_gpuaddr_lo(const char *name, uint32_t dword, int level)
386*61046927SAndroid Build Coastguard Worker {
387*61046927SAndroid Build Coastguard Worker    gpuaddr_lo = dword;
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker static void
reg_dump_gpuaddr_hi(const char * name,uint32_t dword,int level)391*61046927SAndroid Build Coastguard Worker reg_dump_gpuaddr_hi(const char *name, uint32_t dword, int level)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker    dump_gpuaddr(gpuaddr_lo | (((uint64_t)dword) << 32), level);
394*61046927SAndroid Build Coastguard Worker }
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker static void
reg_dump_gpuaddr64(const char * name,uint64_t qword,int level)397*61046927SAndroid Build Coastguard Worker reg_dump_gpuaddr64(const char *name, uint64_t qword, int level)
398*61046927SAndroid Build Coastguard Worker {
399*61046927SAndroid Build Coastguard Worker    dump_gpuaddr(qword, level);
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker static void
dump_shader(const char * ext,void * buf,int bufsz)403*61046927SAndroid Build Coastguard Worker dump_shader(const char *ext, void *buf, int bufsz)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker    if (options->dump_shaders) {
406*61046927SAndroid Build Coastguard Worker       static int n = 0;
407*61046927SAndroid Build Coastguard Worker       char filename[16];
408*61046927SAndroid Build Coastguard Worker       int fd;
409*61046927SAndroid Build Coastguard Worker       sprintf(filename, "%04d.%s", n++, ext);
410*61046927SAndroid Build Coastguard Worker       fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644);
411*61046927SAndroid Build Coastguard Worker       if (fd != -1) {
412*61046927SAndroid Build Coastguard Worker          write(fd, buf, bufsz);
413*61046927SAndroid Build Coastguard Worker          close(fd);
414*61046927SAndroid Build Coastguard Worker       }
415*61046927SAndroid Build Coastguard Worker    }
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker 
418*61046927SAndroid Build Coastguard Worker static void
disasm_gpuaddr(const char * name,uint64_t gpuaddr,int level)419*61046927SAndroid Build Coastguard Worker disasm_gpuaddr(const char *name, uint64_t gpuaddr, int level)
420*61046927SAndroid Build Coastguard Worker {
421*61046927SAndroid Build Coastguard Worker    void *buf;
422*61046927SAndroid Build Coastguard Worker 
423*61046927SAndroid Build Coastguard Worker    gpuaddr &= 0xfffffffffffffff0;
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker    if (quiet(3))
426*61046927SAndroid Build Coastguard Worker       return;
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    buf = hostptr(gpuaddr);
429*61046927SAndroid Build Coastguard Worker    if (buf) {
430*61046927SAndroid Build Coastguard Worker       uint32_t sizedwords = hostlen(gpuaddr) / 4;
431*61046927SAndroid Build Coastguard Worker       const char *ext;
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker       dump_hex(buf, MIN2(64, sizedwords), level + 1);
434*61046927SAndroid Build Coastguard Worker       try_disasm_a3xx(buf, sizedwords, level + 2, stdout, options->info->chip * 100);
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker       /* this is a bit ugly way, but oh well.. */
437*61046927SAndroid Build Coastguard Worker       if (strstr(name, "SP_VS_OBJ")) {
438*61046927SAndroid Build Coastguard Worker          ext = "vo3";
439*61046927SAndroid Build Coastguard Worker       } else if (strstr(name, "SP_FS_OBJ")) {
440*61046927SAndroid Build Coastguard Worker          ext = "fo3";
441*61046927SAndroid Build Coastguard Worker       } else if (strstr(name, "SP_GS_OBJ")) {
442*61046927SAndroid Build Coastguard Worker          ext = "go3";
443*61046927SAndroid Build Coastguard Worker       } else if (strstr(name, "SP_CS_OBJ")) {
444*61046927SAndroid Build Coastguard Worker          ext = "co3";
445*61046927SAndroid Build Coastguard Worker       } else {
446*61046927SAndroid Build Coastguard Worker          ext = NULL;
447*61046927SAndroid Build Coastguard Worker       }
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker       if (ext)
450*61046927SAndroid Build Coastguard Worker          dump_shader(ext, buf, sizedwords * 4);
451*61046927SAndroid Build Coastguard Worker    }
452*61046927SAndroid Build Coastguard Worker }
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker static void
reg_disasm_gpuaddr(const char * name,uint32_t dword,int level)455*61046927SAndroid Build Coastguard Worker reg_disasm_gpuaddr(const char *name, uint32_t dword, int level)
456*61046927SAndroid Build Coastguard Worker {
457*61046927SAndroid Build Coastguard Worker    disasm_gpuaddr(name, dword, level);
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker static void
reg_disasm_gpuaddr_hi(const char * name,uint32_t dword,int level)461*61046927SAndroid Build Coastguard Worker reg_disasm_gpuaddr_hi(const char *name, uint32_t dword, int level)
462*61046927SAndroid Build Coastguard Worker {
463*61046927SAndroid Build Coastguard Worker    disasm_gpuaddr(name, gpuaddr_lo | (((uint64_t)dword) << 32), level);
464*61046927SAndroid Build Coastguard Worker }
465*61046927SAndroid Build Coastguard Worker 
466*61046927SAndroid Build Coastguard Worker static void
reg_disasm_gpuaddr64(const char * name,uint64_t qword,int level)467*61046927SAndroid Build Coastguard Worker reg_disasm_gpuaddr64(const char *name, uint64_t qword, int level)
468*61046927SAndroid Build Coastguard Worker {
469*61046927SAndroid Build Coastguard Worker    disasm_gpuaddr(name, qword, level);
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker /* Find the value of the TEX_COUNT register that corresponds to the named
473*61046927SAndroid Build Coastguard Worker  * TEX_SAMP/TEX_CONST reg.
474*61046927SAndroid Build Coastguard Worker  *
475*61046927SAndroid Build Coastguard Worker  * Note, this kinda assumes an equal # of samplers and textures, but not
476*61046927SAndroid Build Coastguard Worker  * really sure if there is a much better option.  I suppose on a6xx we
477*61046927SAndroid Build Coastguard Worker  * could instead decode the bitfields in SP_xS_CONFIG
478*61046927SAndroid Build Coastguard Worker  */
479*61046927SAndroid Build Coastguard Worker static int
get_tex_count(const char * name)480*61046927SAndroid Build Coastguard Worker get_tex_count(const char *name)
481*61046927SAndroid Build Coastguard Worker {
482*61046927SAndroid Build Coastguard Worker    char count_reg[strlen(name) + 5];
483*61046927SAndroid Build Coastguard Worker    char *p;
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker    p = strstr(name, "CONST");
486*61046927SAndroid Build Coastguard Worker    if (!p)
487*61046927SAndroid Build Coastguard Worker       p = strstr(name, "SAMP");
488*61046927SAndroid Build Coastguard Worker    if (!p)
489*61046927SAndroid Build Coastguard Worker       return 0;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker    int n = p - name;
492*61046927SAndroid Build Coastguard Worker    strncpy(count_reg, name, n);
493*61046927SAndroid Build Coastguard Worker    strcpy(count_reg + n, "COUNT");
494*61046927SAndroid Build Coastguard Worker 
495*61046927SAndroid Build Coastguard Worker    return reg_val(regbase(count_reg));
496*61046927SAndroid Build Coastguard Worker }
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker static void
reg_dump_tex_samp_hi(const char * name,uint32_t dword,int level)499*61046927SAndroid Build Coastguard Worker reg_dump_tex_samp_hi(const char *name, uint32_t dword, int level)
500*61046927SAndroid Build Coastguard Worker {
501*61046927SAndroid Build Coastguard Worker    if (!in_summary)
502*61046927SAndroid Build Coastguard Worker       return;
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker    int num_unit = get_tex_count(name);
505*61046927SAndroid Build Coastguard Worker    uint64_t gpuaddr = gpuaddr_lo | (((uint64_t)dword) << 32);
506*61046927SAndroid Build Coastguard Worker    void *buf = hostptr(gpuaddr);
507*61046927SAndroid Build Coastguard Worker 
508*61046927SAndroid Build Coastguard Worker    if (!buf)
509*61046927SAndroid Build Coastguard Worker       return;
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker    dump_tex_samp(buf, STATE_SRC_DIRECT, num_unit, level + 1);
512*61046927SAndroid Build Coastguard Worker }
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker static void
reg_dump_tex_const_hi(const char * name,uint32_t dword,int level)515*61046927SAndroid Build Coastguard Worker reg_dump_tex_const_hi(const char *name, uint32_t dword, int level)
516*61046927SAndroid Build Coastguard Worker {
517*61046927SAndroid Build Coastguard Worker    if (!in_summary)
518*61046927SAndroid Build Coastguard Worker       return;
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker    int num_unit = get_tex_count(name);
521*61046927SAndroid Build Coastguard Worker    uint64_t gpuaddr = gpuaddr_lo | (((uint64_t)dword) << 32);
522*61046927SAndroid Build Coastguard Worker    void *buf = hostptr(gpuaddr);
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker    if (!buf)
525*61046927SAndroid Build Coastguard Worker       return;
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker    dump_tex_const(buf, num_unit, level + 1);
528*61046927SAndroid Build Coastguard Worker }
529*61046927SAndroid Build Coastguard Worker 
530*61046927SAndroid Build Coastguard Worker /*
531*61046927SAndroid Build Coastguard Worker  * Registers with special handling (rnndec_decode() handles rest):
532*61046927SAndroid Build Coastguard Worker  */
533*61046927SAndroid Build Coastguard Worker #define REG(x, fxn)    { #x, fxn }
534*61046927SAndroid Build Coastguard Worker #define REG64(x, fxn)  { #x, .fxn64 = fxn, .is_reg64 = true }
535*61046927SAndroid Build Coastguard Worker static struct {
536*61046927SAndroid Build Coastguard Worker    const char *regname;
537*61046927SAndroid Build Coastguard Worker    void (*fxn)(const char *name, uint32_t dword, int level);
538*61046927SAndroid Build Coastguard Worker    void (*fxn64)(const char *name, uint64_t qword, int level);
539*61046927SAndroid Build Coastguard Worker    uint32_t regbase;
540*61046927SAndroid Build Coastguard Worker    bool is_reg64;
541*61046927SAndroid Build Coastguard Worker } reg_a2xx[] = {
542*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG0, reg_dump_scratch),
543*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG1, reg_dump_scratch),
544*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG2, reg_dump_scratch),
545*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG3, reg_dump_scratch),
546*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG4, reg_dump_scratch),
547*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG5, reg_dump_scratch),
548*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG6, reg_dump_scratch),
549*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG7, reg_dump_scratch),
550*61046927SAndroid Build Coastguard Worker       {NULL},
551*61046927SAndroid Build Coastguard Worker }, reg_a3xx[] = {
552*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG0, reg_dump_scratch),
553*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG1, reg_dump_scratch),
554*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG2, reg_dump_scratch),
555*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG3, reg_dump_scratch),
556*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG4, reg_dump_scratch),
557*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG5, reg_dump_scratch),
558*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG6, reg_dump_scratch),
559*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH_REG7, reg_dump_scratch),
560*61046927SAndroid Build Coastguard Worker       REG(VSC_SIZE_ADDRESS, reg_dump_gpuaddr),
561*61046927SAndroid Build Coastguard Worker       REG(SP_VS_PVT_MEM_ADDR_REG, reg_dump_gpuaddr),
562*61046927SAndroid Build Coastguard Worker       REG(SP_FS_PVT_MEM_ADDR_REG, reg_dump_gpuaddr),
563*61046927SAndroid Build Coastguard Worker       REG(SP_VS_OBJ_START_REG, reg_disasm_gpuaddr),
564*61046927SAndroid Build Coastguard Worker       REG(SP_FS_OBJ_START_REG, reg_disasm_gpuaddr),
565*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_FS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
566*61046927SAndroid Build Coastguard Worker       {NULL},
567*61046927SAndroid Build Coastguard Worker }, reg_a4xx[] = {
568*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0].REG, reg_dump_scratch),
569*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x1].REG, reg_dump_scratch),
570*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x2].REG, reg_dump_scratch),
571*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x3].REG, reg_dump_scratch),
572*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x4].REG, reg_dump_scratch),
573*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x5].REG, reg_dump_scratch),
574*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x6].REG, reg_dump_scratch),
575*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x7].REG, reg_dump_scratch),
576*61046927SAndroid Build Coastguard Worker       REG(SP_VS_PVT_MEM_ADDR, reg_dump_gpuaddr),
577*61046927SAndroid Build Coastguard Worker       REG(SP_FS_PVT_MEM_ADDR, reg_dump_gpuaddr),
578*61046927SAndroid Build Coastguard Worker       REG(SP_GS_PVT_MEM_ADDR, reg_dump_gpuaddr),
579*61046927SAndroid Build Coastguard Worker       REG(SP_HS_PVT_MEM_ADDR, reg_dump_gpuaddr),
580*61046927SAndroid Build Coastguard Worker       REG(SP_DS_PVT_MEM_ADDR, reg_dump_gpuaddr),
581*61046927SAndroid Build Coastguard Worker       REG(SP_CS_PVT_MEM_ADDR, reg_dump_gpuaddr),
582*61046927SAndroid Build Coastguard Worker       REG(SP_VS_OBJ_START, reg_disasm_gpuaddr),
583*61046927SAndroid Build Coastguard Worker       REG(SP_FS_OBJ_START, reg_disasm_gpuaddr),
584*61046927SAndroid Build Coastguard Worker       REG(SP_GS_OBJ_START, reg_disasm_gpuaddr),
585*61046927SAndroid Build Coastguard Worker       REG(SP_HS_OBJ_START, reg_disasm_gpuaddr),
586*61046927SAndroid Build Coastguard Worker       REG(SP_DS_OBJ_START, reg_disasm_gpuaddr),
587*61046927SAndroid Build Coastguard Worker       REG(SP_CS_OBJ_START, reg_disasm_gpuaddr),
588*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_VS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
589*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_HS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
590*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_DS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
591*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_GS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
592*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_FS_BORDER_COLOR_BASE_ADDR, reg_dump_gpuaddr),
593*61046927SAndroid Build Coastguard Worker       {NULL},
594*61046927SAndroid Build Coastguard Worker }, reg_a5xx[] = {
595*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x4].REG, reg_dump_scratch),
596*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x5].REG, reg_dump_scratch),
597*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x6].REG, reg_dump_scratch),
598*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x7].REG, reg_dump_scratch),
599*61046927SAndroid Build Coastguard Worker       REG(SP_VS_OBJ_START_LO, reg_gpuaddr_lo),
600*61046927SAndroid Build Coastguard Worker       REG(SP_VS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
601*61046927SAndroid Build Coastguard Worker       REG(SP_HS_OBJ_START_LO, reg_gpuaddr_lo),
602*61046927SAndroid Build Coastguard Worker       REG(SP_HS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
603*61046927SAndroid Build Coastguard Worker       REG(SP_DS_OBJ_START_LO, reg_gpuaddr_lo),
604*61046927SAndroid Build Coastguard Worker       REG(SP_DS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
605*61046927SAndroid Build Coastguard Worker       REG(SP_GS_OBJ_START_LO, reg_gpuaddr_lo),
606*61046927SAndroid Build Coastguard Worker       REG(SP_GS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
607*61046927SAndroid Build Coastguard Worker       REG(SP_FS_OBJ_START_LO, reg_gpuaddr_lo),
608*61046927SAndroid Build Coastguard Worker       REG(SP_FS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
609*61046927SAndroid Build Coastguard Worker       REG(SP_CS_OBJ_START_LO, reg_gpuaddr_lo),
610*61046927SAndroid Build Coastguard Worker       REG(SP_CS_OBJ_START_HI, reg_disasm_gpuaddr_hi),
611*61046927SAndroid Build Coastguard Worker       REG(TPL1_VS_TEX_CONST_LO, reg_gpuaddr_lo),
612*61046927SAndroid Build Coastguard Worker       REG(TPL1_VS_TEX_CONST_HI, reg_dump_tex_const_hi),
613*61046927SAndroid Build Coastguard Worker       REG(TPL1_VS_TEX_SAMP_LO, reg_gpuaddr_lo),
614*61046927SAndroid Build Coastguard Worker       REG(TPL1_VS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
615*61046927SAndroid Build Coastguard Worker       REG(TPL1_HS_TEX_CONST_LO, reg_gpuaddr_lo),
616*61046927SAndroid Build Coastguard Worker       REG(TPL1_HS_TEX_CONST_HI, reg_dump_tex_const_hi),
617*61046927SAndroid Build Coastguard Worker       REG(TPL1_HS_TEX_SAMP_LO, reg_gpuaddr_lo),
618*61046927SAndroid Build Coastguard Worker       REG(TPL1_HS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
619*61046927SAndroid Build Coastguard Worker       REG(TPL1_DS_TEX_CONST_LO, reg_gpuaddr_lo),
620*61046927SAndroid Build Coastguard Worker       REG(TPL1_DS_TEX_CONST_HI, reg_dump_tex_const_hi),
621*61046927SAndroid Build Coastguard Worker       REG(TPL1_DS_TEX_SAMP_LO, reg_gpuaddr_lo),
622*61046927SAndroid Build Coastguard Worker       REG(TPL1_DS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
623*61046927SAndroid Build Coastguard Worker       REG(TPL1_GS_TEX_CONST_LO, reg_gpuaddr_lo),
624*61046927SAndroid Build Coastguard Worker       REG(TPL1_GS_TEX_CONST_HI, reg_dump_tex_const_hi),
625*61046927SAndroid Build Coastguard Worker       REG(TPL1_GS_TEX_SAMP_LO, reg_gpuaddr_lo),
626*61046927SAndroid Build Coastguard Worker       REG(TPL1_GS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
627*61046927SAndroid Build Coastguard Worker       REG(TPL1_FS_TEX_CONST_LO, reg_gpuaddr_lo),
628*61046927SAndroid Build Coastguard Worker       REG(TPL1_FS_TEX_CONST_HI, reg_dump_tex_const_hi),
629*61046927SAndroid Build Coastguard Worker       REG(TPL1_FS_TEX_SAMP_LO, reg_gpuaddr_lo),
630*61046927SAndroid Build Coastguard Worker       REG(TPL1_FS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
631*61046927SAndroid Build Coastguard Worker       REG(TPL1_CS_TEX_CONST_LO, reg_gpuaddr_lo),
632*61046927SAndroid Build Coastguard Worker       REG(TPL1_CS_TEX_CONST_HI, reg_dump_tex_const_hi),
633*61046927SAndroid Build Coastguard Worker       REG(TPL1_CS_TEX_SAMP_LO, reg_gpuaddr_lo),
634*61046927SAndroid Build Coastguard Worker       REG(TPL1_CS_TEX_SAMP_HI, reg_dump_tex_samp_hi),
635*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_BORDER_COLOR_BASE_ADDR_LO, reg_gpuaddr_lo),
636*61046927SAndroid Build Coastguard Worker       REG(TPL1_TP_BORDER_COLOR_BASE_ADDR_HI, reg_dump_gpuaddr_hi),
637*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[0].ADDR_LO, reg_gpuaddr_lo),
638*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[0].ADDR_HI, reg_dump_gpuaddr_hi),
639*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[1].ADDR_LO, reg_gpuaddr_lo),
640*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[1].ADDR_HI, reg_dump_gpuaddr_hi),
641*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[2].ADDR_LO, reg_gpuaddr_lo),
642*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[2].ADDR_HI, reg_dump_gpuaddr_hi),
643*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[3].ADDR_LO, reg_gpuaddr_lo),
644*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[3].ADDR_HI, reg_dump_gpuaddr_hi),
645*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[4].ADDR_LO, reg_gpuaddr_lo),
646*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[4].ADDR_HI, reg_dump_gpuaddr_hi),
647*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[5].ADDR_LO, reg_gpuaddr_lo),
648*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[5].ADDR_HI, reg_dump_gpuaddr_hi),
649*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[6].ADDR_LO, reg_gpuaddr_lo),
650*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[6].ADDR_HI, reg_dump_gpuaddr_hi),
651*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[7].ADDR_LO, reg_gpuaddr_lo),
652*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT_FLAG_BUFFER[7].ADDR_HI, reg_dump_gpuaddr_hi),
653*61046927SAndroid Build Coastguard Worker //      REG(RB_BLIT_FLAG_DST_LO, reg_gpuaddr_lo),
654*61046927SAndroid Build Coastguard Worker //      REG(RB_BLIT_FLAG_DST_HI, reg_dump_gpuaddr_hi),
655*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT[0].BASE_LO, reg_gpuaddr_lo),
656*61046927SAndroid Build Coastguard Worker //      REG(RB_MRT[0].BASE_HI, reg_dump_gpuaddr_hi),
657*61046927SAndroid Build Coastguard Worker //      REG(RB_DEPTH_BUFFER_BASE_LO, reg_gpuaddr_lo),
658*61046927SAndroid Build Coastguard Worker //      REG(RB_DEPTH_BUFFER_BASE_HI, reg_dump_gpuaddr_hi),
659*61046927SAndroid Build Coastguard Worker //      REG(RB_DEPTH_FLAG_BUFFER_BASE_LO, reg_gpuaddr_lo),
660*61046927SAndroid Build Coastguard Worker //      REG(RB_DEPTH_FLAG_BUFFER_BASE_HI, reg_dump_gpuaddr_hi),
661*61046927SAndroid Build Coastguard Worker //      REG(RB_BLIT_DST_LO, reg_gpuaddr_lo),
662*61046927SAndroid Build Coastguard Worker //      REG(RB_BLIT_DST_HI, reg_dump_gpuaddr_hi),
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_SRC_LO, reg_gpuaddr_lo),
665*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_SRC_HI, reg_dump_gpuaddr_hi),
666*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_SRC_FLAGS_LO, reg_gpuaddr_lo),
667*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_SRC_FLAGS_HI, reg_dump_gpuaddr_hi),
668*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_DST_LO, reg_gpuaddr_lo),
669*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_DST_HI, reg_dump_gpuaddr_hi),
670*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_DST_FLAGS_LO, reg_gpuaddr_lo),
671*61046927SAndroid Build Coastguard Worker //      REG(RB_2D_DST_FLAGS_HI, reg_dump_gpuaddr_hi),
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker       {NULL},
674*61046927SAndroid Build Coastguard Worker }, reg_a6xx[] = {
675*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x4].REG, reg_dump_scratch),
676*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x5].REG, reg_dump_scratch),
677*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x6].REG, reg_dump_scratch),
678*61046927SAndroid Build Coastguard Worker       REG(CP_SCRATCH[0x7].REG, reg_dump_scratch),
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker       REG64(SP_VS_OBJ_START, reg_disasm_gpuaddr64),
681*61046927SAndroid Build Coastguard Worker       REG64(SP_HS_OBJ_START, reg_disasm_gpuaddr64),
682*61046927SAndroid Build Coastguard Worker       REG64(SP_DS_OBJ_START, reg_disasm_gpuaddr64),
683*61046927SAndroid Build Coastguard Worker       REG64(SP_GS_OBJ_START, reg_disasm_gpuaddr64),
684*61046927SAndroid Build Coastguard Worker       REG64(SP_FS_OBJ_START, reg_disasm_gpuaddr64),
685*61046927SAndroid Build Coastguard Worker       REG64(SP_CS_OBJ_START, reg_disasm_gpuaddr64),
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker       REG64(SP_VS_TEX_CONST, reg_dump_gpuaddr64),
688*61046927SAndroid Build Coastguard Worker       REG64(SP_VS_TEX_SAMP, reg_dump_gpuaddr64),
689*61046927SAndroid Build Coastguard Worker       REG64(SP_HS_TEX_CONST, reg_dump_gpuaddr64),
690*61046927SAndroid Build Coastguard Worker       REG64(SP_HS_TEX_SAMP, reg_dump_gpuaddr64),
691*61046927SAndroid Build Coastguard Worker       REG64(SP_DS_TEX_CONST, reg_dump_gpuaddr64),
692*61046927SAndroid Build Coastguard Worker       REG64(SP_DS_TEX_SAMP, reg_dump_gpuaddr64),
693*61046927SAndroid Build Coastguard Worker       REG64(SP_GS_TEX_CONST, reg_dump_gpuaddr64),
694*61046927SAndroid Build Coastguard Worker       REG64(SP_GS_TEX_SAMP, reg_dump_gpuaddr64),
695*61046927SAndroid Build Coastguard Worker       REG64(SP_FS_TEX_CONST, reg_dump_gpuaddr64),
696*61046927SAndroid Build Coastguard Worker       REG64(SP_FS_TEX_SAMP, reg_dump_gpuaddr64),
697*61046927SAndroid Build Coastguard Worker       REG64(SP_CS_TEX_CONST, reg_dump_gpuaddr64),
698*61046927SAndroid Build Coastguard Worker       REG64(SP_CS_TEX_SAMP, reg_dump_gpuaddr64),
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker       {NULL},
701*61046927SAndroid Build Coastguard Worker }, reg_a7xx[] = {
702*61046927SAndroid Build Coastguard Worker       REG64(SP_VS_OBJ_START, reg_disasm_gpuaddr64),
703*61046927SAndroid Build Coastguard Worker       REG64(SP_HS_OBJ_START, reg_disasm_gpuaddr64),
704*61046927SAndroid Build Coastguard Worker       REG64(SP_DS_OBJ_START, reg_disasm_gpuaddr64),
705*61046927SAndroid Build Coastguard Worker       REG64(SP_GS_OBJ_START, reg_disasm_gpuaddr64),
706*61046927SAndroid Build Coastguard Worker       REG64(SP_FS_OBJ_START, reg_disasm_gpuaddr64),
707*61046927SAndroid Build Coastguard Worker       REG64(SP_CS_OBJ_START, reg_disasm_gpuaddr64),
708*61046927SAndroid Build Coastguard Worker 
709*61046927SAndroid Build Coastguard Worker       {NULL},
710*61046927SAndroid Build Coastguard Worker }, *type0_reg;
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker static struct rnn *rnn;
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker static void
init_rnn(const char * gpuname)715*61046927SAndroid Build Coastguard Worker init_rnn(const char *gpuname)
716*61046927SAndroid Build Coastguard Worker {
717*61046927SAndroid Build Coastguard Worker    rnn = rnn_new(!options->color);
718*61046927SAndroid Build Coastguard Worker 
719*61046927SAndroid Build Coastguard Worker    rnn_load(rnn, gpuname);
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker    if (options->querystrs) {
722*61046927SAndroid Build Coastguard Worker       int i;
723*61046927SAndroid Build Coastguard Worker       queryvals = calloc(options->nquery, sizeof(queryvals[0]));
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker       for (i = 0; i < options->nquery; i++) {
726*61046927SAndroid Build Coastguard Worker          int val = strtol(options->querystrs[i], NULL, 0);
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker          if (val == 0)
729*61046927SAndroid Build Coastguard Worker             val = regbase(options->querystrs[i]);
730*61046927SAndroid Build Coastguard Worker 
731*61046927SAndroid Build Coastguard Worker          queryvals[i] = val;
732*61046927SAndroid Build Coastguard Worker          printf("querystr: %s -> 0x%x\n", options->querystrs[i], queryvals[i]);
733*61046927SAndroid Build Coastguard Worker       }
734*61046927SAndroid Build Coastguard Worker    }
735*61046927SAndroid Build Coastguard Worker 
736*61046927SAndroid Build Coastguard Worker    for (unsigned idx = 0; type0_reg[idx].regname; idx++) {
737*61046927SAndroid Build Coastguard Worker       type0_reg[idx].regbase = regbase(type0_reg[idx].regname);
738*61046927SAndroid Build Coastguard Worker       if (!type0_reg[idx].regbase) {
739*61046927SAndroid Build Coastguard Worker          printf("invalid register name: %s\n", type0_reg[idx].regname);
740*61046927SAndroid Build Coastguard Worker          exit(1);
741*61046927SAndroid Build Coastguard Worker       }
742*61046927SAndroid Build Coastguard Worker    }
743*61046927SAndroid Build Coastguard Worker }
744*61046927SAndroid Build Coastguard Worker 
745*61046927SAndroid Build Coastguard Worker void
reset_regs(void)746*61046927SAndroid Build Coastguard Worker reset_regs(void)
747*61046927SAndroid Build Coastguard Worker {
748*61046927SAndroid Build Coastguard Worker    clear_written();
749*61046927SAndroid Build Coastguard Worker    clear_lastvals();
750*61046927SAndroid Build Coastguard Worker    memset(&ibs, 0, sizeof(ibs));
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker void
cffdec_init(const struct cffdec_options * _options)754*61046927SAndroid Build Coastguard Worker cffdec_init(const struct cffdec_options *_options)
755*61046927SAndroid Build Coastguard Worker {
756*61046927SAndroid Build Coastguard Worker    options = _options;
757*61046927SAndroid Build Coastguard Worker    summary = options->summary;
758*61046927SAndroid Build Coastguard Worker 
759*61046927SAndroid Build Coastguard Worker    /* in case we're decoding multiple files: */
760*61046927SAndroid Build Coastguard Worker    free(queryvals);
761*61046927SAndroid Build Coastguard Worker    reset_regs();
762*61046927SAndroid Build Coastguard Worker    draw_count = 0;
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker    if (!options->info)
765*61046927SAndroid Build Coastguard Worker       return;
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker    switch (options->info->chip) {
768*61046927SAndroid Build Coastguard Worker    case 2:
769*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a2xx;
770*61046927SAndroid Build Coastguard Worker       init_rnn("a2xx");
771*61046927SAndroid Build Coastguard Worker       break;
772*61046927SAndroid Build Coastguard Worker    case 3:
773*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a3xx;
774*61046927SAndroid Build Coastguard Worker       init_rnn("a3xx");
775*61046927SAndroid Build Coastguard Worker       break;
776*61046927SAndroid Build Coastguard Worker    case 4:
777*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a4xx;
778*61046927SAndroid Build Coastguard Worker       init_rnn("a4xx");
779*61046927SAndroid Build Coastguard Worker       break;
780*61046927SAndroid Build Coastguard Worker    case 5:
781*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a5xx;
782*61046927SAndroid Build Coastguard Worker       init_rnn("a5xx");
783*61046927SAndroid Build Coastguard Worker       break;
784*61046927SAndroid Build Coastguard Worker    case 6:
785*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a6xx;
786*61046927SAndroid Build Coastguard Worker       init_rnn("a6xx");
787*61046927SAndroid Build Coastguard Worker       break;
788*61046927SAndroid Build Coastguard Worker    case 7:
789*61046927SAndroid Build Coastguard Worker       type0_reg = reg_a7xx;
790*61046927SAndroid Build Coastguard Worker       init_rnn("a7xx");
791*61046927SAndroid Build Coastguard Worker       break;
792*61046927SAndroid Build Coastguard Worker    default:
793*61046927SAndroid Build Coastguard Worker       errx(-1, "unsupported generation: %u", options->info->chip);
794*61046927SAndroid Build Coastguard Worker    }
795*61046927SAndroid Build Coastguard Worker }
796*61046927SAndroid Build Coastguard Worker 
797*61046927SAndroid Build Coastguard Worker const char *
pktname(unsigned opc)798*61046927SAndroid Build Coastguard Worker pktname(unsigned opc)
799*61046927SAndroid Build Coastguard Worker {
800*61046927SAndroid Build Coastguard Worker    return rnn_enumname(rnn, "adreno_pm4_type3_packets", opc);
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker 
803*61046927SAndroid Build Coastguard Worker const char *
regname(uint32_t regbase,int color)804*61046927SAndroid Build Coastguard Worker regname(uint32_t regbase, int color)
805*61046927SAndroid Build Coastguard Worker {
806*61046927SAndroid Build Coastguard Worker    return rnn_regname(rnn, regbase, color);
807*61046927SAndroid Build Coastguard Worker }
808*61046927SAndroid Build Coastguard Worker 
809*61046927SAndroid Build Coastguard Worker uint32_t
regbase(const char * name)810*61046927SAndroid Build Coastguard Worker regbase(const char *name)
811*61046927SAndroid Build Coastguard Worker {
812*61046927SAndroid Build Coastguard Worker    return rnn_regbase(rnn, name);
813*61046927SAndroid Build Coastguard Worker }
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker static int
endswith(uint32_t regbase,const char * suffix)816*61046927SAndroid Build Coastguard Worker endswith(uint32_t regbase, const char *suffix)
817*61046927SAndroid Build Coastguard Worker {
818*61046927SAndroid Build Coastguard Worker    const char *name = regname(regbase, 0);
819*61046927SAndroid Build Coastguard Worker    const char *s = strstr(name, suffix);
820*61046927SAndroid Build Coastguard Worker    if (!s)
821*61046927SAndroid Build Coastguard Worker       return 0;
822*61046927SAndroid Build Coastguard Worker    return (s - strlen(name) + strlen(suffix)) == name;
823*61046927SAndroid Build Coastguard Worker }
824*61046927SAndroid Build Coastguard Worker 
825*61046927SAndroid Build Coastguard Worker struct regacc
regacc(struct rnn * r)826*61046927SAndroid Build Coastguard Worker regacc(struct rnn *r)
827*61046927SAndroid Build Coastguard Worker {
828*61046927SAndroid Build Coastguard Worker    if (!r)
829*61046927SAndroid Build Coastguard Worker       r = rnn;
830*61046927SAndroid Build Coastguard Worker 
831*61046927SAndroid Build Coastguard Worker    return (struct regacc){ .rnn = r };
832*61046927SAndroid Build Coastguard Worker }
833*61046927SAndroid Build Coastguard Worker 
834*61046927SAndroid Build Coastguard Worker /* returns true if the complete reg value has been accumulated: */
835*61046927SAndroid Build Coastguard Worker bool
regacc_push(struct regacc * r,uint32_t regbase,uint32_t dword)836*61046927SAndroid Build Coastguard Worker regacc_push(struct regacc *r, uint32_t regbase, uint32_t dword)
837*61046927SAndroid Build Coastguard Worker {
838*61046927SAndroid Build Coastguard Worker    if (r->has_dword_lo) {
839*61046927SAndroid Build Coastguard Worker       /* Work around kernel devcore dumps which accidentially miss half of a 64b reg
840*61046927SAndroid Build Coastguard Worker        * see: https://patchwork.freedesktop.org/series/112302/
841*61046927SAndroid Build Coastguard Worker        */
842*61046927SAndroid Build Coastguard Worker       if (regbase != r->regbase + 1) {
843*61046927SAndroid Build Coastguard Worker          printf("WARNING: 64b discontinuity (%x, expected %x)\n", regbase, r->regbase + 1);
844*61046927SAndroid Build Coastguard Worker          r->has_dword_lo = false;
845*61046927SAndroid Build Coastguard Worker          return true;
846*61046927SAndroid Build Coastguard Worker       }
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker       r->value |= ((uint64_t)dword) << 32;
849*61046927SAndroid Build Coastguard Worker       r->has_dword_lo = false;
850*61046927SAndroid Build Coastguard Worker 
851*61046927SAndroid Build Coastguard Worker       return true;
852*61046927SAndroid Build Coastguard Worker    }
853*61046927SAndroid Build Coastguard Worker 
854*61046927SAndroid Build Coastguard Worker    r->regbase = regbase;
855*61046927SAndroid Build Coastguard Worker    r->value = dword;
856*61046927SAndroid Build Coastguard Worker 
857*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(r->rnn, regbase);
858*61046927SAndroid Build Coastguard Worker    r->has_dword_lo = (info->width == 64);
859*61046927SAndroid Build Coastguard Worker 
860*61046927SAndroid Build Coastguard Worker    /* Workaround for kernel devcore dump bugs: */
861*61046927SAndroid Build Coastguard Worker    if ((info->width == 64) && endswith(regbase, "_HI")) {
862*61046927SAndroid Build Coastguard Worker       printf("WARNING: 64b discontinuity (no _LO dword for %x)\n", regbase);
863*61046927SAndroid Build Coastguard Worker       r->has_dword_lo = false;
864*61046927SAndroid Build Coastguard Worker    }
865*61046927SAndroid Build Coastguard Worker 
866*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
867*61046927SAndroid Build Coastguard Worker 
868*61046927SAndroid Build Coastguard Worker    return !r->has_dword_lo;
869*61046927SAndroid Build Coastguard Worker }
870*61046927SAndroid Build Coastguard Worker 
871*61046927SAndroid Build Coastguard Worker void
dump_register_val(struct regacc * r,int level)872*61046927SAndroid Build Coastguard Worker dump_register_val(struct regacc *r, int level)
873*61046927SAndroid Build Coastguard Worker {
874*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(rnn, r->regbase);
875*61046927SAndroid Build Coastguard Worker 
876*61046927SAndroid Build Coastguard Worker    if (info && info->typeinfo) {
877*61046927SAndroid Build Coastguard Worker       uint64_t gpuaddr = 0;
878*61046927SAndroid Build Coastguard Worker       char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, r->value);
879*61046927SAndroid Build Coastguard Worker       printf("%s%s: %s", levels[level], info->name, decoded);
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker       /* Try and figure out if we are looking at a gpuaddr.. this
882*61046927SAndroid Build Coastguard Worker        * might be useful for other gen's too, but at least a5xx has
883*61046927SAndroid Build Coastguard Worker        * the _HI/_LO suffix we can look for.  Maybe a better approach
884*61046927SAndroid Build Coastguard Worker        * would be some special annotation in the xml..
885*61046927SAndroid Build Coastguard Worker        * for a6xx use "address" and "waddress" types
886*61046927SAndroid Build Coastguard Worker        */
887*61046927SAndroid Build Coastguard Worker       if (options->info->chip >= 6) {
888*61046927SAndroid Build Coastguard Worker          if (!strcmp(info->typeinfo->name, "address") ||
889*61046927SAndroid Build Coastguard Worker              !strcmp(info->typeinfo->name, "waddress")) {
890*61046927SAndroid Build Coastguard Worker             gpuaddr = r->value;
891*61046927SAndroid Build Coastguard Worker          }
892*61046927SAndroid Build Coastguard Worker       } else if (options->info->chip >= 5) {
893*61046927SAndroid Build Coastguard Worker          /* TODO we shouldn't rely on reg_val() since reg_set() might
894*61046927SAndroid Build Coastguard Worker           * not have been called yet for the other half of the 64b reg.
895*61046927SAndroid Build Coastguard Worker           * We can remove this hack once a5xx.xml is converted to reg64
896*61046927SAndroid Build Coastguard Worker           * and address/waddess.
897*61046927SAndroid Build Coastguard Worker           */
898*61046927SAndroid Build Coastguard Worker          if (endswith(r->regbase, "_HI") && endswith(r->regbase - 1, "_LO")) {
899*61046927SAndroid Build Coastguard Worker             gpuaddr = (r->value << 32) | reg_val(r->regbase - 1);
900*61046927SAndroid Build Coastguard Worker          } else if (endswith(r->regbase, "_LO") && endswith(r->regbase + 1, "_HI")) {
901*61046927SAndroid Build Coastguard Worker             gpuaddr = (((uint64_t)reg_val(r->regbase + 1)) << 32) | r->value;
902*61046927SAndroid Build Coastguard Worker          }
903*61046927SAndroid Build Coastguard Worker       }
904*61046927SAndroid Build Coastguard Worker 
905*61046927SAndroid Build Coastguard Worker       if (gpuaddr && hostptr(gpuaddr)) {
906*61046927SAndroid Build Coastguard Worker          printf("\t\tbase=%" PRIx64 ", offset=%" PRIu64 ", size=%u",
907*61046927SAndroid Build Coastguard Worker                 gpubaseaddr(gpuaddr), gpuaddr - gpubaseaddr(gpuaddr),
908*61046927SAndroid Build Coastguard Worker                 hostlen(gpubaseaddr(gpuaddr)));
909*61046927SAndroid Build Coastguard Worker       }
910*61046927SAndroid Build Coastguard Worker 
911*61046927SAndroid Build Coastguard Worker       printf("\n");
912*61046927SAndroid Build Coastguard Worker 
913*61046927SAndroid Build Coastguard Worker       free(decoded);
914*61046927SAndroid Build Coastguard Worker    } else if (info) {
915*61046927SAndroid Build Coastguard Worker       printf("%s%s: %08"PRIx64"\n", levels[level], info->name, r->value);
916*61046927SAndroid Build Coastguard Worker    } else {
917*61046927SAndroid Build Coastguard Worker       printf("%s<%04x>: %08"PRIx64"\n", levels[level], r->regbase, r->value);
918*61046927SAndroid Build Coastguard Worker    }
919*61046927SAndroid Build Coastguard Worker 
920*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
921*61046927SAndroid Build Coastguard Worker }
922*61046927SAndroid Build Coastguard Worker 
923*61046927SAndroid Build Coastguard Worker static void
dump_register(struct regacc * r,int level)924*61046927SAndroid Build Coastguard Worker dump_register(struct regacc *r, int level)
925*61046927SAndroid Build Coastguard Worker {
926*61046927SAndroid Build Coastguard Worker    if (!quiet(3)) {
927*61046927SAndroid Build Coastguard Worker       dump_register_val(r, level);
928*61046927SAndroid Build Coastguard Worker    }
929*61046927SAndroid Build Coastguard Worker 
930*61046927SAndroid Build Coastguard Worker    for (unsigned idx = 0; type0_reg[idx].regname; idx++) {
931*61046927SAndroid Build Coastguard Worker       if (type0_reg[idx].regbase == r->regbase) {
932*61046927SAndroid Build Coastguard Worker          if (type0_reg[idx].is_reg64) {
933*61046927SAndroid Build Coastguard Worker             type0_reg[idx].fxn64(type0_reg[idx].regname, r->value, level);
934*61046927SAndroid Build Coastguard Worker          } else {
935*61046927SAndroid Build Coastguard Worker             type0_reg[idx].fxn(type0_reg[idx].regname, (uint32_t)r->value, level);
936*61046927SAndroid Build Coastguard Worker          }
937*61046927SAndroid Build Coastguard Worker          break;
938*61046927SAndroid Build Coastguard Worker       }
939*61046927SAndroid Build Coastguard Worker    }
940*61046927SAndroid Build Coastguard Worker }
941*61046927SAndroid Build Coastguard Worker 
942*61046927SAndroid Build Coastguard Worker static bool
is_banked_reg(uint32_t regbase)943*61046927SAndroid Build Coastguard Worker is_banked_reg(uint32_t regbase)
944*61046927SAndroid Build Coastguard Worker {
945*61046927SAndroid Build Coastguard Worker    return (0x2000 <= regbase) && (regbase < 0x2400);
946*61046927SAndroid Build Coastguard Worker }
947*61046927SAndroid Build Coastguard Worker 
948*61046927SAndroid Build Coastguard Worker static void
dump_registers(uint32_t regbase,uint32_t * dwords,uint32_t sizedwords,int level)949*61046927SAndroid Build Coastguard Worker dump_registers(uint32_t regbase, uint32_t *dwords, uint32_t sizedwords,
950*61046927SAndroid Build Coastguard Worker                int level)
951*61046927SAndroid Build Coastguard Worker {
952*61046927SAndroid Build Coastguard Worker    struct regacc r = regacc(NULL);
953*61046927SAndroid Build Coastguard Worker 
954*61046927SAndroid Build Coastguard Worker    while (sizedwords--) {
955*61046927SAndroid Build Coastguard Worker       int last_summary = summary;
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker       /* access to non-banked registers needs a WFI:
958*61046927SAndroid Build Coastguard Worker        * TODO banked register range for a2xx??
959*61046927SAndroid Build Coastguard Worker        */
960*61046927SAndroid Build Coastguard Worker       if (needs_wfi && !is_banked_reg(regbase))
961*61046927SAndroid Build Coastguard Worker          printl(2, "NEEDS WFI: %s (%x)\n", regname(regbase, 1), regbase);
962*61046927SAndroid Build Coastguard Worker 
963*61046927SAndroid Build Coastguard Worker       reg_set(regbase, *dwords);
964*61046927SAndroid Build Coastguard Worker       if (regacc_push(&r, regbase, *dwords))
965*61046927SAndroid Build Coastguard Worker          dump_register(&r, level);
966*61046927SAndroid Build Coastguard Worker       regbase++;
967*61046927SAndroid Build Coastguard Worker       dwords++;
968*61046927SAndroid Build Coastguard Worker       summary = last_summary;
969*61046927SAndroid Build Coastguard Worker    }
970*61046927SAndroid Build Coastguard Worker }
971*61046927SAndroid Build Coastguard Worker 
972*61046927SAndroid Build Coastguard Worker static void
dump_domain(uint32_t * dwords,uint32_t sizedwords,int level,const char * name)973*61046927SAndroid Build Coastguard Worker dump_domain(uint32_t *dwords, uint32_t sizedwords, int level, const char *name)
974*61046927SAndroid Build Coastguard Worker {
975*61046927SAndroid Build Coastguard Worker    struct rnndomain *dom;
976*61046927SAndroid Build Coastguard Worker    int i;
977*61046927SAndroid Build Coastguard Worker 
978*61046927SAndroid Build Coastguard Worker    dom = rnn_finddomain(rnn->db, name);
979*61046927SAndroid Build Coastguard Worker 
980*61046927SAndroid Build Coastguard Worker    if (!dom)
981*61046927SAndroid Build Coastguard Worker       return;
982*61046927SAndroid Build Coastguard Worker 
983*61046927SAndroid Build Coastguard Worker    if (script_packet)
984*61046927SAndroid Build Coastguard Worker       script_packet(dwords, sizedwords, rnn, dom);
985*61046927SAndroid Build Coastguard Worker 
986*61046927SAndroid Build Coastguard Worker    if (quiet(2))
987*61046927SAndroid Build Coastguard Worker       return;
988*61046927SAndroid Build Coastguard Worker 
989*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords; i++) {
990*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = rnndec_decodeaddr(rnn->vc, dom, i, 0);
991*61046927SAndroid Build Coastguard Worker       char *decoded;
992*61046927SAndroid Build Coastguard Worker       if (!(info && info->typeinfo))
993*61046927SAndroid Build Coastguard Worker          break;
994*61046927SAndroid Build Coastguard Worker       uint64_t value = dwords[i];
995*61046927SAndroid Build Coastguard Worker       if (info->typeinfo->high >= 32 && i < sizedwords - 1) {
996*61046927SAndroid Build Coastguard Worker          value |= (uint64_t)dwords[i + 1] << 32;
997*61046927SAndroid Build Coastguard Worker          i++; /* skip the next dword since we're printing it now */
998*61046927SAndroid Build Coastguard Worker       }
999*61046927SAndroid Build Coastguard Worker       decoded = rnndec_decodeval(rnn->vc, info->typeinfo, value);
1000*61046927SAndroid Build Coastguard Worker       /* Unlike the register printing path, we don't print the name
1001*61046927SAndroid Build Coastguard Worker        * of the register, so if it doesn't contain other named
1002*61046927SAndroid Build Coastguard Worker        * things (i.e. it isn't a bitset) then print the register
1003*61046927SAndroid Build Coastguard Worker        * name as if it's a bitset with a single entry. This avoids
1004*61046927SAndroid Build Coastguard Worker        * having to create a dummy register with a single entry to
1005*61046927SAndroid Build Coastguard Worker        * get a name in the decoding.
1006*61046927SAndroid Build Coastguard Worker        */
1007*61046927SAndroid Build Coastguard Worker       if (info->typeinfo->type == RNN_TTYPE_BITSET ||
1008*61046927SAndroid Build Coastguard Worker           info->typeinfo->type == RNN_TTYPE_INLINE_BITSET) {
1009*61046927SAndroid Build Coastguard Worker          printf("%s%s\n", levels[level], decoded);
1010*61046927SAndroid Build Coastguard Worker       } else {
1011*61046927SAndroid Build Coastguard Worker          printf("%s{ %s%s%s = %s }\n", levels[level], rnn->vc->colors->rname,
1012*61046927SAndroid Build Coastguard Worker                 info->name, rnn->vc->colors->reset, decoded);
1013*61046927SAndroid Build Coastguard Worker       }
1014*61046927SAndroid Build Coastguard Worker       free(decoded);
1015*61046927SAndroid Build Coastguard Worker       free(info->name);
1016*61046927SAndroid Build Coastguard Worker       free(info);
1017*61046927SAndroid Build Coastguard Worker    }
1018*61046927SAndroid Build Coastguard Worker }
1019*61046927SAndroid Build Coastguard Worker 
1020*61046927SAndroid Build Coastguard Worker static uint32_t bin_x1, bin_x2, bin_y1, bin_y2;
1021*61046927SAndroid Build Coastguard Worker static unsigned mode;
1022*61046927SAndroid Build Coastguard Worker static const char *render_mode;
1023*61046927SAndroid Build Coastguard Worker static const char *thread;
1024*61046927SAndroid Build Coastguard Worker static enum {
1025*61046927SAndroid Build Coastguard Worker    MODE_BINNING = 0x1,
1026*61046927SAndroid Build Coastguard Worker    MODE_GMEM = 0x2,
1027*61046927SAndroid Build Coastguard Worker    MODE_BYPASS = 0x4,
1028*61046927SAndroid Build Coastguard Worker    MODE_ALL = MODE_BINNING | MODE_GMEM | MODE_BYPASS,
1029*61046927SAndroid Build Coastguard Worker } enable_mask = MODE_ALL;
1030*61046927SAndroid Build Coastguard Worker static bool skip_ib2_enable_global;
1031*61046927SAndroid Build Coastguard Worker static bool skip_ib2_enable_local;
1032*61046927SAndroid Build Coastguard Worker 
1033*61046927SAndroid Build Coastguard Worker static void
print_mode(int level)1034*61046927SAndroid Build Coastguard Worker print_mode(int level)
1035*61046927SAndroid Build Coastguard Worker {
1036*61046927SAndroid Build Coastguard Worker    if ((options->info->chip >= 5) && !quiet(2)) {
1037*61046927SAndroid Build Coastguard Worker       printf("%smode: %s", levels[level], render_mode);
1038*61046927SAndroid Build Coastguard Worker       if (thread)
1039*61046927SAndroid Build Coastguard Worker          printf(":%s", thread);
1040*61046927SAndroid Build Coastguard Worker       printf("\n");
1041*61046927SAndroid Build Coastguard Worker       printf("%sskip_ib2: g=%d, l=%d\n", levels[level], skip_ib2_enable_global,
1042*61046927SAndroid Build Coastguard Worker              skip_ib2_enable_local);
1043*61046927SAndroid Build Coastguard Worker    }
1044*61046927SAndroid Build Coastguard Worker }
1045*61046927SAndroid Build Coastguard Worker 
1046*61046927SAndroid Build Coastguard Worker static bool
skip_query(void)1047*61046927SAndroid Build Coastguard Worker skip_query(void)
1048*61046927SAndroid Build Coastguard Worker {
1049*61046927SAndroid Build Coastguard Worker    switch (options->query_mode) {
1050*61046927SAndroid Build Coastguard Worker    case QUERY_ALL:
1051*61046927SAndroid Build Coastguard Worker       /* never skip: */
1052*61046927SAndroid Build Coastguard Worker       return false;
1053*61046927SAndroid Build Coastguard Worker    case QUERY_WRITTEN:
1054*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < options->nquery; i++) {
1055*61046927SAndroid Build Coastguard Worker          uint32_t regbase = queryvals[i];
1056*61046927SAndroid Build Coastguard Worker          if (!reg_written(regbase)) {
1057*61046927SAndroid Build Coastguard Worker             continue;
1058*61046927SAndroid Build Coastguard Worker          }
1059*61046927SAndroid Build Coastguard Worker          if (reg_rewritten(regbase)) {
1060*61046927SAndroid Build Coastguard Worker             return false;
1061*61046927SAndroid Build Coastguard Worker          }
1062*61046927SAndroid Build Coastguard Worker       }
1063*61046927SAndroid Build Coastguard Worker       return true;
1064*61046927SAndroid Build Coastguard Worker    case QUERY_DELTA:
1065*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < options->nquery; i++) {
1066*61046927SAndroid Build Coastguard Worker          uint32_t regbase = queryvals[i];
1067*61046927SAndroid Build Coastguard Worker          if (!reg_written(regbase)) {
1068*61046927SAndroid Build Coastguard Worker             continue;
1069*61046927SAndroid Build Coastguard Worker          }
1070*61046927SAndroid Build Coastguard Worker          uint32_t lastval = reg_val(regbase);
1071*61046927SAndroid Build Coastguard Worker          if (lastval != lastvals[regbase]) {
1072*61046927SAndroid Build Coastguard Worker             return false;
1073*61046927SAndroid Build Coastguard Worker          }
1074*61046927SAndroid Build Coastguard Worker       }
1075*61046927SAndroid Build Coastguard Worker       return true;
1076*61046927SAndroid Build Coastguard Worker    }
1077*61046927SAndroid Build Coastguard Worker    return true;
1078*61046927SAndroid Build Coastguard Worker }
1079*61046927SAndroid Build Coastguard Worker 
1080*61046927SAndroid Build Coastguard Worker static void
__do_query(const char * primtype,uint32_t num_indices)1081*61046927SAndroid Build Coastguard Worker __do_query(const char *primtype, uint32_t num_indices)
1082*61046927SAndroid Build Coastguard Worker {
1083*61046927SAndroid Build Coastguard Worker    int n = 0;
1084*61046927SAndroid Build Coastguard Worker 
1085*61046927SAndroid Build Coastguard Worker    if ((5 <= options->info->chip) && (options->info->chip < 7)) {
1086*61046927SAndroid Build Coastguard Worker       uint32_t scissor_tl = reg_val(regbase("GRAS_SC_WINDOW_SCISSOR_TL"));
1087*61046927SAndroid Build Coastguard Worker       uint32_t scissor_br = reg_val(regbase("GRAS_SC_WINDOW_SCISSOR_BR"));
1088*61046927SAndroid Build Coastguard Worker 
1089*61046927SAndroid Build Coastguard Worker       bin_x1 = scissor_tl & 0xffff;
1090*61046927SAndroid Build Coastguard Worker       bin_y1 = scissor_tl >> 16;
1091*61046927SAndroid Build Coastguard Worker       bin_x2 = scissor_br & 0xffff;
1092*61046927SAndroid Build Coastguard Worker       bin_y2 = scissor_br >> 16;
1093*61046927SAndroid Build Coastguard Worker    }
1094*61046927SAndroid Build Coastguard Worker 
1095*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < options->nquery; i++) {
1096*61046927SAndroid Build Coastguard Worker       uint32_t regbase = queryvals[i];
1097*61046927SAndroid Build Coastguard Worker       if (!reg_written(regbase))
1098*61046927SAndroid Build Coastguard Worker          continue;
1099*61046927SAndroid Build Coastguard Worker 
1100*61046927SAndroid Build Coastguard Worker       struct regacc r = regacc(NULL);
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker       /* 64b regs require two successive 32b dwords: */
1103*61046927SAndroid Build Coastguard Worker       for (int d = 0; d < 2; d++)
1104*61046927SAndroid Build Coastguard Worker          if (regacc_push(&r, regbase + d, reg_val(regbase + d)))
1105*61046927SAndroid Build Coastguard Worker             break;
1106*61046927SAndroid Build Coastguard Worker 
1107*61046927SAndroid Build Coastguard Worker       printf("%4d: %s(%u,%u-%u,%u):%u:", draw_count, primtype, bin_x1,
1108*61046927SAndroid Build Coastguard Worker              bin_y1, bin_x2, bin_y2, num_indices);
1109*61046927SAndroid Build Coastguard Worker       if (options->info->chip >= 5)
1110*61046927SAndroid Build Coastguard Worker          printf("%s:", render_mode);
1111*61046927SAndroid Build Coastguard Worker       if (thread)
1112*61046927SAndroid Build Coastguard Worker          printf("%s:", thread);
1113*61046927SAndroid Build Coastguard Worker       printf("\t%08"PRIx64, r.value);
1114*61046927SAndroid Build Coastguard Worker       if (r.value != lastvals[regbase]) {
1115*61046927SAndroid Build Coastguard Worker          printf("!");
1116*61046927SAndroid Build Coastguard Worker       } else {
1117*61046927SAndroid Build Coastguard Worker          printf(" ");
1118*61046927SAndroid Build Coastguard Worker       }
1119*61046927SAndroid Build Coastguard Worker       if (reg_rewritten(regbase)) {
1120*61046927SAndroid Build Coastguard Worker          printf("+");
1121*61046927SAndroid Build Coastguard Worker       } else {
1122*61046927SAndroid Build Coastguard Worker          printf(" ");
1123*61046927SAndroid Build Coastguard Worker       }
1124*61046927SAndroid Build Coastguard Worker       dump_register_val(&r, 0);
1125*61046927SAndroid Build Coastguard Worker       n++;
1126*61046927SAndroid Build Coastguard Worker    }
1127*61046927SAndroid Build Coastguard Worker 
1128*61046927SAndroid Build Coastguard Worker    if (n > 1)
1129*61046927SAndroid Build Coastguard Worker       printf("\n");
1130*61046927SAndroid Build Coastguard Worker }
1131*61046927SAndroid Build Coastguard Worker 
1132*61046927SAndroid Build Coastguard Worker static void
do_query_compare(const char * primtype,uint32_t num_indices)1133*61046927SAndroid Build Coastguard Worker do_query_compare(const char *primtype, uint32_t num_indices)
1134*61046927SAndroid Build Coastguard Worker {
1135*61046927SAndroid Build Coastguard Worker    unsigned saved_enable_mask = enable_mask;
1136*61046927SAndroid Build Coastguard Worker    const char *saved_render_mode = render_mode;
1137*61046927SAndroid Build Coastguard Worker 
1138*61046927SAndroid Build Coastguard Worker    /* in 'query-compare' mode, we want to see if the register is writtten
1139*61046927SAndroid Build Coastguard Worker     * or changed in any mode:
1140*61046927SAndroid Build Coastguard Worker     *
1141*61046927SAndroid Build Coastguard Worker     * (NOTE: this could cause false-positive for 'query-delta' if the reg
1142*61046927SAndroid Build Coastguard Worker     * is written with different values in binning vs sysmem/gmem mode, as
1143*61046927SAndroid Build Coastguard Worker     * we don't track previous values per-mode, but I think we can live with
1144*61046927SAndroid Build Coastguard Worker     * that)
1145*61046927SAndroid Build Coastguard Worker     */
1146*61046927SAndroid Build Coastguard Worker    enable_mask = MODE_ALL;
1147*61046927SAndroid Build Coastguard Worker 
1148*61046927SAndroid Build Coastguard Worker    clear_rewritten();
1149*61046927SAndroid Build Coastguard Worker    load_all_groups(0);
1150*61046927SAndroid Build Coastguard Worker 
1151*61046927SAndroid Build Coastguard Worker    if (!skip_query()) {
1152*61046927SAndroid Build Coastguard Worker       /* dump binning pass values: */
1153*61046927SAndroid Build Coastguard Worker       enable_mask = MODE_BINNING;
1154*61046927SAndroid Build Coastguard Worker       render_mode = "BINNING";
1155*61046927SAndroid Build Coastguard Worker       clear_rewritten();
1156*61046927SAndroid Build Coastguard Worker       load_all_groups(0);
1157*61046927SAndroid Build Coastguard Worker       __do_query(primtype, num_indices);
1158*61046927SAndroid Build Coastguard Worker 
1159*61046927SAndroid Build Coastguard Worker       /* dump draw pass values: */
1160*61046927SAndroid Build Coastguard Worker       enable_mask = MODE_GMEM | MODE_BYPASS;
1161*61046927SAndroid Build Coastguard Worker       render_mode = "DRAW";
1162*61046927SAndroid Build Coastguard Worker       clear_rewritten();
1163*61046927SAndroid Build Coastguard Worker       load_all_groups(0);
1164*61046927SAndroid Build Coastguard Worker       __do_query(primtype, num_indices);
1165*61046927SAndroid Build Coastguard Worker 
1166*61046927SAndroid Build Coastguard Worker       printf("\n");
1167*61046927SAndroid Build Coastguard Worker    }
1168*61046927SAndroid Build Coastguard Worker 
1169*61046927SAndroid Build Coastguard Worker    enable_mask = saved_enable_mask;
1170*61046927SAndroid Build Coastguard Worker    render_mode = saved_render_mode;
1171*61046927SAndroid Build Coastguard Worker 
1172*61046927SAndroid Build Coastguard Worker    disable_all_groups();
1173*61046927SAndroid Build Coastguard Worker }
1174*61046927SAndroid Build Coastguard Worker 
1175*61046927SAndroid Build Coastguard Worker /* well, actually query and script..
1176*61046927SAndroid Build Coastguard Worker  * NOTE: call this before dump_register_summary()
1177*61046927SAndroid Build Coastguard Worker  */
1178*61046927SAndroid Build Coastguard Worker static void
do_query(const char * primtype,uint32_t num_indices)1179*61046927SAndroid Build Coastguard Worker do_query(const char *primtype, uint32_t num_indices)
1180*61046927SAndroid Build Coastguard Worker {
1181*61046927SAndroid Build Coastguard Worker    if (script_draw)
1182*61046927SAndroid Build Coastguard Worker       script_draw(primtype, num_indices);
1183*61046927SAndroid Build Coastguard Worker 
1184*61046927SAndroid Build Coastguard Worker    if (options->query_compare) {
1185*61046927SAndroid Build Coastguard Worker       do_query_compare(primtype, num_indices);
1186*61046927SAndroid Build Coastguard Worker       return;
1187*61046927SAndroid Build Coastguard Worker    }
1188*61046927SAndroid Build Coastguard Worker 
1189*61046927SAndroid Build Coastguard Worker    if (skip_query())
1190*61046927SAndroid Build Coastguard Worker       return;
1191*61046927SAndroid Build Coastguard Worker 
1192*61046927SAndroid Build Coastguard Worker    __do_query(primtype, num_indices);
1193*61046927SAndroid Build Coastguard Worker }
1194*61046927SAndroid Build Coastguard Worker 
1195*61046927SAndroid Build Coastguard Worker static void
cp_im_loadi(uint32_t * dwords,uint32_t sizedwords,int level)1196*61046927SAndroid Build Coastguard Worker cp_im_loadi(uint32_t *dwords, uint32_t sizedwords, int level)
1197*61046927SAndroid Build Coastguard Worker {
1198*61046927SAndroid Build Coastguard Worker    uint32_t start = dwords[1] >> 16;
1199*61046927SAndroid Build Coastguard Worker    uint32_t size = dwords[1] & 0xffff;
1200*61046927SAndroid Build Coastguard Worker    const char *type = NULL, *ext = NULL;
1201*61046927SAndroid Build Coastguard Worker    gl_shader_stage disasm_type;
1202*61046927SAndroid Build Coastguard Worker 
1203*61046927SAndroid Build Coastguard Worker    switch (dwords[0]) {
1204*61046927SAndroid Build Coastguard Worker    case 0:
1205*61046927SAndroid Build Coastguard Worker       type = "vertex";
1206*61046927SAndroid Build Coastguard Worker       ext = "vo";
1207*61046927SAndroid Build Coastguard Worker       disasm_type = MESA_SHADER_VERTEX;
1208*61046927SAndroid Build Coastguard Worker       break;
1209*61046927SAndroid Build Coastguard Worker    case 1:
1210*61046927SAndroid Build Coastguard Worker       type = "fragment";
1211*61046927SAndroid Build Coastguard Worker       ext = "fo";
1212*61046927SAndroid Build Coastguard Worker       disasm_type = MESA_SHADER_FRAGMENT;
1213*61046927SAndroid Build Coastguard Worker       break;
1214*61046927SAndroid Build Coastguard Worker    default:
1215*61046927SAndroid Build Coastguard Worker       type = "<unknown>";
1216*61046927SAndroid Build Coastguard Worker       disasm_type = 0;
1217*61046927SAndroid Build Coastguard Worker       break;
1218*61046927SAndroid Build Coastguard Worker    }
1219*61046927SAndroid Build Coastguard Worker 
1220*61046927SAndroid Build Coastguard Worker    printf("%s%s shader, start=%04x, size=%04x\n", levels[level], type, start,
1221*61046927SAndroid Build Coastguard Worker           size);
1222*61046927SAndroid Build Coastguard Worker    disasm_a2xx(dwords + 2, sizedwords - 2, level + 2, disasm_type);
1223*61046927SAndroid Build Coastguard Worker 
1224*61046927SAndroid Build Coastguard Worker    /* dump raw shader: */
1225*61046927SAndroid Build Coastguard Worker    if (ext)
1226*61046927SAndroid Build Coastguard Worker       dump_shader(ext, dwords + 2, (sizedwords - 2) * 4);
1227*61046927SAndroid Build Coastguard Worker }
1228*61046927SAndroid Build Coastguard Worker 
1229*61046927SAndroid Build Coastguard Worker static void
cp_wide_reg_write(uint32_t * dwords,uint32_t sizedwords,int level)1230*61046927SAndroid Build Coastguard Worker cp_wide_reg_write(uint32_t *dwords, uint32_t sizedwords, int level)
1231*61046927SAndroid Build Coastguard Worker {
1232*61046927SAndroid Build Coastguard Worker    uint32_t reg = dwords[0] & 0xffff;
1233*61046927SAndroid Build Coastguard Worker    struct regacc r = regacc(NULL);
1234*61046927SAndroid Build Coastguard Worker    for (int i = 1; i < sizedwords; i++) {
1235*61046927SAndroid Build Coastguard Worker       if (regacc_push(&r, reg, dwords[i]))
1236*61046927SAndroid Build Coastguard Worker          dump_register(&r, level + 1);
1237*61046927SAndroid Build Coastguard Worker       reg_set(reg, dwords[i]);
1238*61046927SAndroid Build Coastguard Worker       reg++;
1239*61046927SAndroid Build Coastguard Worker    }
1240*61046927SAndroid Build Coastguard Worker }
1241*61046927SAndroid Build Coastguard Worker 
1242*61046927SAndroid Build Coastguard Worker enum state_t {
1243*61046927SAndroid Build Coastguard Worker    TEX_SAMP = 1,
1244*61046927SAndroid Build Coastguard Worker    TEX_CONST,
1245*61046927SAndroid Build Coastguard Worker    TEX_MIPADDR, /* a3xx only */
1246*61046927SAndroid Build Coastguard Worker    SHADER_PROG,
1247*61046927SAndroid Build Coastguard Worker    SHADER_CONST,
1248*61046927SAndroid Build Coastguard Worker 
1249*61046927SAndroid Build Coastguard Worker    // image/ssbo state:
1250*61046927SAndroid Build Coastguard Worker    SSBO_0,
1251*61046927SAndroid Build Coastguard Worker    SSBO_1,
1252*61046927SAndroid Build Coastguard Worker    SSBO_2,
1253*61046927SAndroid Build Coastguard Worker 
1254*61046927SAndroid Build Coastguard Worker    UBO,
1255*61046927SAndroid Build Coastguard Worker 
1256*61046927SAndroid Build Coastguard Worker    // unknown things, just to hexdumps:
1257*61046927SAndroid Build Coastguard Worker    UNKNOWN_DWORDS,
1258*61046927SAndroid Build Coastguard Worker    UNKNOWN_2DWORDS,
1259*61046927SAndroid Build Coastguard Worker    UNKNOWN_4DWORDS,
1260*61046927SAndroid Build Coastguard Worker };
1261*61046927SAndroid Build Coastguard Worker 
1262*61046927SAndroid Build Coastguard Worker enum adreno_state_block {
1263*61046927SAndroid Build Coastguard Worker    SB_VERT_TEX = 0,
1264*61046927SAndroid Build Coastguard Worker    SB_VERT_MIPADDR = 1,
1265*61046927SAndroid Build Coastguard Worker    SB_FRAG_TEX = 2,
1266*61046927SAndroid Build Coastguard Worker    SB_FRAG_MIPADDR = 3,
1267*61046927SAndroid Build Coastguard Worker    SB_VERT_SHADER = 4,
1268*61046927SAndroid Build Coastguard Worker    SB_GEOM_SHADER = 5,
1269*61046927SAndroid Build Coastguard Worker    SB_FRAG_SHADER = 6,
1270*61046927SAndroid Build Coastguard Worker    SB_COMPUTE_SHADER = 7,
1271*61046927SAndroid Build Coastguard Worker };
1272*61046927SAndroid Build Coastguard Worker 
1273*61046927SAndroid Build Coastguard Worker /* TODO there is probably a clever way to let rnndec parse things so
1274*61046927SAndroid Build Coastguard Worker  * we don't have to care about packet format differences across gens
1275*61046927SAndroid Build Coastguard Worker  */
1276*61046927SAndroid Build Coastguard Worker 
1277*61046927SAndroid Build Coastguard Worker static void
a3xx_get_state_type(uint32_t * dwords,gl_shader_stage * stage,enum state_t * state,enum state_src_t * src)1278*61046927SAndroid Build Coastguard Worker a3xx_get_state_type(uint32_t *dwords, gl_shader_stage *stage,
1279*61046927SAndroid Build Coastguard Worker                     enum state_t *state, enum state_src_t *src)
1280*61046927SAndroid Build Coastguard Worker {
1281*61046927SAndroid Build Coastguard Worker    unsigned state_block_id = (dwords[0] >> 19) & 0x7;
1282*61046927SAndroid Build Coastguard Worker    unsigned state_type = dwords[1] & 0x3;
1283*61046927SAndroid Build Coastguard Worker    static const struct {
1284*61046927SAndroid Build Coastguard Worker       gl_shader_stage stage;
1285*61046927SAndroid Build Coastguard Worker       enum state_t state;
1286*61046927SAndroid Build Coastguard Worker    } lookup[0xf][0x3] = {
1287*61046927SAndroid Build Coastguard Worker       [SB_VERT_TEX][0] = {MESA_SHADER_VERTEX, TEX_SAMP},
1288*61046927SAndroid Build Coastguard Worker       [SB_VERT_TEX][1] = {MESA_SHADER_VERTEX, TEX_CONST},
1289*61046927SAndroid Build Coastguard Worker       [SB_FRAG_TEX][0] = {MESA_SHADER_FRAGMENT, TEX_SAMP},
1290*61046927SAndroid Build Coastguard Worker       [SB_FRAG_TEX][1] = {MESA_SHADER_FRAGMENT, TEX_CONST},
1291*61046927SAndroid Build Coastguard Worker       [SB_VERT_SHADER][0] = {MESA_SHADER_VERTEX, SHADER_PROG},
1292*61046927SAndroid Build Coastguard Worker       [SB_VERT_SHADER][1] = {MESA_SHADER_VERTEX, SHADER_CONST},
1293*61046927SAndroid Build Coastguard Worker       [SB_FRAG_SHADER][0] = {MESA_SHADER_FRAGMENT, SHADER_PROG},
1294*61046927SAndroid Build Coastguard Worker       [SB_FRAG_SHADER][1] = {MESA_SHADER_FRAGMENT, SHADER_CONST},
1295*61046927SAndroid Build Coastguard Worker    };
1296*61046927SAndroid Build Coastguard Worker 
1297*61046927SAndroid Build Coastguard Worker    *stage = lookup[state_block_id][state_type].stage;
1298*61046927SAndroid Build Coastguard Worker    *state = lookup[state_block_id][state_type].state;
1299*61046927SAndroid Build Coastguard Worker    unsigned state_src = (dwords[0] >> 16) & 0x7;
1300*61046927SAndroid Build Coastguard Worker    if (state_src == 0 /* SS_DIRECT */)
1301*61046927SAndroid Build Coastguard Worker       *src = STATE_SRC_DIRECT;
1302*61046927SAndroid Build Coastguard Worker    else
1303*61046927SAndroid Build Coastguard Worker       *src = STATE_SRC_INDIRECT;
1304*61046927SAndroid Build Coastguard Worker }
1305*61046927SAndroid Build Coastguard Worker 
1306*61046927SAndroid Build Coastguard Worker static enum state_src_t
_get_state_src(unsigned dword0)1307*61046927SAndroid Build Coastguard Worker _get_state_src(unsigned dword0)
1308*61046927SAndroid Build Coastguard Worker {
1309*61046927SAndroid Build Coastguard Worker    switch ((dword0 >> 16) & 0x3) {
1310*61046927SAndroid Build Coastguard Worker    case 0: /* SS4_DIRECT / SS6_DIRECT */
1311*61046927SAndroid Build Coastguard Worker       return STATE_SRC_DIRECT;
1312*61046927SAndroid Build Coastguard Worker    case 2: /* SS4_INDIRECT / SS6_INDIRECT */
1313*61046927SAndroid Build Coastguard Worker       return STATE_SRC_INDIRECT;
1314*61046927SAndroid Build Coastguard Worker    case 1: /* SS6_BINDLESS */
1315*61046927SAndroid Build Coastguard Worker       return STATE_SRC_BINDLESS;
1316*61046927SAndroid Build Coastguard Worker    default:
1317*61046927SAndroid Build Coastguard Worker       return STATE_SRC_DIRECT;
1318*61046927SAndroid Build Coastguard Worker    }
1319*61046927SAndroid Build Coastguard Worker }
1320*61046927SAndroid Build Coastguard Worker 
1321*61046927SAndroid Build Coastguard Worker static void
_get_state_type(unsigned state_block_id,unsigned state_type,gl_shader_stage * stage,enum state_t * state)1322*61046927SAndroid Build Coastguard Worker _get_state_type(unsigned state_block_id, unsigned state_type,
1323*61046927SAndroid Build Coastguard Worker                 gl_shader_stage *stage, enum state_t *state)
1324*61046927SAndroid Build Coastguard Worker {
1325*61046927SAndroid Build Coastguard Worker    static const struct {
1326*61046927SAndroid Build Coastguard Worker       gl_shader_stage stage;
1327*61046927SAndroid Build Coastguard Worker       enum state_t state;
1328*61046927SAndroid Build Coastguard Worker    } lookup[0x10][0x4] = {
1329*61046927SAndroid Build Coastguard Worker       // SB4_VS_TEX:
1330*61046927SAndroid Build Coastguard Worker       [0x0][0] = {MESA_SHADER_VERTEX, TEX_SAMP},
1331*61046927SAndroid Build Coastguard Worker       [0x0][1] = {MESA_SHADER_VERTEX, TEX_CONST},
1332*61046927SAndroid Build Coastguard Worker       [0x0][2] = {MESA_SHADER_VERTEX, UBO},
1333*61046927SAndroid Build Coastguard Worker       // SB4_HS_TEX:
1334*61046927SAndroid Build Coastguard Worker       [0x1][0] = {MESA_SHADER_TESS_CTRL, TEX_SAMP},
1335*61046927SAndroid Build Coastguard Worker       [0x1][1] = {MESA_SHADER_TESS_CTRL, TEX_CONST},
1336*61046927SAndroid Build Coastguard Worker       [0x1][2] = {MESA_SHADER_TESS_CTRL, UBO},
1337*61046927SAndroid Build Coastguard Worker       // SB4_DS_TEX:
1338*61046927SAndroid Build Coastguard Worker       [0x2][0] = {MESA_SHADER_TESS_EVAL, TEX_SAMP},
1339*61046927SAndroid Build Coastguard Worker       [0x2][1] = {MESA_SHADER_TESS_EVAL, TEX_CONST},
1340*61046927SAndroid Build Coastguard Worker       [0x2][2] = {MESA_SHADER_TESS_EVAL, UBO},
1341*61046927SAndroid Build Coastguard Worker       // SB4_GS_TEX:
1342*61046927SAndroid Build Coastguard Worker       [0x3][0] = {MESA_SHADER_GEOMETRY, TEX_SAMP},
1343*61046927SAndroid Build Coastguard Worker       [0x3][1] = {MESA_SHADER_GEOMETRY, TEX_CONST},
1344*61046927SAndroid Build Coastguard Worker       [0x3][2] = {MESA_SHADER_GEOMETRY, UBO},
1345*61046927SAndroid Build Coastguard Worker       // SB4_FS_TEX:
1346*61046927SAndroid Build Coastguard Worker       [0x4][0] = {MESA_SHADER_FRAGMENT, TEX_SAMP},
1347*61046927SAndroid Build Coastguard Worker       [0x4][1] = {MESA_SHADER_FRAGMENT, TEX_CONST},
1348*61046927SAndroid Build Coastguard Worker       [0x4][2] = {MESA_SHADER_FRAGMENT, UBO},
1349*61046927SAndroid Build Coastguard Worker       // SB4_CS_TEX:
1350*61046927SAndroid Build Coastguard Worker       [0x5][0] = {MESA_SHADER_COMPUTE, TEX_SAMP},
1351*61046927SAndroid Build Coastguard Worker       [0x5][1] = {MESA_SHADER_COMPUTE, TEX_CONST},
1352*61046927SAndroid Build Coastguard Worker       [0x5][2] = {MESA_SHADER_COMPUTE, UBO},
1353*61046927SAndroid Build Coastguard Worker       // SB4_VS_SHADER:
1354*61046927SAndroid Build Coastguard Worker       [0x8][0] = {MESA_SHADER_VERTEX, SHADER_PROG},
1355*61046927SAndroid Build Coastguard Worker       [0x8][1] = {MESA_SHADER_VERTEX, SHADER_CONST},
1356*61046927SAndroid Build Coastguard Worker       [0x8][2] = {MESA_SHADER_VERTEX, UBO},
1357*61046927SAndroid Build Coastguard Worker       // SB4_HS_SHADER
1358*61046927SAndroid Build Coastguard Worker       [0x9][0] = {MESA_SHADER_TESS_CTRL, SHADER_PROG},
1359*61046927SAndroid Build Coastguard Worker       [0x9][1] = {MESA_SHADER_TESS_CTRL, SHADER_CONST},
1360*61046927SAndroid Build Coastguard Worker       [0x9][2] = {MESA_SHADER_TESS_CTRL, UBO},
1361*61046927SAndroid Build Coastguard Worker       // SB4_DS_SHADER
1362*61046927SAndroid Build Coastguard Worker       [0xa][0] = {MESA_SHADER_TESS_EVAL, SHADER_PROG},
1363*61046927SAndroid Build Coastguard Worker       [0xa][1] = {MESA_SHADER_TESS_EVAL, SHADER_CONST},
1364*61046927SAndroid Build Coastguard Worker       [0xa][2] = {MESA_SHADER_TESS_EVAL, UBO},
1365*61046927SAndroid Build Coastguard Worker       // SB4_GS_SHADER
1366*61046927SAndroid Build Coastguard Worker       [0xb][0] = {MESA_SHADER_GEOMETRY, SHADER_PROG},
1367*61046927SAndroid Build Coastguard Worker       [0xb][1] = {MESA_SHADER_GEOMETRY, SHADER_CONST},
1368*61046927SAndroid Build Coastguard Worker       [0xb][2] = {MESA_SHADER_GEOMETRY, UBO},
1369*61046927SAndroid Build Coastguard Worker       // SB4_FS_SHADER:
1370*61046927SAndroid Build Coastguard Worker       [0xc][0] = {MESA_SHADER_FRAGMENT, SHADER_PROG},
1371*61046927SAndroid Build Coastguard Worker       [0xc][1] = {MESA_SHADER_FRAGMENT, SHADER_CONST},
1372*61046927SAndroid Build Coastguard Worker       [0xc][2] = {MESA_SHADER_FRAGMENT, UBO},
1373*61046927SAndroid Build Coastguard Worker       // SB4_CS_SHADER:
1374*61046927SAndroid Build Coastguard Worker       [0xd][0] = {MESA_SHADER_COMPUTE, SHADER_PROG},
1375*61046927SAndroid Build Coastguard Worker       [0xd][1] = {MESA_SHADER_COMPUTE, SHADER_CONST},
1376*61046927SAndroid Build Coastguard Worker       [0xd][2] = {MESA_SHADER_COMPUTE, UBO},
1377*61046927SAndroid Build Coastguard Worker       [0xd][3] = {MESA_SHADER_COMPUTE, SSBO_0}, /* a6xx location */
1378*61046927SAndroid Build Coastguard Worker       // SB4_SSBO (shared across all stages)
1379*61046927SAndroid Build Coastguard Worker       [0xe][0] = {0, SSBO_0}, /* a5xx (and a4xx?) location */
1380*61046927SAndroid Build Coastguard Worker       [0xe][1] = {0, SSBO_1},
1381*61046927SAndroid Build Coastguard Worker       [0xe][2] = {0, SSBO_2},
1382*61046927SAndroid Build Coastguard Worker       // SB4_CS_SSBO
1383*61046927SAndroid Build Coastguard Worker       [0xf][0] = {MESA_SHADER_COMPUTE, SSBO_0},
1384*61046927SAndroid Build Coastguard Worker       [0xf][1] = {MESA_SHADER_COMPUTE, SSBO_1},
1385*61046927SAndroid Build Coastguard Worker       [0xf][2] = {MESA_SHADER_COMPUTE, SSBO_2},
1386*61046927SAndroid Build Coastguard Worker       // unknown things
1387*61046927SAndroid Build Coastguard Worker       /* This looks like combined UBO state for 3d stages (a5xx and
1388*61046927SAndroid Build Coastguard Worker        * before??  I think a6xx has UBO state per shader stage:
1389*61046927SAndroid Build Coastguard Worker        */
1390*61046927SAndroid Build Coastguard Worker       [0x6][2] = {0, UBO},
1391*61046927SAndroid Build Coastguard Worker       [0x7][1] = {0, UNKNOWN_2DWORDS},
1392*61046927SAndroid Build Coastguard Worker    };
1393*61046927SAndroid Build Coastguard Worker 
1394*61046927SAndroid Build Coastguard Worker    *stage = lookup[state_block_id][state_type].stage;
1395*61046927SAndroid Build Coastguard Worker    *state = lookup[state_block_id][state_type].state;
1396*61046927SAndroid Build Coastguard Worker }
1397*61046927SAndroid Build Coastguard Worker 
1398*61046927SAndroid Build Coastguard Worker static void
a4xx_get_state_type(uint32_t * dwords,gl_shader_stage * stage,enum state_t * state,enum state_src_t * src)1399*61046927SAndroid Build Coastguard Worker a4xx_get_state_type(uint32_t *dwords, gl_shader_stage *stage,
1400*61046927SAndroid Build Coastguard Worker                     enum state_t *state, enum state_src_t *src)
1401*61046927SAndroid Build Coastguard Worker {
1402*61046927SAndroid Build Coastguard Worker    unsigned state_block_id = (dwords[0] >> 18) & 0xf;
1403*61046927SAndroid Build Coastguard Worker    unsigned state_type = dwords[1] & 0x3;
1404*61046927SAndroid Build Coastguard Worker    _get_state_type(state_block_id, state_type, stage, state);
1405*61046927SAndroid Build Coastguard Worker    *src = _get_state_src(dwords[0]);
1406*61046927SAndroid Build Coastguard Worker }
1407*61046927SAndroid Build Coastguard Worker 
1408*61046927SAndroid Build Coastguard Worker static void
a6xx_get_state_type(uint32_t * dwords,gl_shader_stage * stage,enum state_t * state,enum state_src_t * src)1409*61046927SAndroid Build Coastguard Worker a6xx_get_state_type(uint32_t *dwords, gl_shader_stage *stage,
1410*61046927SAndroid Build Coastguard Worker                     enum state_t *state, enum state_src_t *src)
1411*61046927SAndroid Build Coastguard Worker {
1412*61046927SAndroid Build Coastguard Worker    unsigned state_block_id = (dwords[0] >> 18) & 0xf;
1413*61046927SAndroid Build Coastguard Worker    unsigned state_type = (dwords[0] >> 14) & 0x3;
1414*61046927SAndroid Build Coastguard Worker    _get_state_type(state_block_id, state_type, stage, state);
1415*61046927SAndroid Build Coastguard Worker    *src = _get_state_src(dwords[0]);
1416*61046927SAndroid Build Coastguard Worker }
1417*61046927SAndroid Build Coastguard Worker 
1418*61046927SAndroid Build Coastguard Worker static void
dump_tex_samp(uint32_t * texsamp,enum state_src_t src,int num_unit,int level)1419*61046927SAndroid Build Coastguard Worker dump_tex_samp(uint32_t *texsamp, enum state_src_t src, int num_unit, int level)
1420*61046927SAndroid Build Coastguard Worker {
1421*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < num_unit; i++) {
1422*61046927SAndroid Build Coastguard Worker       /* work-around to reduce noise for opencl blob which always
1423*61046927SAndroid Build Coastguard Worker        * writes the max # regardless of # of textures used
1424*61046927SAndroid Build Coastguard Worker        */
1425*61046927SAndroid Build Coastguard Worker       if ((num_unit == 16) && (texsamp[0] == 0) && (texsamp[1] == 0))
1426*61046927SAndroid Build Coastguard Worker          break;
1427*61046927SAndroid Build Coastguard Worker 
1428*61046927SAndroid Build Coastguard Worker       if (options->info->chip == 3) {
1429*61046927SAndroid Build Coastguard Worker          dump_domain(texsamp, 2, level + 2, "A3XX_TEX_SAMP");
1430*61046927SAndroid Build Coastguard Worker          dump_hex(texsamp, 2, level + 1);
1431*61046927SAndroid Build Coastguard Worker          texsamp += 2;
1432*61046927SAndroid Build Coastguard Worker       } else if (options->info->chip == 4) {
1433*61046927SAndroid Build Coastguard Worker          dump_domain(texsamp, 2, level + 2, "A4XX_TEX_SAMP");
1434*61046927SAndroid Build Coastguard Worker          dump_hex(texsamp, 2, level + 1);
1435*61046927SAndroid Build Coastguard Worker          texsamp += 2;
1436*61046927SAndroid Build Coastguard Worker       } else if (options->info->chip == 5) {
1437*61046927SAndroid Build Coastguard Worker          dump_domain(texsamp, 4, level + 2, "A5XX_TEX_SAMP");
1438*61046927SAndroid Build Coastguard Worker          dump_hex(texsamp, 4, level + 1);
1439*61046927SAndroid Build Coastguard Worker          texsamp += 4;
1440*61046927SAndroid Build Coastguard Worker       } else if ((6 <= options->info->chip) && (options->info->chip < 8)) {
1441*61046927SAndroid Build Coastguard Worker          dump_domain(texsamp, 4, level + 2, "A6XX_TEX_SAMP");
1442*61046927SAndroid Build Coastguard Worker          dump_hex(texsamp, 4, level + 1);
1443*61046927SAndroid Build Coastguard Worker          texsamp += src == STATE_SRC_BINDLESS ? 16 : 4;
1444*61046927SAndroid Build Coastguard Worker       }
1445*61046927SAndroid Build Coastguard Worker    }
1446*61046927SAndroid Build Coastguard Worker }
1447*61046927SAndroid Build Coastguard Worker 
1448*61046927SAndroid Build Coastguard Worker static void
dump_tex_const(uint32_t * texconst,int num_unit,int level)1449*61046927SAndroid Build Coastguard Worker dump_tex_const(uint32_t *texconst, int num_unit, int level)
1450*61046927SAndroid Build Coastguard Worker {
1451*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < num_unit; i++) {
1452*61046927SAndroid Build Coastguard Worker       /* work-around to reduce noise for opencl blob which always
1453*61046927SAndroid Build Coastguard Worker        * writes the max # regardless of # of textures used
1454*61046927SAndroid Build Coastguard Worker        */
1455*61046927SAndroid Build Coastguard Worker       if ((num_unit == 16) && (texconst[0] == 0) && (texconst[1] == 0) &&
1456*61046927SAndroid Build Coastguard Worker           (texconst[2] == 0) && (texconst[3] == 0))
1457*61046927SAndroid Build Coastguard Worker          break;
1458*61046927SAndroid Build Coastguard Worker 
1459*61046927SAndroid Build Coastguard Worker       if (options->info->chip == 3) {
1460*61046927SAndroid Build Coastguard Worker          dump_domain(texconst, 4, level + 2, "A3XX_TEX_CONST");
1461*61046927SAndroid Build Coastguard Worker          dump_hex(texconst, 4, level + 1);
1462*61046927SAndroid Build Coastguard Worker          texconst += 4;
1463*61046927SAndroid Build Coastguard Worker       } else if (options->info->chip == 4) {
1464*61046927SAndroid Build Coastguard Worker          dump_domain(texconst, 8, level + 2, "A4XX_TEX_CONST");
1465*61046927SAndroid Build Coastguard Worker          if (options->dump_textures) {
1466*61046927SAndroid Build Coastguard Worker             uint32_t addr = texconst[4] & ~0x1f;
1467*61046927SAndroid Build Coastguard Worker             dump_gpuaddr(addr, level - 2);
1468*61046927SAndroid Build Coastguard Worker          }
1469*61046927SAndroid Build Coastguard Worker          dump_hex(texconst, 8, level + 1);
1470*61046927SAndroid Build Coastguard Worker          texconst += 8;
1471*61046927SAndroid Build Coastguard Worker       } else if (options->info->chip == 5) {
1472*61046927SAndroid Build Coastguard Worker          dump_domain(texconst, 12, level + 2, "A5XX_TEX_CONST");
1473*61046927SAndroid Build Coastguard Worker          if (options->dump_textures) {
1474*61046927SAndroid Build Coastguard Worker             uint64_t addr =
1475*61046927SAndroid Build Coastguard Worker                (((uint64_t)texconst[5] & 0x1ffff) << 32) | texconst[4];
1476*61046927SAndroid Build Coastguard Worker             dump_gpuaddr_size(addr, level - 2, hostlen(addr) / 4, 3);
1477*61046927SAndroid Build Coastguard Worker          }
1478*61046927SAndroid Build Coastguard Worker          dump_hex(texconst, 12, level + 1);
1479*61046927SAndroid Build Coastguard Worker          texconst += 12;
1480*61046927SAndroid Build Coastguard Worker       } else if ((6 <= options->info->chip) && (options->info->chip < 8)) {
1481*61046927SAndroid Build Coastguard Worker          dump_domain(texconst, 16, level + 2, "A6XX_TEX_CONST");
1482*61046927SAndroid Build Coastguard Worker          if (options->dump_textures) {
1483*61046927SAndroid Build Coastguard Worker             uint64_t addr =
1484*61046927SAndroid Build Coastguard Worker                (((uint64_t)texconst[5] & 0x1ffff) << 32) | texconst[4];
1485*61046927SAndroid Build Coastguard Worker             dump_gpuaddr_size(addr, level - 2, hostlen(addr) / 4, 3);
1486*61046927SAndroid Build Coastguard Worker          }
1487*61046927SAndroid Build Coastguard Worker          dump_hex(texconst, 16, level + 1);
1488*61046927SAndroid Build Coastguard Worker          texconst += 16;
1489*61046927SAndroid Build Coastguard Worker       }
1490*61046927SAndroid Build Coastguard Worker    }
1491*61046927SAndroid Build Coastguard Worker }
1492*61046927SAndroid Build Coastguard Worker 
1493*61046927SAndroid Build Coastguard Worker static void
cp_load_state(uint32_t * dwords,uint32_t sizedwords,int level)1494*61046927SAndroid Build Coastguard Worker cp_load_state(uint32_t *dwords, uint32_t sizedwords, int level)
1495*61046927SAndroid Build Coastguard Worker {
1496*61046927SAndroid Build Coastguard Worker    gl_shader_stage stage;
1497*61046927SAndroid Build Coastguard Worker    enum state_t state;
1498*61046927SAndroid Build Coastguard Worker    enum state_src_t src;
1499*61046927SAndroid Build Coastguard Worker    uint32_t num_unit = (dwords[0] >> 22) & 0x1ff;
1500*61046927SAndroid Build Coastguard Worker    uint64_t ext_src_addr;
1501*61046927SAndroid Build Coastguard Worker    void *contents;
1502*61046927SAndroid Build Coastguard Worker    int i;
1503*61046927SAndroid Build Coastguard Worker 
1504*61046927SAndroid Build Coastguard Worker    if (quiet(2) && !options->script)
1505*61046927SAndroid Build Coastguard Worker       return;
1506*61046927SAndroid Build Coastguard Worker 
1507*61046927SAndroid Build Coastguard Worker    if (options->info->chip >= 6)
1508*61046927SAndroid Build Coastguard Worker       a6xx_get_state_type(dwords, &stage, &state, &src);
1509*61046927SAndroid Build Coastguard Worker    else if (options->info->chip >= 4)
1510*61046927SAndroid Build Coastguard Worker       a4xx_get_state_type(dwords, &stage, &state, &src);
1511*61046927SAndroid Build Coastguard Worker    else
1512*61046927SAndroid Build Coastguard Worker       a3xx_get_state_type(dwords, &stage, &state, &src);
1513*61046927SAndroid Build Coastguard Worker 
1514*61046927SAndroid Build Coastguard Worker    switch (src) {
1515*61046927SAndroid Build Coastguard Worker    case STATE_SRC_DIRECT:
1516*61046927SAndroid Build Coastguard Worker       ext_src_addr = 0;
1517*61046927SAndroid Build Coastguard Worker       break;
1518*61046927SAndroid Build Coastguard Worker    case STATE_SRC_INDIRECT:
1519*61046927SAndroid Build Coastguard Worker       if (is_64b()) {
1520*61046927SAndroid Build Coastguard Worker          ext_src_addr = dwords[1] & 0xfffffffc;
1521*61046927SAndroid Build Coastguard Worker          ext_src_addr |= ((uint64_t)dwords[2]) << 32;
1522*61046927SAndroid Build Coastguard Worker       } else {
1523*61046927SAndroid Build Coastguard Worker          ext_src_addr = dwords[1] & 0xfffffffc;
1524*61046927SAndroid Build Coastguard Worker       }
1525*61046927SAndroid Build Coastguard Worker 
1526*61046927SAndroid Build Coastguard Worker       break;
1527*61046927SAndroid Build Coastguard Worker    case STATE_SRC_BINDLESS: {
1528*61046927SAndroid Build Coastguard Worker       const unsigned base_reg = stage == MESA_SHADER_COMPUTE
1529*61046927SAndroid Build Coastguard Worker                                    ? regbase("HLSQ_CS_BINDLESS_BASE[0].DESCRIPTOR")
1530*61046927SAndroid Build Coastguard Worker                                    : regbase("HLSQ_BINDLESS_BASE[0].DESCRIPTOR");
1531*61046927SAndroid Build Coastguard Worker 
1532*61046927SAndroid Build Coastguard Worker       if (is_64b()) {
1533*61046927SAndroid Build Coastguard Worker          const unsigned reg = base_reg + (dwords[1] >> 28) * 2;
1534*61046927SAndroid Build Coastguard Worker          ext_src_addr = reg_val(reg) & 0xfffffffc;
1535*61046927SAndroid Build Coastguard Worker          ext_src_addr |= ((uint64_t)reg_val(reg + 1)) << 32;
1536*61046927SAndroid Build Coastguard Worker       } else {
1537*61046927SAndroid Build Coastguard Worker          const unsigned reg = base_reg + (dwords[1] >> 28);
1538*61046927SAndroid Build Coastguard Worker          ext_src_addr = reg_val(reg) & 0xfffffffc;
1539*61046927SAndroid Build Coastguard Worker       }
1540*61046927SAndroid Build Coastguard Worker 
1541*61046927SAndroid Build Coastguard Worker       ext_src_addr += 4 * (dwords[1] & 0xffffff);
1542*61046927SAndroid Build Coastguard Worker       break;
1543*61046927SAndroid Build Coastguard Worker    }
1544*61046927SAndroid Build Coastguard Worker    }
1545*61046927SAndroid Build Coastguard Worker 
1546*61046927SAndroid Build Coastguard Worker    if (ext_src_addr)
1547*61046927SAndroid Build Coastguard Worker       contents = hostptr(ext_src_addr);
1548*61046927SAndroid Build Coastguard Worker    else
1549*61046927SAndroid Build Coastguard Worker       contents = is_64b() ? dwords + 3 : dwords + 2;
1550*61046927SAndroid Build Coastguard Worker 
1551*61046927SAndroid Build Coastguard Worker    if (!contents)
1552*61046927SAndroid Build Coastguard Worker       return;
1553*61046927SAndroid Build Coastguard Worker 
1554*61046927SAndroid Build Coastguard Worker    switch (state) {
1555*61046927SAndroid Build Coastguard Worker    case SHADER_PROG: {
1556*61046927SAndroid Build Coastguard Worker       const char *ext = NULL;
1557*61046927SAndroid Build Coastguard Worker 
1558*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1559*61046927SAndroid Build Coastguard Worker          return;
1560*61046927SAndroid Build Coastguard Worker 
1561*61046927SAndroid Build Coastguard Worker       if (options->info->chip >= 4)
1562*61046927SAndroid Build Coastguard Worker          num_unit *= 16;
1563*61046927SAndroid Build Coastguard Worker       else if (options->info->chip >= 3)
1564*61046927SAndroid Build Coastguard Worker          num_unit *= 4;
1565*61046927SAndroid Build Coastguard Worker 
1566*61046927SAndroid Build Coastguard Worker       /* shaders:
1567*61046927SAndroid Build Coastguard Worker        *
1568*61046927SAndroid Build Coastguard Worker        * note: num_unit seems to be # of instruction groups, where
1569*61046927SAndroid Build Coastguard Worker        * an instruction group has 4 64bit instructions.
1570*61046927SAndroid Build Coastguard Worker        */
1571*61046927SAndroid Build Coastguard Worker       if (stage == MESA_SHADER_VERTEX) {
1572*61046927SAndroid Build Coastguard Worker          ext = "vo3";
1573*61046927SAndroid Build Coastguard Worker       } else if (stage == MESA_SHADER_GEOMETRY) {
1574*61046927SAndroid Build Coastguard Worker          ext = "go3";
1575*61046927SAndroid Build Coastguard Worker       } else if (stage == MESA_SHADER_COMPUTE) {
1576*61046927SAndroid Build Coastguard Worker          ext = "co3";
1577*61046927SAndroid Build Coastguard Worker       } else if (stage == MESA_SHADER_FRAGMENT) {
1578*61046927SAndroid Build Coastguard Worker          ext = "fo3";
1579*61046927SAndroid Build Coastguard Worker       }
1580*61046927SAndroid Build Coastguard Worker 
1581*61046927SAndroid Build Coastguard Worker       if (contents)
1582*61046927SAndroid Build Coastguard Worker          try_disasm_a3xx(contents, num_unit * 2, level + 2, stdout,
1583*61046927SAndroid Build Coastguard Worker                          options->info->chip * 100);
1584*61046927SAndroid Build Coastguard Worker 
1585*61046927SAndroid Build Coastguard Worker       /* dump raw shader: */
1586*61046927SAndroid Build Coastguard Worker       if (ext)
1587*61046927SAndroid Build Coastguard Worker          dump_shader(ext, contents, num_unit * 2 * 4);
1588*61046927SAndroid Build Coastguard Worker 
1589*61046927SAndroid Build Coastguard Worker       break;
1590*61046927SAndroid Build Coastguard Worker    }
1591*61046927SAndroid Build Coastguard Worker    case SHADER_CONST: {
1592*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1593*61046927SAndroid Build Coastguard Worker          return;
1594*61046927SAndroid Build Coastguard Worker 
1595*61046927SAndroid Build Coastguard Worker       /* uniforms/consts:
1596*61046927SAndroid Build Coastguard Worker        *
1597*61046927SAndroid Build Coastguard Worker        * note: num_unit seems to be # of pairs of dwords??
1598*61046927SAndroid Build Coastguard Worker        */
1599*61046927SAndroid Build Coastguard Worker 
1600*61046927SAndroid Build Coastguard Worker       if (options->info->chip >= 4)
1601*61046927SAndroid Build Coastguard Worker          num_unit *= 2;
1602*61046927SAndroid Build Coastguard Worker 
1603*61046927SAndroid Build Coastguard Worker       dump_float(contents, num_unit * 2, level + 1);
1604*61046927SAndroid Build Coastguard Worker       dump_hex(contents, num_unit * 2, level + 1);
1605*61046927SAndroid Build Coastguard Worker 
1606*61046927SAndroid Build Coastguard Worker       break;
1607*61046927SAndroid Build Coastguard Worker    }
1608*61046927SAndroid Build Coastguard Worker    case TEX_MIPADDR: {
1609*61046927SAndroid Build Coastguard Worker       uint32_t *addrs = contents;
1610*61046927SAndroid Build Coastguard Worker 
1611*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1612*61046927SAndroid Build Coastguard Worker          return;
1613*61046927SAndroid Build Coastguard Worker 
1614*61046927SAndroid Build Coastguard Worker       /* mipmap consts block just appears to be array of num_unit gpu addr's: */
1615*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_unit; i++) {
1616*61046927SAndroid Build Coastguard Worker          void *ptr = hostptr(addrs[i]);
1617*61046927SAndroid Build Coastguard Worker          printf("%s%2d: %08x\n", levels[level + 1], i, addrs[i]);
1618*61046927SAndroid Build Coastguard Worker          if (options->dump_textures) {
1619*61046927SAndroid Build Coastguard Worker             printf("base=%08x\n", (uint32_t)gpubaseaddr(addrs[i]));
1620*61046927SAndroid Build Coastguard Worker             dump_hex(ptr, hostlen(addrs[i]) / 4, level + 1);
1621*61046927SAndroid Build Coastguard Worker          }
1622*61046927SAndroid Build Coastguard Worker       }
1623*61046927SAndroid Build Coastguard Worker       break;
1624*61046927SAndroid Build Coastguard Worker    }
1625*61046927SAndroid Build Coastguard Worker    case TEX_SAMP: {
1626*61046927SAndroid Build Coastguard Worker       dump_tex_samp(contents, src, num_unit, level);
1627*61046927SAndroid Build Coastguard Worker       break;
1628*61046927SAndroid Build Coastguard Worker    }
1629*61046927SAndroid Build Coastguard Worker    case TEX_CONST: {
1630*61046927SAndroid Build Coastguard Worker       dump_tex_const(contents, num_unit, level);
1631*61046927SAndroid Build Coastguard Worker       break;
1632*61046927SAndroid Build Coastguard Worker    }
1633*61046927SAndroid Build Coastguard Worker    case SSBO_0: {
1634*61046927SAndroid Build Coastguard Worker       uint32_t *ssboconst = (uint32_t *)contents;
1635*61046927SAndroid Build Coastguard Worker 
1636*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_unit; i++) {
1637*61046927SAndroid Build Coastguard Worker          int sz = 4;
1638*61046927SAndroid Build Coastguard Worker          if (options->info->chip == 4) {
1639*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 4, level + 2, "A4XX_SSBO_0");
1640*61046927SAndroid Build Coastguard Worker          } else if (options->info->chip == 5) {
1641*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 4, level + 2, "A5XX_SSBO_0");
1642*61046927SAndroid Build Coastguard Worker          } else if ((6 <= options->info->chip) && (options->info->chip < 8)) {
1643*61046927SAndroid Build Coastguard Worker             sz = 16;
1644*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 16, level + 2, "A6XX_TEX_CONST");
1645*61046927SAndroid Build Coastguard Worker          }
1646*61046927SAndroid Build Coastguard Worker          dump_hex(ssboconst, sz, level + 1);
1647*61046927SAndroid Build Coastguard Worker          ssboconst += sz;
1648*61046927SAndroid Build Coastguard Worker       }
1649*61046927SAndroid Build Coastguard Worker       break;
1650*61046927SAndroid Build Coastguard Worker    }
1651*61046927SAndroid Build Coastguard Worker    case SSBO_1: {
1652*61046927SAndroid Build Coastguard Worker       uint32_t *ssboconst = (uint32_t *)contents;
1653*61046927SAndroid Build Coastguard Worker 
1654*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_unit; i++) {
1655*61046927SAndroid Build Coastguard Worker          if (options->info->chip == 4)
1656*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 2, level + 2, "A4XX_SSBO_1");
1657*61046927SAndroid Build Coastguard Worker          else if (options->info->chip == 5)
1658*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 2, level + 2, "A5XX_SSBO_1");
1659*61046927SAndroid Build Coastguard Worker          dump_hex(ssboconst, 2, level + 1);
1660*61046927SAndroid Build Coastguard Worker          ssboconst += 2;
1661*61046927SAndroid Build Coastguard Worker       }
1662*61046927SAndroid Build Coastguard Worker       break;
1663*61046927SAndroid Build Coastguard Worker    }
1664*61046927SAndroid Build Coastguard Worker    case SSBO_2: {
1665*61046927SAndroid Build Coastguard Worker       uint32_t *ssboconst = (uint32_t *)contents;
1666*61046927SAndroid Build Coastguard Worker 
1667*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_unit; i++) {
1668*61046927SAndroid Build Coastguard Worker          /* TODO a4xx and a5xx might be same: */
1669*61046927SAndroid Build Coastguard Worker          if (options->info->chip == 5) {
1670*61046927SAndroid Build Coastguard Worker             dump_domain(ssboconst, 2, level + 2, "A5XX_SSBO_2");
1671*61046927SAndroid Build Coastguard Worker             dump_hex(ssboconst, 2, level + 1);
1672*61046927SAndroid Build Coastguard Worker          }
1673*61046927SAndroid Build Coastguard Worker          if (options->dump_textures) {
1674*61046927SAndroid Build Coastguard Worker             uint64_t addr =
1675*61046927SAndroid Build Coastguard Worker                (((uint64_t)ssboconst[1] & 0x1ffff) << 32) | ssboconst[0];
1676*61046927SAndroid Build Coastguard Worker             dump_gpuaddr_size(addr, level - 2, hostlen(addr) / 4, 3);
1677*61046927SAndroid Build Coastguard Worker          }
1678*61046927SAndroid Build Coastguard Worker          ssboconst += 2;
1679*61046927SAndroid Build Coastguard Worker       }
1680*61046927SAndroid Build Coastguard Worker       break;
1681*61046927SAndroid Build Coastguard Worker    }
1682*61046927SAndroid Build Coastguard Worker    case UBO: {
1683*61046927SAndroid Build Coastguard Worker       uint32_t *uboconst = (uint32_t *)contents;
1684*61046927SAndroid Build Coastguard Worker 
1685*61046927SAndroid Build Coastguard Worker       for (i = 0; i < num_unit; i++) {
1686*61046927SAndroid Build Coastguard Worker          // TODO probably similar on a4xx..
1687*61046927SAndroid Build Coastguard Worker          if (options->info->chip == 5)
1688*61046927SAndroid Build Coastguard Worker             dump_domain(uboconst, 2, level + 2, "A5XX_UBO");
1689*61046927SAndroid Build Coastguard Worker          else if (options->info->chip == 6)
1690*61046927SAndroid Build Coastguard Worker             dump_domain(uboconst, 2, level + 2, "A6XX_UBO");
1691*61046927SAndroid Build Coastguard Worker          dump_hex(uboconst, 2, level + 1);
1692*61046927SAndroid Build Coastguard Worker          uboconst += src == STATE_SRC_BINDLESS ? 16 : 2;
1693*61046927SAndroid Build Coastguard Worker       }
1694*61046927SAndroid Build Coastguard Worker       break;
1695*61046927SAndroid Build Coastguard Worker    }
1696*61046927SAndroid Build Coastguard Worker    case UNKNOWN_DWORDS: {
1697*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1698*61046927SAndroid Build Coastguard Worker          return;
1699*61046927SAndroid Build Coastguard Worker       dump_hex(contents, num_unit, level + 1);
1700*61046927SAndroid Build Coastguard Worker       break;
1701*61046927SAndroid Build Coastguard Worker    }
1702*61046927SAndroid Build Coastguard Worker    case UNKNOWN_2DWORDS: {
1703*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1704*61046927SAndroid Build Coastguard Worker          return;
1705*61046927SAndroid Build Coastguard Worker       dump_hex(contents, num_unit * 2, level + 1);
1706*61046927SAndroid Build Coastguard Worker       break;
1707*61046927SAndroid Build Coastguard Worker    }
1708*61046927SAndroid Build Coastguard Worker    case UNKNOWN_4DWORDS: {
1709*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1710*61046927SAndroid Build Coastguard Worker          return;
1711*61046927SAndroid Build Coastguard Worker       dump_hex(contents, num_unit * 4, level + 1);
1712*61046927SAndroid Build Coastguard Worker       break;
1713*61046927SAndroid Build Coastguard Worker    }
1714*61046927SAndroid Build Coastguard Worker    default:
1715*61046927SAndroid Build Coastguard Worker       if (quiet(2))
1716*61046927SAndroid Build Coastguard Worker          return;
1717*61046927SAndroid Build Coastguard Worker       /* hmm.. */
1718*61046927SAndroid Build Coastguard Worker       dump_hex(contents, num_unit, level + 1);
1719*61046927SAndroid Build Coastguard Worker       break;
1720*61046927SAndroid Build Coastguard Worker    }
1721*61046927SAndroid Build Coastguard Worker }
1722*61046927SAndroid Build Coastguard Worker 
1723*61046927SAndroid Build Coastguard Worker static void
cp_set_bin(uint32_t * dwords,uint32_t sizedwords,int level)1724*61046927SAndroid Build Coastguard Worker cp_set_bin(uint32_t *dwords, uint32_t sizedwords, int level)
1725*61046927SAndroid Build Coastguard Worker {
1726*61046927SAndroid Build Coastguard Worker    bin_x1 = dwords[1] & 0xffff;
1727*61046927SAndroid Build Coastguard Worker    bin_y1 = dwords[1] >> 16;
1728*61046927SAndroid Build Coastguard Worker    bin_x2 = dwords[2] & 0xffff;
1729*61046927SAndroid Build Coastguard Worker    bin_y2 = dwords[2] >> 16;
1730*61046927SAndroid Build Coastguard Worker }
1731*61046927SAndroid Build Coastguard Worker 
1732*61046927SAndroid Build Coastguard Worker static void
dump_a2xx_tex_const(uint32_t * dwords,uint32_t sizedwords,uint32_t val,int level)1733*61046927SAndroid Build Coastguard Worker dump_a2xx_tex_const(uint32_t *dwords, uint32_t sizedwords, uint32_t val,
1734*61046927SAndroid Build Coastguard Worker                     int level)
1735*61046927SAndroid Build Coastguard Worker {
1736*61046927SAndroid Build Coastguard Worker    uint32_t w, h, p;
1737*61046927SAndroid Build Coastguard Worker    uint32_t gpuaddr, flags, mip_gpuaddr, mip_flags;
1738*61046927SAndroid Build Coastguard Worker    uint32_t min, mag, swiz, clamp_x, clamp_y, clamp_z;
1739*61046927SAndroid Build Coastguard Worker    static const char *filter[] = {
1740*61046927SAndroid Build Coastguard Worker       "point",
1741*61046927SAndroid Build Coastguard Worker       "bilinear",
1742*61046927SAndroid Build Coastguard Worker       "bicubic",
1743*61046927SAndroid Build Coastguard Worker    };
1744*61046927SAndroid Build Coastguard Worker    static const char *clamp[] = {
1745*61046927SAndroid Build Coastguard Worker       "wrap",
1746*61046927SAndroid Build Coastguard Worker       "mirror",
1747*61046927SAndroid Build Coastguard Worker       "clamp-last-texel",
1748*61046927SAndroid Build Coastguard Worker    };
1749*61046927SAndroid Build Coastguard Worker    static const char swiznames[] = "xyzw01??";
1750*61046927SAndroid Build Coastguard Worker 
1751*61046927SAndroid Build Coastguard Worker    /* see sys2gmem_tex_const[] in adreno_a2xxx.c */
1752*61046927SAndroid Build Coastguard Worker 
1753*61046927SAndroid Build Coastguard Worker    /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat,
1754*61046927SAndroid Build Coastguard Worker     * RFMode=ZeroClamp-1, Dim=1:2d, pitch
1755*61046927SAndroid Build Coastguard Worker     */
1756*61046927SAndroid Build Coastguard Worker    p = (dwords[0] >> 22) << 5;
1757*61046927SAndroid Build Coastguard Worker    clamp_x = (dwords[0] >> 10) & 0x3;
1758*61046927SAndroid Build Coastguard Worker    clamp_y = (dwords[0] >> 13) & 0x3;
1759*61046927SAndroid Build Coastguard Worker    clamp_z = (dwords[0] >> 16) & 0x3;
1760*61046927SAndroid Build Coastguard Worker 
1761*61046927SAndroid Build Coastguard Worker    /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0,
1762*61046927SAndroid Build Coastguard Worker     * NearestClamp=1:OGL Mode
1763*61046927SAndroid Build Coastguard Worker     */
1764*61046927SAndroid Build Coastguard Worker    parse_dword_addr(dwords[1], &gpuaddr, &flags, 0xfff);
1765*61046927SAndroid Build Coastguard Worker 
1766*61046927SAndroid Build Coastguard Worker    /* Width, Height, EndianSwap=0:None */
1767*61046927SAndroid Build Coastguard Worker    w = (dwords[2] & 0x1fff) + 1;
1768*61046927SAndroid Build Coastguard Worker    h = ((dwords[2] >> 13) & 0x1fff) + 1;
1769*61046927SAndroid Build Coastguard Worker 
1770*61046927SAndroid Build Coastguard Worker    /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point,
1771*61046927SAndroid Build Coastguard Worker     * Mip=2:BaseMap
1772*61046927SAndroid Build Coastguard Worker     */
1773*61046927SAndroid Build Coastguard Worker    mag = (dwords[3] >> 19) & 0x3;
1774*61046927SAndroid Build Coastguard Worker    min = (dwords[3] >> 21) & 0x3;
1775*61046927SAndroid Build Coastguard Worker    swiz = (dwords[3] >> 1) & 0xfff;
1776*61046927SAndroid Build Coastguard Worker 
1777*61046927SAndroid Build Coastguard Worker    /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0,
1778*61046927SAndroid Build Coastguard Worker     * Dim3d=0
1779*61046927SAndroid Build Coastguard Worker     */
1780*61046927SAndroid Build Coastguard Worker    // XXX
1781*61046927SAndroid Build Coastguard Worker 
1782*61046927SAndroid Build Coastguard Worker    /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0,
1783*61046927SAndroid Build Coastguard Worker     * Dim=1:2d, MipPacking=0
1784*61046927SAndroid Build Coastguard Worker     */
1785*61046927SAndroid Build Coastguard Worker    parse_dword_addr(dwords[5], &mip_gpuaddr, &mip_flags, 0xfff);
1786*61046927SAndroid Build Coastguard Worker 
1787*61046927SAndroid Build Coastguard Worker    printf("%sset texture const %04x\n", levels[level], val);
1788*61046927SAndroid Build Coastguard Worker    printf("%sclamp x/y/z: %s/%s/%s\n", levels[level + 1], clamp[clamp_x],
1789*61046927SAndroid Build Coastguard Worker           clamp[clamp_y], clamp[clamp_z]);
1790*61046927SAndroid Build Coastguard Worker    printf("%sfilter min/mag: %s/%s\n", levels[level + 1], filter[min],
1791*61046927SAndroid Build Coastguard Worker           filter[mag]);
1792*61046927SAndroid Build Coastguard Worker    printf("%sswizzle: %c%c%c%c\n", levels[level + 1],
1793*61046927SAndroid Build Coastguard Worker           swiznames[(swiz >> 0) & 0x7], swiznames[(swiz >> 3) & 0x7],
1794*61046927SAndroid Build Coastguard Worker           swiznames[(swiz >> 6) & 0x7], swiznames[(swiz >> 9) & 0x7]);
1795*61046927SAndroid Build Coastguard Worker    printf("%saddr=%08x (flags=%03x), size=%dx%d, pitch=%d, format=%s\n",
1796*61046927SAndroid Build Coastguard Worker           levels[level + 1], gpuaddr, flags, w, h, p,
1797*61046927SAndroid Build Coastguard Worker           rnn_enumname(rnn, "a2xx_sq_surfaceformat", flags & 0xf));
1798*61046927SAndroid Build Coastguard Worker    printf("%smipaddr=%08x (flags=%03x)\n", levels[level + 1], mip_gpuaddr,
1799*61046927SAndroid Build Coastguard Worker           mip_flags);
1800*61046927SAndroid Build Coastguard Worker }
1801*61046927SAndroid Build Coastguard Worker 
1802*61046927SAndroid Build Coastguard Worker static void
dump_a2xx_shader_const(uint32_t * dwords,uint32_t sizedwords,uint32_t val,int level)1803*61046927SAndroid Build Coastguard Worker dump_a2xx_shader_const(uint32_t *dwords, uint32_t sizedwords, uint32_t val,
1804*61046927SAndroid Build Coastguard Worker                        int level)
1805*61046927SAndroid Build Coastguard Worker {
1806*61046927SAndroid Build Coastguard Worker    int i;
1807*61046927SAndroid Build Coastguard Worker    printf("%sset shader const %04x\n", levels[level], val);
1808*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords;) {
1809*61046927SAndroid Build Coastguard Worker       uint32_t gpuaddr, flags;
1810*61046927SAndroid Build Coastguard Worker       parse_dword_addr(dwords[i++], &gpuaddr, &flags, 0xf);
1811*61046927SAndroid Build Coastguard Worker       void *addr = hostptr(gpuaddr);
1812*61046927SAndroid Build Coastguard Worker       if (addr) {
1813*61046927SAndroid Build Coastguard Worker          const char *fmt =
1814*61046927SAndroid Build Coastguard Worker             rnn_enumname(rnn, "a2xx_sq_surfaceformat", flags & 0xf);
1815*61046927SAndroid Build Coastguard Worker          uint32_t size = dwords[i++];
1816*61046927SAndroid Build Coastguard Worker          printf("%saddr=%08x, size=%d, format=%s\n", levels[level + 1], gpuaddr,
1817*61046927SAndroid Build Coastguard Worker                 size, fmt);
1818*61046927SAndroid Build Coastguard Worker          // TODO maybe dump these as bytes instead of dwords?
1819*61046927SAndroid Build Coastguard Worker          size = (size + 3) / 4; // for now convert to dwords
1820*61046927SAndroid Build Coastguard Worker          dump_hex(addr, MIN2(size, 64), level + 1);
1821*61046927SAndroid Build Coastguard Worker          if (size > MIN2(size, 64))
1822*61046927SAndroid Build Coastguard Worker             printf("%s\t\t...\n", levels[level + 1]);
1823*61046927SAndroid Build Coastguard Worker          dump_float(addr, MIN2(size, 64), level + 1);
1824*61046927SAndroid Build Coastguard Worker          if (size > MIN2(size, 64))
1825*61046927SAndroid Build Coastguard Worker             printf("%s\t\t...\n", levels[level + 1]);
1826*61046927SAndroid Build Coastguard Worker       }
1827*61046927SAndroid Build Coastguard Worker    }
1828*61046927SAndroid Build Coastguard Worker }
1829*61046927SAndroid Build Coastguard Worker 
1830*61046927SAndroid Build Coastguard Worker static void
cp_set_const(uint32_t * dwords,uint32_t sizedwords,int level)1831*61046927SAndroid Build Coastguard Worker cp_set_const(uint32_t *dwords, uint32_t sizedwords, int level)
1832*61046927SAndroid Build Coastguard Worker {
1833*61046927SAndroid Build Coastguard Worker    uint32_t val = dwords[0] & 0xffff;
1834*61046927SAndroid Build Coastguard Worker    switch ((dwords[0] >> 16) & 0xf) {
1835*61046927SAndroid Build Coastguard Worker    case 0x0:
1836*61046927SAndroid Build Coastguard Worker       dump_float((float *)(dwords + 1), sizedwords - 1, level + 1);
1837*61046927SAndroid Build Coastguard Worker       break;
1838*61046927SAndroid Build Coastguard Worker    case 0x1:
1839*61046927SAndroid Build Coastguard Worker       /* need to figure out how const space is partitioned between
1840*61046927SAndroid Build Coastguard Worker        * attributes, textures, etc..
1841*61046927SAndroid Build Coastguard Worker        */
1842*61046927SAndroid Build Coastguard Worker       if (val < 0x78) {
1843*61046927SAndroid Build Coastguard Worker          dump_a2xx_tex_const(dwords + 1, sizedwords - 1, val, level);
1844*61046927SAndroid Build Coastguard Worker       } else {
1845*61046927SAndroid Build Coastguard Worker          dump_a2xx_shader_const(dwords + 1, sizedwords - 1, val, level);
1846*61046927SAndroid Build Coastguard Worker       }
1847*61046927SAndroid Build Coastguard Worker       break;
1848*61046927SAndroid Build Coastguard Worker    case 0x2:
1849*61046927SAndroid Build Coastguard Worker       printf("%sset bool const %04x\n", levels[level], val);
1850*61046927SAndroid Build Coastguard Worker       break;
1851*61046927SAndroid Build Coastguard Worker    case 0x3:
1852*61046927SAndroid Build Coastguard Worker       printf("%sset loop const %04x\n", levels[level], val);
1853*61046927SAndroid Build Coastguard Worker       break;
1854*61046927SAndroid Build Coastguard Worker    case 0x4:
1855*61046927SAndroid Build Coastguard Worker       val += 0x2000;
1856*61046927SAndroid Build Coastguard Worker       if (dwords[0] & 0x80000000) {
1857*61046927SAndroid Build Coastguard Worker          uint32_t srcreg = dwords[1];
1858*61046927SAndroid Build Coastguard Worker          uint32_t dstval = dwords[2];
1859*61046927SAndroid Build Coastguard Worker 
1860*61046927SAndroid Build Coastguard Worker          /* TODO: not sure what happens w/ payload != 2.. */
1861*61046927SAndroid Build Coastguard Worker          assert(sizedwords == 3);
1862*61046927SAndroid Build Coastguard Worker          assert(srcreg < ARRAY_SIZE(type0_reg_vals));
1863*61046927SAndroid Build Coastguard Worker 
1864*61046927SAndroid Build Coastguard Worker          /* note: rnn_regname uses a static buf so we can't do
1865*61046927SAndroid Build Coastguard Worker           * two regname() calls for one printf..
1866*61046927SAndroid Build Coastguard Worker           */
1867*61046927SAndroid Build Coastguard Worker          printf("%s%s = %08x + ", levels[level], regname(val, 1), dstval);
1868*61046927SAndroid Build Coastguard Worker          printf("%s (%08x)\n", regname(srcreg, 1), type0_reg_vals[srcreg]);
1869*61046927SAndroid Build Coastguard Worker 
1870*61046927SAndroid Build Coastguard Worker          dstval += type0_reg_vals[srcreg];
1871*61046927SAndroid Build Coastguard Worker 
1872*61046927SAndroid Build Coastguard Worker          dump_registers(val, &dstval, 1, level + 1);
1873*61046927SAndroid Build Coastguard Worker       } else {
1874*61046927SAndroid Build Coastguard Worker          dump_registers(val, dwords + 1, sizedwords - 1, level + 1);
1875*61046927SAndroid Build Coastguard Worker       }
1876*61046927SAndroid Build Coastguard Worker       break;
1877*61046927SAndroid Build Coastguard Worker    }
1878*61046927SAndroid Build Coastguard Worker }
1879*61046927SAndroid Build Coastguard Worker 
1880*61046927SAndroid Build Coastguard Worker static void dump_register_summary(int level);
1881*61046927SAndroid Build Coastguard Worker 
1882*61046927SAndroid Build Coastguard Worker static void
cp_event_write(uint32_t * dwords,uint32_t sizedwords,int level)1883*61046927SAndroid Build Coastguard Worker cp_event_write(uint32_t *dwords, uint32_t sizedwords, int level)
1884*61046927SAndroid Build Coastguard Worker {
1885*61046927SAndroid Build Coastguard Worker    const char *name = rnn_enumname(rnn, "vgt_event_type", dwords[0] & 0xff);
1886*61046927SAndroid Build Coastguard Worker    printl(2, "%sevent %s\n", levels[level], name);
1887*61046927SAndroid Build Coastguard Worker 
1888*61046927SAndroid Build Coastguard Worker    if (name && (options->info->chip > 5)) {
1889*61046927SAndroid Build Coastguard Worker       char eventname[64];
1890*61046927SAndroid Build Coastguard Worker       snprintf(eventname, sizeof(eventname), "EVENT:%s", name);
1891*61046927SAndroid Build Coastguard Worker       if (!strcmp(name, "BLIT") || !strcmp(name, "LRZ_CLEAR")) {
1892*61046927SAndroid Build Coastguard Worker          do_query(eventname, 0);
1893*61046927SAndroid Build Coastguard Worker          print_mode(level);
1894*61046927SAndroid Build Coastguard Worker          dump_register_summary(level);
1895*61046927SAndroid Build Coastguard Worker       }
1896*61046927SAndroid Build Coastguard Worker    }
1897*61046927SAndroid Build Coastguard Worker }
1898*61046927SAndroid Build Coastguard Worker 
1899*61046927SAndroid Build Coastguard Worker static void
dump_register_summary(int level)1900*61046927SAndroid Build Coastguard Worker dump_register_summary(int level)
1901*61046927SAndroid Build Coastguard Worker {
1902*61046927SAndroid Build Coastguard Worker    uint32_t i;
1903*61046927SAndroid Build Coastguard Worker    bool saved_summary = summary;
1904*61046927SAndroid Build Coastguard Worker    summary = false;
1905*61046927SAndroid Build Coastguard Worker 
1906*61046927SAndroid Build Coastguard Worker    in_summary = true;
1907*61046927SAndroid Build Coastguard Worker 
1908*61046927SAndroid Build Coastguard Worker    struct regacc r = regacc(NULL);
1909*61046927SAndroid Build Coastguard Worker 
1910*61046927SAndroid Build Coastguard Worker    /* dump current state of registers: */
1911*61046927SAndroid Build Coastguard Worker    printl(2, "%sdraw[%i] register values\n", levels[level], draw_count);
1912*61046927SAndroid Build Coastguard Worker 
1913*61046927SAndroid Build Coastguard Worker    bool changed = false;
1914*61046927SAndroid Build Coastguard Worker    bool written = false;
1915*61046927SAndroid Build Coastguard Worker 
1916*61046927SAndroid Build Coastguard Worker    for (i = 0; i < regcnt(); i++) {
1917*61046927SAndroid Build Coastguard Worker       uint32_t regbase = i;
1918*61046927SAndroid Build Coastguard Worker       uint32_t lastval = reg_val(regbase);
1919*61046927SAndroid Build Coastguard Worker       /* skip registers that haven't been updated since last draw/blit: */
1920*61046927SAndroid Build Coastguard Worker       if (!(options->allregs || reg_rewritten(regbase)))
1921*61046927SAndroid Build Coastguard Worker          continue;
1922*61046927SAndroid Build Coastguard Worker       if (!reg_written(regbase))
1923*61046927SAndroid Build Coastguard Worker          continue;
1924*61046927SAndroid Build Coastguard Worker       if (lastval != lastvals[regbase]) {
1925*61046927SAndroid Build Coastguard Worker          changed |= true;
1926*61046927SAndroid Build Coastguard Worker          lastvals[regbase] = lastval;
1927*61046927SAndroid Build Coastguard Worker       }
1928*61046927SAndroid Build Coastguard Worker       if (reg_rewritten(regbase)) {
1929*61046927SAndroid Build Coastguard Worker          written |= true;
1930*61046927SAndroid Build Coastguard Worker       }
1931*61046927SAndroid Build Coastguard Worker       if (!quiet(2)) {
1932*61046927SAndroid Build Coastguard Worker          if (regacc_push(&r, regbase, lastval)) {
1933*61046927SAndroid Build Coastguard Worker             if (changed) {
1934*61046927SAndroid Build Coastguard Worker                printl(2, "!");
1935*61046927SAndroid Build Coastguard Worker             } else {
1936*61046927SAndroid Build Coastguard Worker                printl(2, " ");
1937*61046927SAndroid Build Coastguard Worker             }
1938*61046927SAndroid Build Coastguard Worker             if (written) {
1939*61046927SAndroid Build Coastguard Worker                printl(2, "+");
1940*61046927SAndroid Build Coastguard Worker             } else {
1941*61046927SAndroid Build Coastguard Worker                printl(2, " ");
1942*61046927SAndroid Build Coastguard Worker             }
1943*61046927SAndroid Build Coastguard Worker             printl(2, "\t%08"PRIx64, r.value);
1944*61046927SAndroid Build Coastguard Worker             dump_register(&r, level);
1945*61046927SAndroid Build Coastguard Worker 
1946*61046927SAndroid Build Coastguard Worker             changed = written = false;
1947*61046927SAndroid Build Coastguard Worker          }
1948*61046927SAndroid Build Coastguard Worker       }
1949*61046927SAndroid Build Coastguard Worker    }
1950*61046927SAndroid Build Coastguard Worker 
1951*61046927SAndroid Build Coastguard Worker    clear_rewritten();
1952*61046927SAndroid Build Coastguard Worker 
1953*61046927SAndroid Build Coastguard Worker    in_summary = false;
1954*61046927SAndroid Build Coastguard Worker 
1955*61046927SAndroid Build Coastguard Worker    draw_count++;
1956*61046927SAndroid Build Coastguard Worker    summary = saved_summary;
1957*61046927SAndroid Build Coastguard Worker }
1958*61046927SAndroid Build Coastguard Worker 
1959*61046927SAndroid Build Coastguard Worker static uint32_t
draw_indx_common(uint32_t * dwords,int level)1960*61046927SAndroid Build Coastguard Worker draw_indx_common(uint32_t *dwords, int level)
1961*61046927SAndroid Build Coastguard Worker {
1962*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[1] & 0x1f;
1963*61046927SAndroid Build Coastguard Worker    uint32_t source_select = (dwords[1] >> 6) & 0x3;
1964*61046927SAndroid Build Coastguard Worker    uint32_t num_indices = dwords[2];
1965*61046927SAndroid Build Coastguard Worker    const char *primtype;
1966*61046927SAndroid Build Coastguard Worker 
1967*61046927SAndroid Build Coastguard Worker    primtype = rnn_enumname(rnn, "pc_di_primtype", prim_type);
1968*61046927SAndroid Build Coastguard Worker 
1969*61046927SAndroid Build Coastguard Worker    do_query(primtype, num_indices);
1970*61046927SAndroid Build Coastguard Worker 
1971*61046927SAndroid Build Coastguard Worker    printl(2, "%sdraw:          %d\n", levels[level], draws[ib]);
1972*61046927SAndroid Build Coastguard Worker    printl(2, "%sprim_type:     %s (%d)\n", levels[level], primtype, prim_type);
1973*61046927SAndroid Build Coastguard Worker    printl(2, "%ssource_select: %s (%d)\n", levels[level],
1974*61046927SAndroid Build Coastguard Worker           rnn_enumname(rnn, "pc_di_src_sel", source_select), source_select);
1975*61046927SAndroid Build Coastguard Worker    printl(2, "%snum_indices:   %d\n", levels[level], num_indices);
1976*61046927SAndroid Build Coastguard Worker 
1977*61046927SAndroid Build Coastguard Worker    vertices += num_indices;
1978*61046927SAndroid Build Coastguard Worker 
1979*61046927SAndroid Build Coastguard Worker    draws[ib]++;
1980*61046927SAndroid Build Coastguard Worker 
1981*61046927SAndroid Build Coastguard Worker    return num_indices;
1982*61046927SAndroid Build Coastguard Worker }
1983*61046927SAndroid Build Coastguard Worker 
1984*61046927SAndroid Build Coastguard Worker enum pc_di_index_size {
1985*61046927SAndroid Build Coastguard Worker    INDEX_SIZE_IGN = 0,
1986*61046927SAndroid Build Coastguard Worker    INDEX_SIZE_16_BIT = 0,
1987*61046927SAndroid Build Coastguard Worker    INDEX_SIZE_32_BIT = 1,
1988*61046927SAndroid Build Coastguard Worker    INDEX_SIZE_8_BIT = 2,
1989*61046927SAndroid Build Coastguard Worker    INDEX_SIZE_INVALID = 0,
1990*61046927SAndroid Build Coastguard Worker };
1991*61046927SAndroid Build Coastguard Worker 
1992*61046927SAndroid Build Coastguard Worker static void
cp_draw_indx(uint32_t * dwords,uint32_t sizedwords,int level)1993*61046927SAndroid Build Coastguard Worker cp_draw_indx(uint32_t *dwords, uint32_t sizedwords, int level)
1994*61046927SAndroid Build Coastguard Worker {
1995*61046927SAndroid Build Coastguard Worker    uint32_t num_indices = draw_indx_common(dwords, level);
1996*61046927SAndroid Build Coastguard Worker 
1997*61046927SAndroid Build Coastguard Worker    assert(!is_64b());
1998*61046927SAndroid Build Coastguard Worker 
1999*61046927SAndroid Build Coastguard Worker    /* if we have an index buffer, dump that: */
2000*61046927SAndroid Build Coastguard Worker    if (sizedwords == 5) {
2001*61046927SAndroid Build Coastguard Worker       void *ptr = hostptr(dwords[3]);
2002*61046927SAndroid Build Coastguard Worker       printl(2, "%sgpuaddr:       %08x\n", levels[level], dwords[3]);
2003*61046927SAndroid Build Coastguard Worker       printl(2, "%sidx_size:      %d\n", levels[level], dwords[4]);
2004*61046927SAndroid Build Coastguard Worker       if (ptr) {
2005*61046927SAndroid Build Coastguard Worker          enum pc_di_index_size size =
2006*61046927SAndroid Build Coastguard Worker             ((dwords[1] >> 11) & 1) | ((dwords[1] >> 12) & 2);
2007*61046927SAndroid Build Coastguard Worker          if (!quiet(2)) {
2008*61046927SAndroid Build Coastguard Worker             int i;
2009*61046927SAndroid Build Coastguard Worker             printf("%sidxs:         ", levels[level]);
2010*61046927SAndroid Build Coastguard Worker             if (size == INDEX_SIZE_8_BIT) {
2011*61046927SAndroid Build Coastguard Worker                uint8_t *idx = ptr;
2012*61046927SAndroid Build Coastguard Worker                for (i = 0; i < dwords[4]; i++)
2013*61046927SAndroid Build Coastguard Worker                   printf(" %u", idx[i]);
2014*61046927SAndroid Build Coastguard Worker             } else if (size == INDEX_SIZE_16_BIT) {
2015*61046927SAndroid Build Coastguard Worker                uint16_t *idx = ptr;
2016*61046927SAndroid Build Coastguard Worker                for (i = 0; i < dwords[4] / 2; i++)
2017*61046927SAndroid Build Coastguard Worker                   printf(" %u", idx[i]);
2018*61046927SAndroid Build Coastguard Worker             } else if (size == INDEX_SIZE_32_BIT) {
2019*61046927SAndroid Build Coastguard Worker                uint32_t *idx = ptr;
2020*61046927SAndroid Build Coastguard Worker                for (i = 0; i < dwords[4] / 4; i++)
2021*61046927SAndroid Build Coastguard Worker                   printf(" %u", idx[i]);
2022*61046927SAndroid Build Coastguard Worker             }
2023*61046927SAndroid Build Coastguard Worker             printf("\n");
2024*61046927SAndroid Build Coastguard Worker             dump_hex(ptr, dwords[4] / 4, level + 1);
2025*61046927SAndroid Build Coastguard Worker          }
2026*61046927SAndroid Build Coastguard Worker       }
2027*61046927SAndroid Build Coastguard Worker    }
2028*61046927SAndroid Build Coastguard Worker 
2029*61046927SAndroid Build Coastguard Worker    /* don't bother dumping registers for the dummy draw_indx's.. */
2030*61046927SAndroid Build Coastguard Worker    if (num_indices > 0)
2031*61046927SAndroid Build Coastguard Worker       dump_register_summary(level);
2032*61046927SAndroid Build Coastguard Worker 
2033*61046927SAndroid Build Coastguard Worker    needs_wfi = true;
2034*61046927SAndroid Build Coastguard Worker }
2035*61046927SAndroid Build Coastguard Worker 
2036*61046927SAndroid Build Coastguard Worker static void
cp_draw_indx_2(uint32_t * dwords,uint32_t sizedwords,int level)2037*61046927SAndroid Build Coastguard Worker cp_draw_indx_2(uint32_t *dwords, uint32_t sizedwords, int level)
2038*61046927SAndroid Build Coastguard Worker {
2039*61046927SAndroid Build Coastguard Worker    uint32_t num_indices = draw_indx_common(dwords, level);
2040*61046927SAndroid Build Coastguard Worker    enum pc_di_index_size size =
2041*61046927SAndroid Build Coastguard Worker       ((dwords[1] >> 11) & 1) | ((dwords[1] >> 12) & 2);
2042*61046927SAndroid Build Coastguard Worker    void *ptr = &dwords[3];
2043*61046927SAndroid Build Coastguard Worker    int sz = 0;
2044*61046927SAndroid Build Coastguard Worker 
2045*61046927SAndroid Build Coastguard Worker    assert(!is_64b());
2046*61046927SAndroid Build Coastguard Worker 
2047*61046927SAndroid Build Coastguard Worker    /* CP_DRAW_INDX_2 has embedded/inline idx buffer: */
2048*61046927SAndroid Build Coastguard Worker    if (!quiet(2)) {
2049*61046927SAndroid Build Coastguard Worker       int i;
2050*61046927SAndroid Build Coastguard Worker       printf("%sidxs:         ", levels[level]);
2051*61046927SAndroid Build Coastguard Worker       if (size == INDEX_SIZE_8_BIT) {
2052*61046927SAndroid Build Coastguard Worker          uint8_t *idx = ptr;
2053*61046927SAndroid Build Coastguard Worker          for (i = 0; i < num_indices; i++)
2054*61046927SAndroid Build Coastguard Worker             printf(" %u", idx[i]);
2055*61046927SAndroid Build Coastguard Worker          sz = num_indices;
2056*61046927SAndroid Build Coastguard Worker       } else if (size == INDEX_SIZE_16_BIT) {
2057*61046927SAndroid Build Coastguard Worker          uint16_t *idx = ptr;
2058*61046927SAndroid Build Coastguard Worker          for (i = 0; i < num_indices; i++)
2059*61046927SAndroid Build Coastguard Worker             printf(" %u", idx[i]);
2060*61046927SAndroid Build Coastguard Worker          sz = num_indices * 2;
2061*61046927SAndroid Build Coastguard Worker       } else if (size == INDEX_SIZE_32_BIT) {
2062*61046927SAndroid Build Coastguard Worker          uint32_t *idx = ptr;
2063*61046927SAndroid Build Coastguard Worker          for (i = 0; i < num_indices; i++)
2064*61046927SAndroid Build Coastguard Worker             printf(" %u", idx[i]);
2065*61046927SAndroid Build Coastguard Worker          sz = num_indices * 4;
2066*61046927SAndroid Build Coastguard Worker       }
2067*61046927SAndroid Build Coastguard Worker       printf("\n");
2068*61046927SAndroid Build Coastguard Worker       dump_hex(ptr, sz / 4, level + 1);
2069*61046927SAndroid Build Coastguard Worker    }
2070*61046927SAndroid Build Coastguard Worker 
2071*61046927SAndroid Build Coastguard Worker    /* don't bother dumping registers for the dummy draw_indx's.. */
2072*61046927SAndroid Build Coastguard Worker    if (num_indices > 0)
2073*61046927SAndroid Build Coastguard Worker       dump_register_summary(level);
2074*61046927SAndroid Build Coastguard Worker }
2075*61046927SAndroid Build Coastguard Worker 
2076*61046927SAndroid Build Coastguard Worker static void
cp_draw_indx_offset(uint32_t * dwords,uint32_t sizedwords,int level)2077*61046927SAndroid Build Coastguard Worker cp_draw_indx_offset(uint32_t *dwords, uint32_t sizedwords, int level)
2078*61046927SAndroid Build Coastguard Worker {
2079*61046927SAndroid Build Coastguard Worker    uint32_t num_indices = dwords[2];
2080*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[0] & 0x1f;
2081*61046927SAndroid Build Coastguard Worker 
2082*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), num_indices);
2083*61046927SAndroid Build Coastguard Worker    print_mode(level);
2084*61046927SAndroid Build Coastguard Worker 
2085*61046927SAndroid Build Coastguard Worker    /* don't bother dumping registers for the dummy draw_indx's.. */
2086*61046927SAndroid Build Coastguard Worker    if (num_indices > 0)
2087*61046927SAndroid Build Coastguard Worker       dump_register_summary(level);
2088*61046927SAndroid Build Coastguard Worker }
2089*61046927SAndroid Build Coastguard Worker 
2090*61046927SAndroid Build Coastguard Worker static void
cp_draw_indx_indirect(uint32_t * dwords,uint32_t sizedwords,int level)2091*61046927SAndroid Build Coastguard Worker cp_draw_indx_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
2092*61046927SAndroid Build Coastguard Worker {
2093*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[0] & 0x1f;
2094*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2095*61046927SAndroid Build Coastguard Worker 
2096*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), 0);
2097*61046927SAndroid Build Coastguard Worker    print_mode(level);
2098*61046927SAndroid Build Coastguard Worker 
2099*61046927SAndroid Build Coastguard Worker    if (is_64b())
2100*61046927SAndroid Build Coastguard Worker       addr = (((uint64_t)dwords[2] & 0x1ffff) << 32) | dwords[1];
2101*61046927SAndroid Build Coastguard Worker    else
2102*61046927SAndroid Build Coastguard Worker       addr = dwords[1];
2103*61046927SAndroid Build Coastguard Worker    dump_gpuaddr_size(addr, level, 0x10, 2);
2104*61046927SAndroid Build Coastguard Worker 
2105*61046927SAndroid Build Coastguard Worker    if (is_64b())
2106*61046927SAndroid Build Coastguard Worker       addr = (((uint64_t)dwords[5] & 0x1ffff) << 32) | dwords[4];
2107*61046927SAndroid Build Coastguard Worker    else
2108*61046927SAndroid Build Coastguard Worker       addr = dwords[3];
2109*61046927SAndroid Build Coastguard Worker    dump_gpuaddr_size(addr, level, 0x10, 2);
2110*61046927SAndroid Build Coastguard Worker 
2111*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2112*61046927SAndroid Build Coastguard Worker }
2113*61046927SAndroid Build Coastguard Worker 
2114*61046927SAndroid Build Coastguard Worker static void
cp_draw_indirect(uint32_t * dwords,uint32_t sizedwords,int level)2115*61046927SAndroid Build Coastguard Worker cp_draw_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
2116*61046927SAndroid Build Coastguard Worker {
2117*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[0] & 0x1f;
2118*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2119*61046927SAndroid Build Coastguard Worker 
2120*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), 0);
2121*61046927SAndroid Build Coastguard Worker    print_mode(level);
2122*61046927SAndroid Build Coastguard Worker 
2123*61046927SAndroid Build Coastguard Worker    addr = (((uint64_t)dwords[2] & 0x1ffff) << 32) | dwords[1];
2124*61046927SAndroid Build Coastguard Worker    dump_gpuaddr_size(addr, level, 0x10, 2);
2125*61046927SAndroid Build Coastguard Worker 
2126*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2127*61046927SAndroid Build Coastguard Worker }
2128*61046927SAndroid Build Coastguard Worker 
2129*61046927SAndroid Build Coastguard Worker static void
cp_draw_indirect_multi(uint32_t * dwords,uint32_t sizedwords,int level)2130*61046927SAndroid Build Coastguard Worker cp_draw_indirect_multi(uint32_t *dwords, uint32_t sizedwords, int level)
2131*61046927SAndroid Build Coastguard Worker {
2132*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[0] & 0x1f;
2133*61046927SAndroid Build Coastguard Worker    uint32_t count = dwords[2];
2134*61046927SAndroid Build Coastguard Worker 
2135*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), 0);
2136*61046927SAndroid Build Coastguard Worker    print_mode(level);
2137*61046927SAndroid Build Coastguard Worker 
2138*61046927SAndroid Build Coastguard Worker    struct rnndomain *domain = rnn_finddomain(rnn->db, "CP_DRAW_INDIRECT_MULTI");
2139*61046927SAndroid Build Coastguard Worker    uint32_t count_dword = rnndec_decodereg(rnn->vc, domain, "INDIRECT_COUNT");
2140*61046927SAndroid Build Coastguard Worker    uint32_t addr_dword = rnndec_decodereg(rnn->vc, domain, "INDIRECT");
2141*61046927SAndroid Build Coastguard Worker    uint64_t stride_dword = rnndec_decodereg(rnn->vc, domain, "STRIDE");
2142*61046927SAndroid Build Coastguard Worker 
2143*61046927SAndroid Build Coastguard Worker    if (count_dword) {
2144*61046927SAndroid Build Coastguard Worker       uint64_t count_addr =
2145*61046927SAndroid Build Coastguard Worker          ((uint64_t)dwords[count_dword + 1] << 32) | dwords[count_dword];
2146*61046927SAndroid Build Coastguard Worker       uint32_t *buf = hostptr(count_addr);
2147*61046927SAndroid Build Coastguard Worker 
2148*61046927SAndroid Build Coastguard Worker       /* Don't print more draws than this if we don't know the indirect
2149*61046927SAndroid Build Coastguard Worker        * count. It's possible the user will give ~0 or some other large
2150*61046927SAndroid Build Coastguard Worker        * value, expecting the GPU to fill in the draw count, and we don't
2151*61046927SAndroid Build Coastguard Worker        * want to print a gazillion draws in that case:
2152*61046927SAndroid Build Coastguard Worker        */
2153*61046927SAndroid Build Coastguard Worker       const uint32_t max_draw_count = 0x100;
2154*61046927SAndroid Build Coastguard Worker 
2155*61046927SAndroid Build Coastguard Worker       /* Assume the indirect count is garbage if it's larger than this
2156*61046927SAndroid Build Coastguard Worker        * (quite large) value or 0. Hopefully this catches most cases.
2157*61046927SAndroid Build Coastguard Worker        */
2158*61046927SAndroid Build Coastguard Worker       const uint32_t max_indirect_draw_count = 0x10000;
2159*61046927SAndroid Build Coastguard Worker 
2160*61046927SAndroid Build Coastguard Worker       if (buf) {
2161*61046927SAndroid Build Coastguard Worker          printf("%sindirect count: %u\n", levels[level], *buf);
2162*61046927SAndroid Build Coastguard Worker          if (*buf == 0 || *buf > max_indirect_draw_count) {
2163*61046927SAndroid Build Coastguard Worker             /* garbage value */
2164*61046927SAndroid Build Coastguard Worker             count = MIN2(count, max_draw_count);
2165*61046927SAndroid Build Coastguard Worker          } else {
2166*61046927SAndroid Build Coastguard Worker             /* not garbage */
2167*61046927SAndroid Build Coastguard Worker             count = MIN2(count, *buf);
2168*61046927SAndroid Build Coastguard Worker          }
2169*61046927SAndroid Build Coastguard Worker       } else {
2170*61046927SAndroid Build Coastguard Worker          count = MIN2(count, max_draw_count);
2171*61046927SAndroid Build Coastguard Worker       }
2172*61046927SAndroid Build Coastguard Worker    }
2173*61046927SAndroid Build Coastguard Worker 
2174*61046927SAndroid Build Coastguard Worker    if (addr_dword && stride_dword) {
2175*61046927SAndroid Build Coastguard Worker       uint64_t addr =
2176*61046927SAndroid Build Coastguard Worker          ((uint64_t)dwords[addr_dword + 1] << 32) | dwords[addr_dword];
2177*61046927SAndroid Build Coastguard Worker       uint32_t stride = dwords[stride_dword];
2178*61046927SAndroid Build Coastguard Worker 
2179*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < count; i++, addr += stride) {
2180*61046927SAndroid Build Coastguard Worker          printf("%sdraw %d:\n", levels[level], i);
2181*61046927SAndroid Build Coastguard Worker          dump_gpuaddr_size(addr, level, 0x10, 2);
2182*61046927SAndroid Build Coastguard Worker       }
2183*61046927SAndroid Build Coastguard Worker    }
2184*61046927SAndroid Build Coastguard Worker 
2185*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2186*61046927SAndroid Build Coastguard Worker }
2187*61046927SAndroid Build Coastguard Worker 
2188*61046927SAndroid Build Coastguard Worker static void
cp_draw_auto(uint32_t * dwords,uint32_t sizedwords,int level)2189*61046927SAndroid Build Coastguard Worker cp_draw_auto(uint32_t *dwords, uint32_t sizedwords, int level)
2190*61046927SAndroid Build Coastguard Worker {
2191*61046927SAndroid Build Coastguard Worker    uint32_t prim_type = dwords[0] & 0x1f;
2192*61046927SAndroid Build Coastguard Worker 
2193*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "pc_di_primtype", prim_type), 0);
2194*61046927SAndroid Build Coastguard Worker    print_mode(level);
2195*61046927SAndroid Build Coastguard Worker 
2196*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2197*61046927SAndroid Build Coastguard Worker }
2198*61046927SAndroid Build Coastguard Worker 
2199*61046927SAndroid Build Coastguard Worker static void
cp_run_cl(uint32_t * dwords,uint32_t sizedwords,int level)2200*61046927SAndroid Build Coastguard Worker cp_run_cl(uint32_t *dwords, uint32_t sizedwords, int level)
2201*61046927SAndroid Build Coastguard Worker {
2202*61046927SAndroid Build Coastguard Worker    do_query("COMPUTE", 1);
2203*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2204*61046927SAndroid Build Coastguard Worker }
2205*61046927SAndroid Build Coastguard Worker 
2206*61046927SAndroid Build Coastguard Worker static void
print_nop_tail_string(uint32_t * dwords,uint32_t sizedwords)2207*61046927SAndroid Build Coastguard Worker print_nop_tail_string(uint32_t *dwords, uint32_t sizedwords)
2208*61046927SAndroid Build Coastguard Worker {
2209*61046927SAndroid Build Coastguard Worker    const char *buf = (void *)dwords;
2210*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < 4 * sizedwords; i++) {
2211*61046927SAndroid Build Coastguard Worker       if (buf[i] == '\0')
2212*61046927SAndroid Build Coastguard Worker          break;
2213*61046927SAndroid Build Coastguard Worker       if (isascii(buf[i]))
2214*61046927SAndroid Build Coastguard Worker          printf("%c", buf[i]);
2215*61046927SAndroid Build Coastguard Worker    }
2216*61046927SAndroid Build Coastguard Worker }
2217*61046927SAndroid Build Coastguard Worker 
2218*61046927SAndroid Build Coastguard Worker static void
cp_nop(uint32_t * dwords,uint32_t sizedwords,int level)2219*61046927SAndroid Build Coastguard Worker cp_nop(uint32_t *dwords, uint32_t sizedwords, int level)
2220*61046927SAndroid Build Coastguard Worker {
2221*61046927SAndroid Build Coastguard Worker    if (quiet(3))
2222*61046927SAndroid Build Coastguard Worker       return;
2223*61046927SAndroid Build Coastguard Worker 
2224*61046927SAndroid Build Coastguard Worker    /* NOP is used to encode special debug strings by Turnip.
2225*61046927SAndroid Build Coastguard Worker     * See tu_cs_emit_debug_magic_strv(...)
2226*61046927SAndroid Build Coastguard Worker     */
2227*61046927SAndroid Build Coastguard Worker    static int scope_level = 0;
2228*61046927SAndroid Build Coastguard Worker    uint32_t identifier = dwords[0];
2229*61046927SAndroid Build Coastguard Worker    bool is_special = false;
2230*61046927SAndroid Build Coastguard Worker    if (identifier == CP_NOP_MESG) {
2231*61046927SAndroid Build Coastguard Worker       printf("### ");
2232*61046927SAndroid Build Coastguard Worker       is_special = true;
2233*61046927SAndroid Build Coastguard Worker    } else if (identifier == CP_NOP_BEGN) {
2234*61046927SAndroid Build Coastguard Worker       printf(">>> #%d: ", ++scope_level);
2235*61046927SAndroid Build Coastguard Worker       is_special = true;
2236*61046927SAndroid Build Coastguard Worker    } else if (identifier == CP_NOP_END) {
2237*61046927SAndroid Build Coastguard Worker       printf("<<< #%d: ", scope_level--);
2238*61046927SAndroid Build Coastguard Worker       is_special = true;
2239*61046927SAndroid Build Coastguard Worker    }
2240*61046927SAndroid Build Coastguard Worker 
2241*61046927SAndroid Build Coastguard Worker    if (is_special) {
2242*61046927SAndroid Build Coastguard Worker       if (sizedwords > 1) {
2243*61046927SAndroid Build Coastguard Worker          print_nop_tail_string(dwords + 1, sizedwords - 1);
2244*61046927SAndroid Build Coastguard Worker          printf("\n");
2245*61046927SAndroid Build Coastguard Worker       }
2246*61046927SAndroid Build Coastguard Worker       return;
2247*61046927SAndroid Build Coastguard Worker    }
2248*61046927SAndroid Build Coastguard Worker 
2249*61046927SAndroid Build Coastguard Worker    // blob doesn't use CP_NOP for string_marker but it does
2250*61046927SAndroid Build Coastguard Worker    // use it for things that end up looking like, but aren't
2251*61046927SAndroid Build Coastguard Worker    // ascii chars:
2252*61046927SAndroid Build Coastguard Worker    if (!options->decode_markers)
2253*61046927SAndroid Build Coastguard Worker       return;
2254*61046927SAndroid Build Coastguard Worker 
2255*61046927SAndroid Build Coastguard Worker    print_nop_tail_string(dwords, sizedwords);
2256*61046927SAndroid Build Coastguard Worker    printf("\n");
2257*61046927SAndroid Build Coastguard Worker }
2258*61046927SAndroid Build Coastguard Worker 
2259*61046927SAndroid Build Coastguard Worker uint32_t *
parse_cp_indirect(uint32_t * dwords,uint32_t sizedwords,uint64_t * ibaddr,uint32_t * ibsize)2260*61046927SAndroid Build Coastguard Worker parse_cp_indirect(uint32_t *dwords, uint32_t sizedwords,
2261*61046927SAndroid Build Coastguard Worker                   uint64_t *ibaddr, uint32_t *ibsize)
2262*61046927SAndroid Build Coastguard Worker {
2263*61046927SAndroid Build Coastguard Worker    if (is_64b()) {
2264*61046927SAndroid Build Coastguard Worker       assert(sizedwords == 3);
2265*61046927SAndroid Build Coastguard Worker 
2266*61046927SAndroid Build Coastguard Worker       /* a5xx+.. high 32b of gpu addr, then size: */
2267*61046927SAndroid Build Coastguard Worker       *ibaddr = dwords[0];
2268*61046927SAndroid Build Coastguard Worker       *ibaddr |= ((uint64_t)dwords[1]) << 32;
2269*61046927SAndroid Build Coastguard Worker       *ibsize = dwords[2];
2270*61046927SAndroid Build Coastguard Worker 
2271*61046927SAndroid Build Coastguard Worker       return dwords + 3;
2272*61046927SAndroid Build Coastguard Worker    } else {
2273*61046927SAndroid Build Coastguard Worker       assert(sizedwords == 2);
2274*61046927SAndroid Build Coastguard Worker 
2275*61046927SAndroid Build Coastguard Worker       *ibaddr = dwords[0];
2276*61046927SAndroid Build Coastguard Worker       *ibsize = dwords[1];
2277*61046927SAndroid Build Coastguard Worker 
2278*61046927SAndroid Build Coastguard Worker       return dwords + 2;
2279*61046927SAndroid Build Coastguard Worker    }
2280*61046927SAndroid Build Coastguard Worker }
2281*61046927SAndroid Build Coastguard Worker 
2282*61046927SAndroid Build Coastguard Worker static void
cp_indirect(uint32_t * dwords,uint32_t sizedwords,int level)2283*61046927SAndroid Build Coastguard Worker cp_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
2284*61046927SAndroid Build Coastguard Worker {
2285*61046927SAndroid Build Coastguard Worker    /* traverse indirect buffers */
2286*61046927SAndroid Build Coastguard Worker    uint64_t ibaddr;
2287*61046927SAndroid Build Coastguard Worker    uint32_t ibsize;
2288*61046927SAndroid Build Coastguard Worker    uint32_t *ptr = NULL;
2289*61046927SAndroid Build Coastguard Worker 
2290*61046927SAndroid Build Coastguard Worker    dwords = parse_cp_indirect(dwords, sizedwords, &ibaddr, &ibsize);
2291*61046927SAndroid Build Coastguard Worker 
2292*61046927SAndroid Build Coastguard Worker    if (!quiet(3)) {
2293*61046927SAndroid Build Coastguard Worker       if (is_64b()) {
2294*61046927SAndroid Build Coastguard Worker          printf("%sibaddr:%016" PRIx64 "\n", levels[level], ibaddr);
2295*61046927SAndroid Build Coastguard Worker       } else {
2296*61046927SAndroid Build Coastguard Worker          printf("%sibaddr:%08x\n", levels[level], (uint32_t)ibaddr);
2297*61046927SAndroid Build Coastguard Worker       }
2298*61046927SAndroid Build Coastguard Worker       printf("%sibsize:%08x\n", levels[level], ibsize);
2299*61046927SAndroid Build Coastguard Worker    }
2300*61046927SAndroid Build Coastguard Worker 
2301*61046927SAndroid Build Coastguard Worker    if (options->once && has_dumped(ibaddr, enable_mask))
2302*61046927SAndroid Build Coastguard Worker       return;
2303*61046927SAndroid Build Coastguard Worker 
2304*61046927SAndroid Build Coastguard Worker    /* 'query-compare' mode implies 'once' mode, although we need only to
2305*61046927SAndroid Build Coastguard Worker     * process the cmdstream for *any* enable_mask mode, since we are
2306*61046927SAndroid Build Coastguard Worker     * comparing binning vs draw reg values at the same time, ie. it is
2307*61046927SAndroid Build Coastguard Worker     * not useful to process the same draw in both binning and draw pass.
2308*61046927SAndroid Build Coastguard Worker     */
2309*61046927SAndroid Build Coastguard Worker    if (options->query_compare && has_dumped(ibaddr, MODE_ALL))
2310*61046927SAndroid Build Coastguard Worker       return;
2311*61046927SAndroid Build Coastguard Worker 
2312*61046927SAndroid Build Coastguard Worker    /* map gpuaddr back to hostptr: */
2313*61046927SAndroid Build Coastguard Worker    ptr = hostptr(ibaddr);
2314*61046927SAndroid Build Coastguard Worker 
2315*61046927SAndroid Build Coastguard Worker    if (ptr) {
2316*61046927SAndroid Build Coastguard Worker       /* If the GPU hung within the target IB, the trigger point will be
2317*61046927SAndroid Build Coastguard Worker        * just after the current CP_INDIRECT_BUFFER.  Because the IB is
2318*61046927SAndroid Build Coastguard Worker        * executed but never returns.  Account for this by checking if
2319*61046927SAndroid Build Coastguard Worker        * the IB returned:
2320*61046927SAndroid Build Coastguard Worker        */
2321*61046927SAndroid Build Coastguard Worker       highlight_gpuaddr(gpuaddr(dwords));
2322*61046927SAndroid Build Coastguard Worker 
2323*61046927SAndroid Build Coastguard Worker       ib++;
2324*61046927SAndroid Build Coastguard Worker       ibs[ib].base = ibaddr;
2325*61046927SAndroid Build Coastguard Worker       ibs[ib].size = ibsize;
2326*61046927SAndroid Build Coastguard Worker 
2327*61046927SAndroid Build Coastguard Worker       dump_commands(ptr, ibsize, level);
2328*61046927SAndroid Build Coastguard Worker       ib--;
2329*61046927SAndroid Build Coastguard Worker    } else {
2330*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "could not find: %016" PRIx64 " (%d)\n", ibaddr, ibsize);
2331*61046927SAndroid Build Coastguard Worker    }
2332*61046927SAndroid Build Coastguard Worker }
2333*61046927SAndroid Build Coastguard Worker 
2334*61046927SAndroid Build Coastguard Worker static void
cp_start_bin(uint32_t * dwords,uint32_t sizedwords,int level)2335*61046927SAndroid Build Coastguard Worker cp_start_bin(uint32_t *dwords, uint32_t sizedwords, int level)
2336*61046927SAndroid Build Coastguard Worker {
2337*61046927SAndroid Build Coastguard Worker    uint64_t ibaddr;
2338*61046927SAndroid Build Coastguard Worker    uint32_t ibsize;
2339*61046927SAndroid Build Coastguard Worker    uint32_t loopcount;
2340*61046927SAndroid Build Coastguard Worker    uint32_t *ptr = NULL;
2341*61046927SAndroid Build Coastguard Worker 
2342*61046927SAndroid Build Coastguard Worker    loopcount = dwords[0];
2343*61046927SAndroid Build Coastguard Worker    ibaddr = dwords[1];
2344*61046927SAndroid Build Coastguard Worker    ibaddr |= ((uint64_t)dwords[2]) << 32;
2345*61046927SAndroid Build Coastguard Worker    ibsize = dwords[3];
2346*61046927SAndroid Build Coastguard Worker 
2347*61046927SAndroid Build Coastguard Worker    /* map gpuaddr back to hostptr: */
2348*61046927SAndroid Build Coastguard Worker    ptr = hostptr(ibaddr);
2349*61046927SAndroid Build Coastguard Worker 
2350*61046927SAndroid Build Coastguard Worker    if (ptr) {
2351*61046927SAndroid Build Coastguard Worker       /* If the GPU hung within the target IB, the trigger point will be
2352*61046927SAndroid Build Coastguard Worker        * just after the current CP_START_BIN.  Because the IB is
2353*61046927SAndroid Build Coastguard Worker        * executed but never returns.  Account for this by checking if
2354*61046927SAndroid Build Coastguard Worker        * the IB returned:
2355*61046927SAndroid Build Coastguard Worker        */
2356*61046927SAndroid Build Coastguard Worker       highlight_gpuaddr(gpuaddr(&dwords[5]));
2357*61046927SAndroid Build Coastguard Worker 
2358*61046927SAndroid Build Coastguard Worker       /* TODO: we should duplicate the body of the loop after each bin, so
2359*61046927SAndroid Build Coastguard Worker        * that draws get the correct state. We should also figure out if there
2360*61046927SAndroid Build Coastguard Worker        * are any registers that can tell us what bin we're in when we hang so
2361*61046927SAndroid Build Coastguard Worker        * that crashdec points to the right place.
2362*61046927SAndroid Build Coastguard Worker        */
2363*61046927SAndroid Build Coastguard Worker       ib++;
2364*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < loopcount; i++) {
2365*61046927SAndroid Build Coastguard Worker          ibs[ib].base = ibaddr;
2366*61046927SAndroid Build Coastguard Worker          ibs[ib].size = ibsize;
2367*61046927SAndroid Build Coastguard Worker          printl(3, "%sbin %u\n", levels[level], i);
2368*61046927SAndroid Build Coastguard Worker          dump_commands(ptr, ibsize, level);
2369*61046927SAndroid Build Coastguard Worker          ibaddr += ibsize;
2370*61046927SAndroid Build Coastguard Worker          ptr += ibsize;
2371*61046927SAndroid Build Coastguard Worker       }
2372*61046927SAndroid Build Coastguard Worker       ib--;
2373*61046927SAndroid Build Coastguard Worker    } else {
2374*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "could not find: %016" PRIx64 " (%d)\n", ibaddr, ibsize);
2375*61046927SAndroid Build Coastguard Worker    }
2376*61046927SAndroid Build Coastguard Worker }
2377*61046927SAndroid Build Coastguard Worker 
2378*61046927SAndroid Build Coastguard Worker static void
cp_fixed_stride_draw_table(uint32_t * dwords,uint32_t sizedwords,int level)2379*61046927SAndroid Build Coastguard Worker cp_fixed_stride_draw_table(uint32_t *dwords, uint32_t sizedwords, int level)
2380*61046927SAndroid Build Coastguard Worker {
2381*61046927SAndroid Build Coastguard Worker    uint64_t ibaddr;
2382*61046927SAndroid Build Coastguard Worker    uint32_t ibsize;
2383*61046927SAndroid Build Coastguard Worker    uint32_t loopcount;
2384*61046927SAndroid Build Coastguard Worker    uint32_t *ptr = NULL;
2385*61046927SAndroid Build Coastguard Worker 
2386*61046927SAndroid Build Coastguard Worker    loopcount = dwords[3];
2387*61046927SAndroid Build Coastguard Worker    ibaddr = dwords[0];
2388*61046927SAndroid Build Coastguard Worker    ibaddr |= ((uint64_t)dwords[1]) << 32;
2389*61046927SAndroid Build Coastguard Worker    ibsize = dwords[2] >> 20;
2390*61046927SAndroid Build Coastguard Worker 
2391*61046927SAndroid Build Coastguard Worker    /* map gpuaddr back to hostptr: */
2392*61046927SAndroid Build Coastguard Worker    ptr = hostptr(ibaddr);
2393*61046927SAndroid Build Coastguard Worker 
2394*61046927SAndroid Build Coastguard Worker    if (ptr) {
2395*61046927SAndroid Build Coastguard Worker       /* If the GPU hung within the target IB, the trigger point will be
2396*61046927SAndroid Build Coastguard Worker        * just after the current CP_START_BIN.  Because the IB is
2397*61046927SAndroid Build Coastguard Worker        * executed but never returns.  Account for this by checking if
2398*61046927SAndroid Build Coastguard Worker        * the IB returned:
2399*61046927SAndroid Build Coastguard Worker        */
2400*61046927SAndroid Build Coastguard Worker       highlight_gpuaddr(gpuaddr(&dwords[5]));
2401*61046927SAndroid Build Coastguard Worker 
2402*61046927SAndroid Build Coastguard Worker       ib++;
2403*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < loopcount; i++) {
2404*61046927SAndroid Build Coastguard Worker          ibs[ib].base = ibaddr;
2405*61046927SAndroid Build Coastguard Worker          ibs[ib].size = ibsize;
2406*61046927SAndroid Build Coastguard Worker          printl(3, "%sdraw %u\n", levels[level], i);
2407*61046927SAndroid Build Coastguard Worker          dump_commands(ptr, ibsize, level);
2408*61046927SAndroid Build Coastguard Worker          ibaddr += ibsize;
2409*61046927SAndroid Build Coastguard Worker          ptr += ibsize;
2410*61046927SAndroid Build Coastguard Worker       }
2411*61046927SAndroid Build Coastguard Worker       ib--;
2412*61046927SAndroid Build Coastguard Worker    } else {
2413*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "could not find: %016" PRIx64 " (%d)\n", ibaddr, ibsize);
2414*61046927SAndroid Build Coastguard Worker    }
2415*61046927SAndroid Build Coastguard Worker }
2416*61046927SAndroid Build Coastguard Worker 
2417*61046927SAndroid Build Coastguard Worker static void
cp_wfi(uint32_t * dwords,uint32_t sizedwords,int level)2418*61046927SAndroid Build Coastguard Worker cp_wfi(uint32_t *dwords, uint32_t sizedwords, int level)
2419*61046927SAndroid Build Coastguard Worker {
2420*61046927SAndroid Build Coastguard Worker    needs_wfi = false;
2421*61046927SAndroid Build Coastguard Worker }
2422*61046927SAndroid Build Coastguard Worker 
2423*61046927SAndroid Build Coastguard Worker static void
cp_mem_write(uint32_t * dwords,uint32_t sizedwords,int level)2424*61046927SAndroid Build Coastguard Worker cp_mem_write(uint32_t *dwords, uint32_t sizedwords, int level)
2425*61046927SAndroid Build Coastguard Worker {
2426*61046927SAndroid Build Coastguard Worker    if (quiet(2))
2427*61046927SAndroid Build Coastguard Worker       return;
2428*61046927SAndroid Build Coastguard Worker 
2429*61046927SAndroid Build Coastguard Worker    if (is_64b()) {
2430*61046927SAndroid Build Coastguard Worker       uint64_t gpuaddr = dwords[0] | (((uint64_t)dwords[1]) << 32);
2431*61046927SAndroid Build Coastguard Worker       printf("%sgpuaddr:%016" PRIx64 "\n", levels[level], gpuaddr);
2432*61046927SAndroid Build Coastguard Worker       dump_hex(&dwords[2], sizedwords - 2, level + 1);
2433*61046927SAndroid Build Coastguard Worker 
2434*61046927SAndroid Build Coastguard Worker       if (pkt_is_type4(dwords[2]) || pkt_is_type7(dwords[2]))
2435*61046927SAndroid Build Coastguard Worker          dump_commands(&dwords[2], sizedwords - 2, level + 1);
2436*61046927SAndroid Build Coastguard Worker    } else {
2437*61046927SAndroid Build Coastguard Worker       uint32_t gpuaddr = dwords[0];
2438*61046927SAndroid Build Coastguard Worker       printf("%sgpuaddr:%08x\n", levels[level], gpuaddr);
2439*61046927SAndroid Build Coastguard Worker       dump_float((float *)&dwords[1], sizedwords - 1, level + 1);
2440*61046927SAndroid Build Coastguard Worker    }
2441*61046927SAndroid Build Coastguard Worker }
2442*61046927SAndroid Build Coastguard Worker 
2443*61046927SAndroid Build Coastguard Worker static void
cp_rmw(uint32_t * dwords,uint32_t sizedwords,int level)2444*61046927SAndroid Build Coastguard Worker cp_rmw(uint32_t *dwords, uint32_t sizedwords, int level)
2445*61046927SAndroid Build Coastguard Worker {
2446*61046927SAndroid Build Coastguard Worker    uint32_t val = dwords[0] & 0xffff;
2447*61046927SAndroid Build Coastguard Worker    uint32_t and = dwords[1];
2448*61046927SAndroid Build Coastguard Worker    uint32_t or = dwords[2];
2449*61046927SAndroid Build Coastguard Worker    printl(3, "%srmw (%s & 0x%08x) | 0x%08x)\n", levels[level], regname(val, 1),
2450*61046927SAndroid Build Coastguard Worker           and, or);
2451*61046927SAndroid Build Coastguard Worker    if (needs_wfi)
2452*61046927SAndroid Build Coastguard Worker       printl(2, "NEEDS WFI: rmw (%s & 0x%08x) | 0x%08x)\n", regname(val, 1),
2453*61046927SAndroid Build Coastguard Worker              and, or);
2454*61046927SAndroid Build Coastguard Worker    reg_set(val, (reg_val(val) & and) | or);
2455*61046927SAndroid Build Coastguard Worker }
2456*61046927SAndroid Build Coastguard Worker 
2457*61046927SAndroid Build Coastguard Worker static void
cp_reg_mem(uint32_t * dwords,uint32_t sizedwords,int level)2458*61046927SAndroid Build Coastguard Worker cp_reg_mem(uint32_t *dwords, uint32_t sizedwords, int level)
2459*61046927SAndroid Build Coastguard Worker {
2460*61046927SAndroid Build Coastguard Worker    uint32_t val = dwords[0] & 0xffff;
2461*61046927SAndroid Build Coastguard Worker    printl(3, "%sbase register: %s\n", levels[level], regname(val, 1));
2462*61046927SAndroid Build Coastguard Worker 
2463*61046927SAndroid Build Coastguard Worker    if (quiet(2))
2464*61046927SAndroid Build Coastguard Worker       return;
2465*61046927SAndroid Build Coastguard Worker 
2466*61046927SAndroid Build Coastguard Worker    uint64_t gpuaddr = dwords[1] | (((uint64_t)dwords[2]) << 32);
2467*61046927SAndroid Build Coastguard Worker    printf("%sgpuaddr:%016" PRIx64 "\n", levels[level], gpuaddr);
2468*61046927SAndroid Build Coastguard Worker    void *ptr = hostptr(gpuaddr);
2469*61046927SAndroid Build Coastguard Worker    if (ptr) {
2470*61046927SAndroid Build Coastguard Worker       uint32_t cnt = (dwords[0] >> 19) & 0x3ff;
2471*61046927SAndroid Build Coastguard Worker       dump_hex(ptr, cnt, level + 1);
2472*61046927SAndroid Build Coastguard Worker    }
2473*61046927SAndroid Build Coastguard Worker }
2474*61046927SAndroid Build Coastguard Worker 
2475*61046927SAndroid Build Coastguard Worker struct draw_state {
2476*61046927SAndroid Build Coastguard Worker    uint16_t enable_mask;
2477*61046927SAndroid Build Coastguard Worker    uint16_t flags;
2478*61046927SAndroid Build Coastguard Worker    uint32_t count;
2479*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2480*61046927SAndroid Build Coastguard Worker };
2481*61046927SAndroid Build Coastguard Worker 
2482*61046927SAndroid Build Coastguard Worker struct draw_state state[32];
2483*61046927SAndroid Build Coastguard Worker 
2484*61046927SAndroid Build Coastguard Worker #define FLAG_DIRTY              0x1
2485*61046927SAndroid Build Coastguard Worker #define FLAG_DISABLE            0x2
2486*61046927SAndroid Build Coastguard Worker #define FLAG_DISABLE_ALL_GROUPS 0x4
2487*61046927SAndroid Build Coastguard Worker #define FLAG_LOAD_IMMED         0x8
2488*61046927SAndroid Build Coastguard Worker 
2489*61046927SAndroid Build Coastguard Worker static int draw_mode;
2490*61046927SAndroid Build Coastguard Worker 
2491*61046927SAndroid Build Coastguard Worker static void
disable_group(unsigned group_id)2492*61046927SAndroid Build Coastguard Worker disable_group(unsigned group_id)
2493*61046927SAndroid Build Coastguard Worker {
2494*61046927SAndroid Build Coastguard Worker    struct draw_state *ds = &state[group_id];
2495*61046927SAndroid Build Coastguard Worker    memset(ds, 0, sizeof(*ds));
2496*61046927SAndroid Build Coastguard Worker }
2497*61046927SAndroid Build Coastguard Worker 
2498*61046927SAndroid Build Coastguard Worker static void
disable_all_groups(void)2499*61046927SAndroid Build Coastguard Worker disable_all_groups(void)
2500*61046927SAndroid Build Coastguard Worker {
2501*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(state); i++)
2502*61046927SAndroid Build Coastguard Worker       disable_group(i);
2503*61046927SAndroid Build Coastguard Worker }
2504*61046927SAndroid Build Coastguard Worker 
2505*61046927SAndroid Build Coastguard Worker static void
load_group(unsigned group_id,int level)2506*61046927SAndroid Build Coastguard Worker load_group(unsigned group_id, int level)
2507*61046927SAndroid Build Coastguard Worker {
2508*61046927SAndroid Build Coastguard Worker    struct draw_state *ds = &state[group_id];
2509*61046927SAndroid Build Coastguard Worker 
2510*61046927SAndroid Build Coastguard Worker    if (!ds->count)
2511*61046927SAndroid Build Coastguard Worker       return;
2512*61046927SAndroid Build Coastguard Worker 
2513*61046927SAndroid Build Coastguard Worker    printl(2, "%sgroup_id: %u\n", levels[level], group_id);
2514*61046927SAndroid Build Coastguard Worker    printl(2, "%scount: %d\n", levels[level], ds->count);
2515*61046927SAndroid Build Coastguard Worker    printl(2, "%saddr: %016llx\n", levels[level], ds->addr);
2516*61046927SAndroid Build Coastguard Worker    printl(2, "%sflags: %x\n", levels[level], ds->flags);
2517*61046927SAndroid Build Coastguard Worker 
2518*61046927SAndroid Build Coastguard Worker    if (options->info->chip >= 6) {
2519*61046927SAndroid Build Coastguard Worker       printl(2, "%senable_mask: 0x%x\n", levels[level], ds->enable_mask);
2520*61046927SAndroid Build Coastguard Worker 
2521*61046927SAndroid Build Coastguard Worker       if (!(ds->enable_mask & enable_mask)) {
2522*61046927SAndroid Build Coastguard Worker          printl(2, "%s\tskipped!\n\n", levels[level]);
2523*61046927SAndroid Build Coastguard Worker          return;
2524*61046927SAndroid Build Coastguard Worker       }
2525*61046927SAndroid Build Coastguard Worker    }
2526*61046927SAndroid Build Coastguard Worker 
2527*61046927SAndroid Build Coastguard Worker    void *ptr = hostptr(ds->addr);
2528*61046927SAndroid Build Coastguard Worker    if (ptr) {
2529*61046927SAndroid Build Coastguard Worker       if (!quiet(2))
2530*61046927SAndroid Build Coastguard Worker          dump_hex(ptr, ds->count, level + 1);
2531*61046927SAndroid Build Coastguard Worker 
2532*61046927SAndroid Build Coastguard Worker       ib++;
2533*61046927SAndroid Build Coastguard Worker       dump_commands(ptr, ds->count, level + 1);
2534*61046927SAndroid Build Coastguard Worker       ib--;
2535*61046927SAndroid Build Coastguard Worker    }
2536*61046927SAndroid Build Coastguard Worker }
2537*61046927SAndroid Build Coastguard Worker 
2538*61046927SAndroid Build Coastguard Worker static void
load_all_groups(int level)2539*61046927SAndroid Build Coastguard Worker load_all_groups(int level)
2540*61046927SAndroid Build Coastguard Worker {
2541*61046927SAndroid Build Coastguard Worker    /* sanity check, we should never recursively hit recursion here, and if
2542*61046927SAndroid Build Coastguard Worker     * we do bad things happen:
2543*61046927SAndroid Build Coastguard Worker     */
2544*61046927SAndroid Build Coastguard Worker    static bool loading_groups = false;
2545*61046927SAndroid Build Coastguard Worker    if (loading_groups) {
2546*61046927SAndroid Build Coastguard Worker       printf("ERROR: nothing in draw state should trigger recursively loading "
2547*61046927SAndroid Build Coastguard Worker              "groups!\n");
2548*61046927SAndroid Build Coastguard Worker       return;
2549*61046927SAndroid Build Coastguard Worker    }
2550*61046927SAndroid Build Coastguard Worker    loading_groups = true;
2551*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(state); i++)
2552*61046927SAndroid Build Coastguard Worker       load_group(i, level);
2553*61046927SAndroid Build Coastguard Worker    loading_groups = false;
2554*61046927SAndroid Build Coastguard Worker 
2555*61046927SAndroid Build Coastguard Worker    /* in 'query-compare' mode, defer disabling all groups until we have a
2556*61046927SAndroid Build Coastguard Worker     * chance to process the query:
2557*61046927SAndroid Build Coastguard Worker     */
2558*61046927SAndroid Build Coastguard Worker    if (!options->query_compare)
2559*61046927SAndroid Build Coastguard Worker       disable_all_groups();
2560*61046927SAndroid Build Coastguard Worker }
2561*61046927SAndroid Build Coastguard Worker 
2562*61046927SAndroid Build Coastguard Worker static void
cp_set_draw_state(uint32_t * dwords,uint32_t sizedwords,int level)2563*61046927SAndroid Build Coastguard Worker cp_set_draw_state(uint32_t *dwords, uint32_t sizedwords, int level)
2564*61046927SAndroid Build Coastguard Worker {
2565*61046927SAndroid Build Coastguard Worker    uint32_t i;
2566*61046927SAndroid Build Coastguard Worker 
2567*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords;) {
2568*61046927SAndroid Build Coastguard Worker       struct draw_state *ds;
2569*61046927SAndroid Build Coastguard Worker       uint32_t count = dwords[i] & 0xffff;
2570*61046927SAndroid Build Coastguard Worker       uint32_t group_id = (dwords[i] >> 24) & 0x1f;
2571*61046927SAndroid Build Coastguard Worker       uint32_t enable_mask = (dwords[i] >> 20) & 0xf;
2572*61046927SAndroid Build Coastguard Worker       uint32_t flags = (dwords[i] >> 16) & 0xf;
2573*61046927SAndroid Build Coastguard Worker       uint64_t addr;
2574*61046927SAndroid Build Coastguard Worker 
2575*61046927SAndroid Build Coastguard Worker       if (is_64b()) {
2576*61046927SAndroid Build Coastguard Worker          addr = dwords[i + 1];
2577*61046927SAndroid Build Coastguard Worker          addr |= ((uint64_t)dwords[i + 2]) << 32;
2578*61046927SAndroid Build Coastguard Worker          i += 3;
2579*61046927SAndroid Build Coastguard Worker       } else {
2580*61046927SAndroid Build Coastguard Worker          addr = dwords[i + 1];
2581*61046927SAndroid Build Coastguard Worker          i += 2;
2582*61046927SAndroid Build Coastguard Worker       }
2583*61046927SAndroid Build Coastguard Worker 
2584*61046927SAndroid Build Coastguard Worker       if (flags & FLAG_DISABLE_ALL_GROUPS) {
2585*61046927SAndroid Build Coastguard Worker          disable_all_groups();
2586*61046927SAndroid Build Coastguard Worker          continue;
2587*61046927SAndroid Build Coastguard Worker       }
2588*61046927SAndroid Build Coastguard Worker 
2589*61046927SAndroid Build Coastguard Worker       if (flags & FLAG_DISABLE) {
2590*61046927SAndroid Build Coastguard Worker          disable_group(group_id);
2591*61046927SAndroid Build Coastguard Worker          continue;
2592*61046927SAndroid Build Coastguard Worker       }
2593*61046927SAndroid Build Coastguard Worker 
2594*61046927SAndroid Build Coastguard Worker       assert(group_id < ARRAY_SIZE(state));
2595*61046927SAndroid Build Coastguard Worker       disable_group(group_id);
2596*61046927SAndroid Build Coastguard Worker 
2597*61046927SAndroid Build Coastguard Worker       ds = &state[group_id];
2598*61046927SAndroid Build Coastguard Worker 
2599*61046927SAndroid Build Coastguard Worker       ds->enable_mask = enable_mask;
2600*61046927SAndroid Build Coastguard Worker       ds->flags = flags;
2601*61046927SAndroid Build Coastguard Worker       ds->count = count;
2602*61046927SAndroid Build Coastguard Worker       ds->addr = addr;
2603*61046927SAndroid Build Coastguard Worker 
2604*61046927SAndroid Build Coastguard Worker       if (flags & FLAG_LOAD_IMMED) {
2605*61046927SAndroid Build Coastguard Worker          load_group(group_id, level);
2606*61046927SAndroid Build Coastguard Worker          disable_group(group_id);
2607*61046927SAndroid Build Coastguard Worker       }
2608*61046927SAndroid Build Coastguard Worker    }
2609*61046927SAndroid Build Coastguard Worker }
2610*61046927SAndroid Build Coastguard Worker 
2611*61046927SAndroid Build Coastguard Worker static void
cp_set_mode(uint32_t * dwords,uint32_t sizedwords,int level)2612*61046927SAndroid Build Coastguard Worker cp_set_mode(uint32_t *dwords, uint32_t sizedwords, int level)
2613*61046927SAndroid Build Coastguard Worker {
2614*61046927SAndroid Build Coastguard Worker    draw_mode = dwords[0];
2615*61046927SAndroid Build Coastguard Worker }
2616*61046927SAndroid Build Coastguard Worker 
2617*61046927SAndroid Build Coastguard Worker /* execute compute shader */
2618*61046927SAndroid Build Coastguard Worker static void
cp_exec_cs(uint32_t * dwords,uint32_t sizedwords,int level)2619*61046927SAndroid Build Coastguard Worker cp_exec_cs(uint32_t *dwords, uint32_t sizedwords, int level)
2620*61046927SAndroid Build Coastguard Worker {
2621*61046927SAndroid Build Coastguard Worker    do_query("compute", 0);
2622*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2623*61046927SAndroid Build Coastguard Worker }
2624*61046927SAndroid Build Coastguard Worker 
2625*61046927SAndroid Build Coastguard Worker static void
cp_exec_cs_indirect(uint32_t * dwords,uint32_t sizedwords,int level)2626*61046927SAndroid Build Coastguard Worker cp_exec_cs_indirect(uint32_t *dwords, uint32_t sizedwords, int level)
2627*61046927SAndroid Build Coastguard Worker {
2628*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2629*61046927SAndroid Build Coastguard Worker 
2630*61046927SAndroid Build Coastguard Worker    if (is_64b()) {
2631*61046927SAndroid Build Coastguard Worker       addr = (((uint64_t)dwords[2] & 0x1ffff) << 32) | dwords[1];
2632*61046927SAndroid Build Coastguard Worker    } else {
2633*61046927SAndroid Build Coastguard Worker       addr = dwords[1];
2634*61046927SAndroid Build Coastguard Worker    }
2635*61046927SAndroid Build Coastguard Worker 
2636*61046927SAndroid Build Coastguard Worker    printl(3, "%saddr: %016llx\n", levels[level], addr);
2637*61046927SAndroid Build Coastguard Worker    dump_gpuaddr_size(addr, level, 0x10, 2);
2638*61046927SAndroid Build Coastguard Worker 
2639*61046927SAndroid Build Coastguard Worker    do_query("compute", 0);
2640*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2641*61046927SAndroid Build Coastguard Worker }
2642*61046927SAndroid Build Coastguard Worker 
2643*61046927SAndroid Build Coastguard Worker static void
cp_set_marker(uint32_t * dwords,uint32_t sizedwords,int level)2644*61046927SAndroid Build Coastguard Worker cp_set_marker(uint32_t *dwords, uint32_t sizedwords, int level)
2645*61046927SAndroid Build Coastguard Worker {
2646*61046927SAndroid Build Coastguard Worker    uint32_t val = dwords[0] & 0xf;
2647*61046927SAndroid Build Coastguard Worker    const char *mode = rnn_enumname(rnn, "a6xx_marker", val);
2648*61046927SAndroid Build Coastguard Worker 
2649*61046927SAndroid Build Coastguard Worker    if (!mode) {
2650*61046927SAndroid Build Coastguard Worker       static char buf[8];
2651*61046927SAndroid Build Coastguard Worker       sprintf(buf, "0x%x", val);
2652*61046927SAndroid Build Coastguard Worker       render_mode = buf;
2653*61046927SAndroid Build Coastguard Worker       return;
2654*61046927SAndroid Build Coastguard Worker    }
2655*61046927SAndroid Build Coastguard Worker 
2656*61046927SAndroid Build Coastguard Worker    render_mode = mode;
2657*61046927SAndroid Build Coastguard Worker 
2658*61046927SAndroid Build Coastguard Worker    if (!strcmp(render_mode, "RM6_BINNING")) {
2659*61046927SAndroid Build Coastguard Worker       enable_mask = MODE_BINNING;
2660*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(render_mode, "RM6_GMEM")) {
2661*61046927SAndroid Build Coastguard Worker       enable_mask = MODE_GMEM;
2662*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(render_mode, "RM6_BYPASS")) {
2663*61046927SAndroid Build Coastguard Worker       enable_mask = MODE_BYPASS;
2664*61046927SAndroid Build Coastguard Worker    }
2665*61046927SAndroid Build Coastguard Worker }
2666*61046927SAndroid Build Coastguard Worker 
2667*61046927SAndroid Build Coastguard Worker static void
cp_set_thread_control(uint32_t * dwords,uint32_t sizedwords,int level)2668*61046927SAndroid Build Coastguard Worker cp_set_thread_control(uint32_t *dwords, uint32_t sizedwords, int level)
2669*61046927SAndroid Build Coastguard Worker {
2670*61046927SAndroid Build Coastguard Worker    uint32_t val = dwords[0] & 0x3;
2671*61046927SAndroid Build Coastguard Worker    thread = rnn_enumname(rnn, "cp_thread", val);
2672*61046927SAndroid Build Coastguard Worker }
2673*61046927SAndroid Build Coastguard Worker 
2674*61046927SAndroid Build Coastguard Worker static void
cp_set_render_mode(uint32_t * dwords,uint32_t sizedwords,int level)2675*61046927SAndroid Build Coastguard Worker cp_set_render_mode(uint32_t *dwords, uint32_t sizedwords, int level)
2676*61046927SAndroid Build Coastguard Worker {
2677*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2678*61046927SAndroid Build Coastguard Worker    uint32_t *ptr, len;
2679*61046927SAndroid Build Coastguard Worker 
2680*61046927SAndroid Build Coastguard Worker    assert(is_64b());
2681*61046927SAndroid Build Coastguard Worker 
2682*61046927SAndroid Build Coastguard Worker    /* TODO seems to have two ptrs, 9 dwords total (incl pkt7 hdr)..
2683*61046927SAndroid Build Coastguard Worker     * not sure if this can come in different sizes.
2684*61046927SAndroid Build Coastguard Worker     *
2685*61046927SAndroid Build Coastguard Worker     * First ptr doesn't seem to be cmdstream, second one does.
2686*61046927SAndroid Build Coastguard Worker     *
2687*61046927SAndroid Build Coastguard Worker     * Comment from downstream kernel:
2688*61046927SAndroid Build Coastguard Worker     *
2689*61046927SAndroid Build Coastguard Worker     * SRM -- set render mode (ex binning, direct render etc)
2690*61046927SAndroid Build Coastguard Worker     * SRM is set by UMD usually at start of IB to tell CP the type of
2691*61046927SAndroid Build Coastguard Worker     * preemption.
2692*61046927SAndroid Build Coastguard Worker     * KMD needs to set SRM to NULL to indicate CP that rendering is
2693*61046927SAndroid Build Coastguard Worker     * done by IB.
2694*61046927SAndroid Build Coastguard Worker     * ------------------------------------------------------------------
2695*61046927SAndroid Build Coastguard Worker     *
2696*61046927SAndroid Build Coastguard Worker     * Seems to always be one of these two:
2697*61046927SAndroid Build Coastguard Worker     * 70ec0008 00000001 001c0000 00000000 00000010 00000003 0000000d 001c2000
2698*61046927SAndroid Build Coastguard Worker     * 00000000 70ec0008 00000001 001c0000 00000000 00000000 00000003 0000000d
2699*61046927SAndroid Build Coastguard Worker     * 001c2000 00000000
2700*61046927SAndroid Build Coastguard Worker     *
2701*61046927SAndroid Build Coastguard Worker     */
2702*61046927SAndroid Build Coastguard Worker 
2703*61046927SAndroid Build Coastguard Worker    assert(options->info->chip >= 5);
2704*61046927SAndroid Build Coastguard Worker 
2705*61046927SAndroid Build Coastguard Worker    render_mode = rnn_enumname(rnn, "render_mode_cmd", dwords[0]);
2706*61046927SAndroid Build Coastguard Worker 
2707*61046927SAndroid Build Coastguard Worker    if (sizedwords == 1)
2708*61046927SAndroid Build Coastguard Worker       return;
2709*61046927SAndroid Build Coastguard Worker 
2710*61046927SAndroid Build Coastguard Worker    addr = dwords[1];
2711*61046927SAndroid Build Coastguard Worker    addr |= ((uint64_t)dwords[2]) << 32;
2712*61046927SAndroid Build Coastguard Worker 
2713*61046927SAndroid Build Coastguard Worker    mode = dwords[3];
2714*61046927SAndroid Build Coastguard Worker 
2715*61046927SAndroid Build Coastguard Worker    dump_gpuaddr(addr, level + 1);
2716*61046927SAndroid Build Coastguard Worker 
2717*61046927SAndroid Build Coastguard Worker    if (sizedwords == 5)
2718*61046927SAndroid Build Coastguard Worker       return;
2719*61046927SAndroid Build Coastguard Worker 
2720*61046927SAndroid Build Coastguard Worker    assert(sizedwords == 8);
2721*61046927SAndroid Build Coastguard Worker 
2722*61046927SAndroid Build Coastguard Worker    len = dwords[5];
2723*61046927SAndroid Build Coastguard Worker    addr = dwords[6];
2724*61046927SAndroid Build Coastguard Worker    addr |= ((uint64_t)dwords[7]) << 32;
2725*61046927SAndroid Build Coastguard Worker 
2726*61046927SAndroid Build Coastguard Worker    printl(3, "%saddr: 0x%016lx\n", levels[level], addr);
2727*61046927SAndroid Build Coastguard Worker    printl(3, "%slen:  0x%x\n", levels[level], len);
2728*61046927SAndroid Build Coastguard Worker 
2729*61046927SAndroid Build Coastguard Worker    ptr = hostptr(addr);
2730*61046927SAndroid Build Coastguard Worker 
2731*61046927SAndroid Build Coastguard Worker    if (ptr) {
2732*61046927SAndroid Build Coastguard Worker       if (!quiet(2)) {
2733*61046927SAndroid Build Coastguard Worker          ib++;
2734*61046927SAndroid Build Coastguard Worker          dump_commands(ptr, len, level + 1);
2735*61046927SAndroid Build Coastguard Worker          ib--;
2736*61046927SAndroid Build Coastguard Worker          dump_hex(ptr, len, level + 1);
2737*61046927SAndroid Build Coastguard Worker       }
2738*61046927SAndroid Build Coastguard Worker    }
2739*61046927SAndroid Build Coastguard Worker }
2740*61046927SAndroid Build Coastguard Worker 
2741*61046927SAndroid Build Coastguard Worker static void
cp_compute_checkpoint(uint32_t * dwords,uint32_t sizedwords,int level)2742*61046927SAndroid Build Coastguard Worker cp_compute_checkpoint(uint32_t *dwords, uint32_t sizedwords, int level)
2743*61046927SAndroid Build Coastguard Worker {
2744*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2745*61046927SAndroid Build Coastguard Worker    uint32_t *ptr, len;
2746*61046927SAndroid Build Coastguard Worker 
2747*61046927SAndroid Build Coastguard Worker    assert(is_64b());
2748*61046927SAndroid Build Coastguard Worker    assert(options->info->chip >= 5);
2749*61046927SAndroid Build Coastguard Worker 
2750*61046927SAndroid Build Coastguard Worker    if (sizedwords == 8) {
2751*61046927SAndroid Build Coastguard Worker       addr = dwords[5];
2752*61046927SAndroid Build Coastguard Worker       addr |= ((uint64_t)dwords[6]) << 32;
2753*61046927SAndroid Build Coastguard Worker       len = dwords[7];
2754*61046927SAndroid Build Coastguard Worker    } else {
2755*61046927SAndroid Build Coastguard Worker       addr = dwords[5];
2756*61046927SAndroid Build Coastguard Worker       addr |= ((uint64_t)dwords[6]) << 32;
2757*61046927SAndroid Build Coastguard Worker       len = dwords[4];
2758*61046927SAndroid Build Coastguard Worker    }
2759*61046927SAndroid Build Coastguard Worker 
2760*61046927SAndroid Build Coastguard Worker    printl(3, "%saddr: 0x%016" PRIx64 "\n", levels[level], addr);
2761*61046927SAndroid Build Coastguard Worker    printl(3, "%slen:  0x%x\n", levels[level], len);
2762*61046927SAndroid Build Coastguard Worker 
2763*61046927SAndroid Build Coastguard Worker    ptr = hostptr(addr);
2764*61046927SAndroid Build Coastguard Worker 
2765*61046927SAndroid Build Coastguard Worker    if (ptr) {
2766*61046927SAndroid Build Coastguard Worker       if (!quiet(2)) {
2767*61046927SAndroid Build Coastguard Worker          ib++;
2768*61046927SAndroid Build Coastguard Worker          dump_commands(ptr, len, level + 1);
2769*61046927SAndroid Build Coastguard Worker          ib--;
2770*61046927SAndroid Build Coastguard Worker          dump_hex(ptr, len, level + 1);
2771*61046927SAndroid Build Coastguard Worker       }
2772*61046927SAndroid Build Coastguard Worker    }
2773*61046927SAndroid Build Coastguard Worker }
2774*61046927SAndroid Build Coastguard Worker 
2775*61046927SAndroid Build Coastguard Worker static void
cp_blit(uint32_t * dwords,uint32_t sizedwords,int level)2776*61046927SAndroid Build Coastguard Worker cp_blit(uint32_t *dwords, uint32_t sizedwords, int level)
2777*61046927SAndroid Build Coastguard Worker {
2778*61046927SAndroid Build Coastguard Worker    do_query(rnn_enumname(rnn, "cp_blit_cmd", dwords[0]), 0);
2779*61046927SAndroid Build Coastguard Worker    print_mode(level);
2780*61046927SAndroid Build Coastguard Worker    dump_register_summary(level);
2781*61046927SAndroid Build Coastguard Worker }
2782*61046927SAndroid Build Coastguard Worker 
2783*61046927SAndroid Build Coastguard Worker static void
cp_context_reg_bunch(uint32_t * dwords,uint32_t sizedwords,int level)2784*61046927SAndroid Build Coastguard Worker cp_context_reg_bunch(uint32_t *dwords, uint32_t sizedwords, int level)
2785*61046927SAndroid Build Coastguard Worker {
2786*61046927SAndroid Build Coastguard Worker    int i;
2787*61046927SAndroid Build Coastguard Worker 
2788*61046927SAndroid Build Coastguard Worker    /* NOTE: seems to write same reg multiple times.. not sure if different parts
2789*61046927SAndroid Build Coastguard Worker     * of these are triggered by the FLUSH_SO_n events?? (if that is what they
2790*61046927SAndroid Build Coastguard Worker     * actually are?)
2791*61046927SAndroid Build Coastguard Worker     */
2792*61046927SAndroid Build Coastguard Worker    bool saved_summary = summary;
2793*61046927SAndroid Build Coastguard Worker    summary = false;
2794*61046927SAndroid Build Coastguard Worker 
2795*61046927SAndroid Build Coastguard Worker    struct regacc r = regacc(NULL);
2796*61046927SAndroid Build Coastguard Worker 
2797*61046927SAndroid Build Coastguard Worker    for (i = 0; i < sizedwords; i += 2) {
2798*61046927SAndroid Build Coastguard Worker       if (regacc_push(&r, dwords[i + 0], dwords[i + 1]))
2799*61046927SAndroid Build Coastguard Worker          dump_register(&r, level + 1);
2800*61046927SAndroid Build Coastguard Worker       reg_set(dwords[i + 0], dwords[i + 1]);
2801*61046927SAndroid Build Coastguard Worker    }
2802*61046927SAndroid Build Coastguard Worker 
2803*61046927SAndroid Build Coastguard Worker    summary = saved_summary;
2804*61046927SAndroid Build Coastguard Worker }
2805*61046927SAndroid Build Coastguard Worker 
2806*61046927SAndroid Build Coastguard Worker /* Looks similar to CP_CONTEXT_REG_BUNCH, but not quite the same...
2807*61046927SAndroid Build Coastguard Worker  * discarding first two dwords??
2808*61046927SAndroid Build Coastguard Worker  *
2809*61046927SAndroid Build Coastguard Worker  *   CP_CONTEXT_REG_BUNCH:
2810*61046927SAndroid Build Coastguard Worker  *        0221: 9c1ff606  (rep)(xmov3)mov $usraddr, $data
2811*61046927SAndroid Build Coastguard Worker  *        ; mov $data, $data
2812*61046927SAndroid Build Coastguard Worker  *        ; mov $usraddr, $data
2813*61046927SAndroid Build Coastguard Worker  *        ; mov $data, $data
2814*61046927SAndroid Build Coastguard Worker  *        0222: d8000000  waitin
2815*61046927SAndroid Build Coastguard Worker  *        0223: 981f0806  mov $01, $data
2816*61046927SAndroid Build Coastguard Worker  *
2817*61046927SAndroid Build Coastguard Worker  *   CP_UNK5D:
2818*61046927SAndroid Build Coastguard Worker  *        0224: 981f0006  mov $00, $data
2819*61046927SAndroid Build Coastguard Worker  *        0225: 981f0006  mov $00, $data
2820*61046927SAndroid Build Coastguard Worker  *        0226: 9c1ff206  (rep)(xmov1)mov $usraddr, $data
2821*61046927SAndroid Build Coastguard Worker  *        ; mov $data, $data
2822*61046927SAndroid Build Coastguard Worker  *        0227: d8000000  waitin
2823*61046927SAndroid Build Coastguard Worker  *        0228: 981f0806  mov $01, $data
2824*61046927SAndroid Build Coastguard Worker  *
2825*61046927SAndroid Build Coastguard Worker  */
2826*61046927SAndroid Build Coastguard Worker static void
cp_context_reg_bunch2(uint32_t * dwords,uint32_t sizedwords,int level)2827*61046927SAndroid Build Coastguard Worker cp_context_reg_bunch2(uint32_t *dwords, uint32_t sizedwords, int level)
2828*61046927SAndroid Build Coastguard Worker {
2829*61046927SAndroid Build Coastguard Worker    dwords += 2;
2830*61046927SAndroid Build Coastguard Worker    sizedwords -= 2;
2831*61046927SAndroid Build Coastguard Worker    cp_context_reg_bunch(dwords, sizedwords, level);
2832*61046927SAndroid Build Coastguard Worker }
2833*61046927SAndroid Build Coastguard Worker 
2834*61046927SAndroid Build Coastguard Worker static void
cp_reg_write(uint32_t * dwords,uint32_t sizedwords,int level)2835*61046927SAndroid Build Coastguard Worker cp_reg_write(uint32_t *dwords, uint32_t sizedwords, int level)
2836*61046927SAndroid Build Coastguard Worker {
2837*61046927SAndroid Build Coastguard Worker    uint32_t reg = dwords[1] & 0xffff;
2838*61046927SAndroid Build Coastguard Worker 
2839*61046927SAndroid Build Coastguard Worker    struct regacc r = regacc(NULL);
2840*61046927SAndroid Build Coastguard Worker    if (regacc_push(&r, reg, dwords[2]))
2841*61046927SAndroid Build Coastguard Worker       dump_register(&r, level + 1);
2842*61046927SAndroid Build Coastguard Worker    reg_set(reg, dwords[2]);
2843*61046927SAndroid Build Coastguard Worker }
2844*61046927SAndroid Build Coastguard Worker 
2845*61046927SAndroid Build Coastguard Worker static void
cp_set_ctxswitch_ib(uint32_t * dwords,uint32_t sizedwords,int level)2846*61046927SAndroid Build Coastguard Worker cp_set_ctxswitch_ib(uint32_t *dwords, uint32_t sizedwords, int level)
2847*61046927SAndroid Build Coastguard Worker {
2848*61046927SAndroid Build Coastguard Worker    uint64_t addr;
2849*61046927SAndroid Build Coastguard Worker    uint32_t size = dwords[2] & 0xffff;
2850*61046927SAndroid Build Coastguard Worker    void *ptr;
2851*61046927SAndroid Build Coastguard Worker 
2852*61046927SAndroid Build Coastguard Worker    addr = dwords[0] | ((uint64_t)dwords[1] << 32);
2853*61046927SAndroid Build Coastguard Worker 
2854*61046927SAndroid Build Coastguard Worker    if (!quiet(3)) {
2855*61046927SAndroid Build Coastguard Worker       printf("%saddr=%" PRIx64 "\n", levels[level], addr);
2856*61046927SAndroid Build Coastguard Worker    }
2857*61046927SAndroid Build Coastguard Worker 
2858*61046927SAndroid Build Coastguard Worker    ptr = hostptr(addr);
2859*61046927SAndroid Build Coastguard Worker    if (ptr) {
2860*61046927SAndroid Build Coastguard Worker       dump_commands(ptr, size, level + 1);
2861*61046927SAndroid Build Coastguard Worker    }
2862*61046927SAndroid Build Coastguard Worker }
2863*61046927SAndroid Build Coastguard Worker 
2864*61046927SAndroid Build Coastguard Worker static void
cp_skip_ib2_enable_global(uint32_t * dwords,uint32_t sizedwords,int level)2865*61046927SAndroid Build Coastguard Worker cp_skip_ib2_enable_global(uint32_t *dwords, uint32_t sizedwords, int level)
2866*61046927SAndroid Build Coastguard Worker {
2867*61046927SAndroid Build Coastguard Worker    skip_ib2_enable_global = dwords[0];
2868*61046927SAndroid Build Coastguard Worker }
2869*61046927SAndroid Build Coastguard Worker 
2870*61046927SAndroid Build Coastguard Worker static void
cp_skip_ib2_enable_local(uint32_t * dwords,uint32_t sizedwords,int level)2871*61046927SAndroid Build Coastguard Worker cp_skip_ib2_enable_local(uint32_t *dwords, uint32_t sizedwords, int level)
2872*61046927SAndroid Build Coastguard Worker {
2873*61046927SAndroid Build Coastguard Worker    skip_ib2_enable_local = dwords[0];
2874*61046927SAndroid Build Coastguard Worker }
2875*61046927SAndroid Build Coastguard Worker 
2876*61046927SAndroid Build Coastguard Worker #define CP(x, fxn, ...) { "CP_" #x, fxn, ##__VA_ARGS__ }
2877*61046927SAndroid Build Coastguard Worker static const struct type3_op {
2878*61046927SAndroid Build Coastguard Worker    const char *name;
2879*61046927SAndroid Build Coastguard Worker    void (*fxn)(uint32_t *dwords, uint32_t sizedwords, int level);
2880*61046927SAndroid Build Coastguard Worker    struct {
2881*61046927SAndroid Build Coastguard Worker       bool load_all_groups;
2882*61046927SAndroid Build Coastguard Worker    } options;
2883*61046927SAndroid Build Coastguard Worker } type3_op[] = {
2884*61046927SAndroid Build Coastguard Worker    CP(NOP, cp_nop),
2885*61046927SAndroid Build Coastguard Worker    CP(INDIRECT_BUFFER, cp_indirect),
2886*61046927SAndroid Build Coastguard Worker    CP(INDIRECT_BUFFER_PFD, cp_indirect),
2887*61046927SAndroid Build Coastguard Worker    CP(WAIT_FOR_IDLE, cp_wfi),
2888*61046927SAndroid Build Coastguard Worker    CP(REG_RMW, cp_rmw),
2889*61046927SAndroid Build Coastguard Worker    CP(REG_TO_MEM, cp_reg_mem),
2890*61046927SAndroid Build Coastguard Worker    CP(MEM_TO_REG, cp_reg_mem), /* same layout as CP_REG_TO_MEM */
2891*61046927SAndroid Build Coastguard Worker    CP(MEM_WRITE, cp_mem_write),
2892*61046927SAndroid Build Coastguard Worker    CP(EVENT_WRITE, cp_event_write),
2893*61046927SAndroid Build Coastguard Worker    CP(RUN_OPENCL, cp_run_cl),
2894*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDX, cp_draw_indx, {.load_all_groups = true}),
2895*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDX_2, cp_draw_indx_2, {.load_all_groups = true}),
2896*61046927SAndroid Build Coastguard Worker    CP(SET_CONSTANT, cp_set_const),
2897*61046927SAndroid Build Coastguard Worker    CP(IM_LOAD_IMMEDIATE, cp_im_loadi),
2898*61046927SAndroid Build Coastguard Worker    CP(WIDE_REG_WRITE, cp_wide_reg_write),
2899*61046927SAndroid Build Coastguard Worker 
2900*61046927SAndroid Build Coastguard Worker    /* for a3xx */
2901*61046927SAndroid Build Coastguard Worker    CP(LOAD_STATE, cp_load_state),
2902*61046927SAndroid Build Coastguard Worker    CP(SET_BIN, cp_set_bin),
2903*61046927SAndroid Build Coastguard Worker 
2904*61046927SAndroid Build Coastguard Worker    /* for a4xx */
2905*61046927SAndroid Build Coastguard Worker    CP(LOAD_STATE4, cp_load_state),
2906*61046927SAndroid Build Coastguard Worker    CP(SET_DRAW_STATE, cp_set_draw_state),
2907*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDX_OFFSET, cp_draw_indx_offset, {.load_all_groups = true}),
2908*61046927SAndroid Build Coastguard Worker    CP(EXEC_CS, cp_exec_cs, {.load_all_groups = true}),
2909*61046927SAndroid Build Coastguard Worker    CP(EXEC_CS_INDIRECT, cp_exec_cs_indirect, {.load_all_groups = true}),
2910*61046927SAndroid Build Coastguard Worker 
2911*61046927SAndroid Build Coastguard Worker    /* for a5xx */
2912*61046927SAndroid Build Coastguard Worker    CP(SET_RENDER_MODE, cp_set_render_mode),
2913*61046927SAndroid Build Coastguard Worker    CP(COMPUTE_CHECKPOINT, cp_compute_checkpoint),
2914*61046927SAndroid Build Coastguard Worker    CP(BLIT, cp_blit),
2915*61046927SAndroid Build Coastguard Worker    CP(CONTEXT_REG_BUNCH, cp_context_reg_bunch),
2916*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDIRECT, cp_draw_indirect, {.load_all_groups = true}),
2917*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDX_INDIRECT, cp_draw_indx_indirect, {.load_all_groups = true}),
2918*61046927SAndroid Build Coastguard Worker    CP(DRAW_INDIRECT_MULTI, cp_draw_indirect_multi, {.load_all_groups = true}),
2919*61046927SAndroid Build Coastguard Worker    CP(SKIP_IB2_ENABLE_GLOBAL, cp_skip_ib2_enable_global),
2920*61046927SAndroid Build Coastguard Worker    CP(SKIP_IB2_ENABLE_LOCAL, cp_skip_ib2_enable_local),
2921*61046927SAndroid Build Coastguard Worker 
2922*61046927SAndroid Build Coastguard Worker    /* for a6xx */
2923*61046927SAndroid Build Coastguard Worker    CP(LOAD_STATE6_GEOM, cp_load_state),
2924*61046927SAndroid Build Coastguard Worker    CP(LOAD_STATE6_FRAG, cp_load_state),
2925*61046927SAndroid Build Coastguard Worker    CP(LOAD_STATE6, cp_load_state),
2926*61046927SAndroid Build Coastguard Worker    CP(SET_MODE, cp_set_mode),
2927*61046927SAndroid Build Coastguard Worker    CP(SET_MARKER, cp_set_marker),
2928*61046927SAndroid Build Coastguard Worker    CP(REG_WRITE, cp_reg_write),
2929*61046927SAndroid Build Coastguard Worker    CP(DRAW_AUTO, cp_draw_auto, {.load_all_groups = true}),
2930*61046927SAndroid Build Coastguard Worker 
2931*61046927SAndroid Build Coastguard Worker    CP(SET_CTXSWITCH_IB, cp_set_ctxswitch_ib),
2932*61046927SAndroid Build Coastguard Worker 
2933*61046927SAndroid Build Coastguard Worker    CP(START_BIN, cp_start_bin),
2934*61046927SAndroid Build Coastguard Worker 
2935*61046927SAndroid Build Coastguard Worker    CP(FIXED_STRIDE_DRAW_TABLE, cp_fixed_stride_draw_table),
2936*61046927SAndroid Build Coastguard Worker 
2937*61046927SAndroid Build Coastguard Worker    /* for a7xx */
2938*61046927SAndroid Build Coastguard Worker    CP(THREAD_CONTROL, cp_set_thread_control),
2939*61046927SAndroid Build Coastguard Worker    CP(CONTEXT_REG_BUNCH2, cp_context_reg_bunch2),
2940*61046927SAndroid Build Coastguard Worker    CP(EVENT_WRITE7, cp_event_write),
2941*61046927SAndroid Build Coastguard Worker };
2942*61046927SAndroid Build Coastguard Worker 
2943*61046927SAndroid Build Coastguard Worker static void
noop_fxn(uint32_t * dwords,uint32_t sizedwords,int level)2944*61046927SAndroid Build Coastguard Worker noop_fxn(uint32_t *dwords, uint32_t sizedwords, int level)
2945*61046927SAndroid Build Coastguard Worker {
2946*61046927SAndroid Build Coastguard Worker }
2947*61046927SAndroid Build Coastguard Worker 
2948*61046927SAndroid Build Coastguard Worker static const struct type3_op *
get_type3_op(unsigned opc)2949*61046927SAndroid Build Coastguard Worker get_type3_op(unsigned opc)
2950*61046927SAndroid Build Coastguard Worker {
2951*61046927SAndroid Build Coastguard Worker    static const struct type3_op dummy_op = {
2952*61046927SAndroid Build Coastguard Worker       .fxn = noop_fxn,
2953*61046927SAndroid Build Coastguard Worker    };
2954*61046927SAndroid Build Coastguard Worker    const char *name = pktname(opc);
2955*61046927SAndroid Build Coastguard Worker 
2956*61046927SAndroid Build Coastguard Worker    if (!name)
2957*61046927SAndroid Build Coastguard Worker       return &dummy_op;
2958*61046927SAndroid Build Coastguard Worker 
2959*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(type3_op); i++)
2960*61046927SAndroid Build Coastguard Worker       if (!strcmp(name, type3_op[i].name))
2961*61046927SAndroid Build Coastguard Worker          return &type3_op[i];
2962*61046927SAndroid Build Coastguard Worker 
2963*61046927SAndroid Build Coastguard Worker    return &dummy_op;
2964*61046927SAndroid Build Coastguard Worker }
2965*61046927SAndroid Build Coastguard Worker 
2966*61046927SAndroid Build Coastguard Worker void
dump_commands(uint32_t * dwords,uint32_t sizedwords,int level)2967*61046927SAndroid Build Coastguard Worker dump_commands(uint32_t *dwords, uint32_t sizedwords, int level)
2968*61046927SAndroid Build Coastguard Worker {
2969*61046927SAndroid Build Coastguard Worker    int dwords_left = sizedwords;
2970*61046927SAndroid Build Coastguard Worker    uint32_t count = 0; /* dword count including packet header */
2971*61046927SAndroid Build Coastguard Worker    uint32_t val;
2972*61046927SAndroid Build Coastguard Worker 
2973*61046927SAndroid Build Coastguard Worker    //	assert(dwords);
2974*61046927SAndroid Build Coastguard Worker    if (!dwords) {
2975*61046927SAndroid Build Coastguard Worker       printf("NULL cmd buffer!\n");
2976*61046927SAndroid Build Coastguard Worker       return;
2977*61046927SAndroid Build Coastguard Worker    }
2978*61046927SAndroid Build Coastguard Worker 
2979*61046927SAndroid Build Coastguard Worker    assert(ib < ARRAY_SIZE(draws));
2980*61046927SAndroid Build Coastguard Worker    draws[ib] = 0;
2981*61046927SAndroid Build Coastguard Worker 
2982*61046927SAndroid Build Coastguard Worker    while (dwords_left > 0) {
2983*61046927SAndroid Build Coastguard Worker 
2984*61046927SAndroid Build Coastguard Worker       current_draw_count = draw_count;
2985*61046927SAndroid Build Coastguard Worker 
2986*61046927SAndroid Build Coastguard Worker       /* hack, this looks like a -1 underflow, in some versions
2987*61046927SAndroid Build Coastguard Worker        * when it tries to write zero registers via pkt0
2988*61046927SAndroid Build Coastguard Worker        */
2989*61046927SAndroid Build Coastguard Worker       //		if ((dwords[0] >> 16) == 0xffff)
2990*61046927SAndroid Build Coastguard Worker       //			goto skip;
2991*61046927SAndroid Build Coastguard Worker 
2992*61046927SAndroid Build Coastguard Worker       if (pkt_is_regwrite(dwords[0], &val, &count)) {
2993*61046927SAndroid Build Coastguard Worker          assert(val < regcnt());
2994*61046927SAndroid Build Coastguard Worker          printl(3, "%swrite %s (%04x)\n", levels[level + 1], regname(val, 1),
2995*61046927SAndroid Build Coastguard Worker                 val);
2996*61046927SAndroid Build Coastguard Worker          dump_registers(val, dwords + 1, count - 1, level + 2);
2997*61046927SAndroid Build Coastguard Worker          if (!quiet(3))
2998*61046927SAndroid Build Coastguard Worker             dump_hex(dwords, count, level + 1);
2999*61046927SAndroid Build Coastguard Worker #if 0
3000*61046927SAndroid Build Coastguard Worker       } else if (pkt_is_type1(dwords[0])) {
3001*61046927SAndroid Build Coastguard Worker          count = 3;
3002*61046927SAndroid Build Coastguard Worker          val = dwords[0] & 0xfff;
3003*61046927SAndroid Build Coastguard Worker          printl(3, "%swrite %s\n", levels[level+1], regname(val, 1));
3004*61046927SAndroid Build Coastguard Worker          dump_registers(val, dwords+1, 1, level+2);
3005*61046927SAndroid Build Coastguard Worker          val = (dwords[0] >> 12) & 0xfff;
3006*61046927SAndroid Build Coastguard Worker          printl(3, "%swrite %s\n", levels[level+1], regname(val, 1));
3007*61046927SAndroid Build Coastguard Worker          dump_registers(val, dwords+2, 1, level+2);
3008*61046927SAndroid Build Coastguard Worker          if (!quiet(3))
3009*61046927SAndroid Build Coastguard Worker             dump_hex(dwords, count, level+1);
3010*61046927SAndroid Build Coastguard Worker #endif
3011*61046927SAndroid Build Coastguard Worker       } else if (pkt_is_opcode(dwords[0], &val, &count)) {
3012*61046927SAndroid Build Coastguard Worker          const struct type3_op *op = get_type3_op(val);
3013*61046927SAndroid Build Coastguard Worker          if (op->options.load_all_groups)
3014*61046927SAndroid Build Coastguard Worker             load_all_groups(level + 1);
3015*61046927SAndroid Build Coastguard Worker          const char *name = pktname(val);
3016*61046927SAndroid Build Coastguard Worker          if (!quiet(2)) {
3017*61046927SAndroid Build Coastguard Worker             printf("\t%sopcode: %s%s%s (%02x) (%d dwords)\n", levels[level],
3018*61046927SAndroid Build Coastguard Worker                    rnn->vc->colors->bctarg, name, rnn->vc->colors->reset, val,
3019*61046927SAndroid Build Coastguard Worker                    count);
3020*61046927SAndroid Build Coastguard Worker          }
3021*61046927SAndroid Build Coastguard Worker          if (name) {
3022*61046927SAndroid Build Coastguard Worker             /* special hack for two packets that decode the same way
3023*61046927SAndroid Build Coastguard Worker              * on a6xx:
3024*61046927SAndroid Build Coastguard Worker              */
3025*61046927SAndroid Build Coastguard Worker             if (!strcmp(name, "CP_LOAD_STATE6_FRAG") ||
3026*61046927SAndroid Build Coastguard Worker                 !strcmp(name, "CP_LOAD_STATE6_GEOM"))
3027*61046927SAndroid Build Coastguard Worker                name = "CP_LOAD_STATE6";
3028*61046927SAndroid Build Coastguard Worker             dump_domain(dwords + 1, count - 1, level + 2, name);
3029*61046927SAndroid Build Coastguard Worker          }
3030*61046927SAndroid Build Coastguard Worker          op->fxn(dwords + 1, count - 1, level + 1);
3031*61046927SAndroid Build Coastguard Worker          if (!quiet(2))
3032*61046927SAndroid Build Coastguard Worker             dump_hex(dwords, count, level + 1);
3033*61046927SAndroid Build Coastguard Worker       } else if (pkt_is_type2(dwords[0])) {
3034*61046927SAndroid Build Coastguard Worker          printl(3, "%snop\n", levels[level + 1]);
3035*61046927SAndroid Build Coastguard Worker          count = 1;
3036*61046927SAndroid Build Coastguard Worker       } else {
3037*61046927SAndroid Build Coastguard Worker          printf("bad type! %08x\n", dwords[0]);
3038*61046927SAndroid Build Coastguard Worker          /* for 5xx+ we can do a passable job of looking for start of next valid
3039*61046927SAndroid Build Coastguard Worker           * packet: */
3040*61046927SAndroid Build Coastguard Worker          if (options->info->chip >= 5) {
3041*61046927SAndroid Build Coastguard Worker             count = find_next_packet(dwords, dwords_left);
3042*61046927SAndroid Build Coastguard Worker          } else {
3043*61046927SAndroid Build Coastguard Worker             return;
3044*61046927SAndroid Build Coastguard Worker          }
3045*61046927SAndroid Build Coastguard Worker       }
3046*61046927SAndroid Build Coastguard Worker 
3047*61046927SAndroid Build Coastguard Worker       dwords += count;
3048*61046927SAndroid Build Coastguard Worker       dwords_left -= count;
3049*61046927SAndroid Build Coastguard Worker    }
3050*61046927SAndroid Build Coastguard Worker 
3051*61046927SAndroid Build Coastguard Worker    if (dwords_left < 0)
3052*61046927SAndroid Build Coastguard Worker       printf("**** this ain't right!! dwords_left=%d\n", dwords_left);
3053*61046927SAndroid Build Coastguard Worker }
3054