xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/decode.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2017-2019 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker  * Copyright 2017-2019 Connor Abbott
4*61046927SAndroid Build Coastguard Worker  * Copyright 2019 Collabora, Ltd.
5*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
6*61046927SAndroid Build Coastguard Worker  */
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include <ctype.h>
9*61046927SAndroid Build Coastguard Worker #include <memory.h>
10*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
11*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
12*61046927SAndroid Build Coastguard Worker #include <stdio.h>
13*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
14*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
15*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
16*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
17*61046927SAndroid Build Coastguard Worker #include <agx_pack.h>
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker #include "util/u_hexdump.h"
20*61046927SAndroid Build Coastguard Worker #include "decode.h"
21*61046927SAndroid Build Coastguard Worker #include "unstable_asahi_drm.h"
22*61046927SAndroid Build Coastguard Worker #ifdef __APPLE__
23*61046927SAndroid Build Coastguard Worker #include "agx_iokit.h"
24*61046927SAndroid Build Coastguard Worker #endif
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker struct libagxdecode_config lib_config;
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker static void
agx_disassemble(void * _code,size_t maxlen,FILE * fp)29*61046927SAndroid Build Coastguard Worker agx_disassemble(void *_code, size_t maxlen, FILE *fp)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker    /* stub */
32*61046927SAndroid Build Coastguard Worker }
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker FILE *agxdecode_dump_stream;
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker #define MAX_MAPPINGS 4096
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker struct agxdecode_ctx {
39*61046927SAndroid Build Coastguard Worker    struct util_dynarray mmap_array;
40*61046927SAndroid Build Coastguard Worker    uint64_t shader_base;
41*61046927SAndroid Build Coastguard Worker };
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker static uint64_t
decode_usc(struct agxdecode_ctx * ctx,uint64_t addr)44*61046927SAndroid Build Coastguard Worker decode_usc(struct agxdecode_ctx *ctx, uint64_t addr)
45*61046927SAndroid Build Coastguard Worker {
46*61046927SAndroid Build Coastguard Worker    return ctx->shader_base + addr;
47*61046927SAndroid Build Coastguard Worker }
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker struct agxdecode_ctx *
agxdecode_new_context(uint64_t shader_base)50*61046927SAndroid Build Coastguard Worker agxdecode_new_context(uint64_t shader_base)
51*61046927SAndroid Build Coastguard Worker {
52*61046927SAndroid Build Coastguard Worker    struct agxdecode_ctx *ctx = calloc(1, sizeof(struct agxdecode_ctx));
53*61046927SAndroid Build Coastguard Worker    ctx->shader_base = shader_base;
54*61046927SAndroid Build Coastguard Worker    return ctx;
55*61046927SAndroid Build Coastguard Worker }
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker void
agxdecode_destroy_context(struct agxdecode_ctx * ctx)58*61046927SAndroid Build Coastguard Worker agxdecode_destroy_context(struct agxdecode_ctx *ctx)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker    free(ctx);
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker static struct agx_bo *
agxdecode_find_mapped_gpu_mem_containing(struct agxdecode_ctx * ctx,uint64_t addr)64*61046927SAndroid Build Coastguard Worker agxdecode_find_mapped_gpu_mem_containing(struct agxdecode_ctx *ctx,
65*61046927SAndroid Build Coastguard Worker                                          uint64_t addr)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&ctx->mmap_array, struct agx_bo, it) {
68*61046927SAndroid Build Coastguard Worker       if (it->va && addr >= it->va->addr && (addr - it->va->addr) < it->size)
69*61046927SAndroid Build Coastguard Worker          return it;
70*61046927SAndroid Build Coastguard Worker    }
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker    return NULL;
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker static struct agx_bo *
agxdecode_find_handle(struct agxdecode_ctx * ctx,unsigned handle,unsigned type)76*61046927SAndroid Build Coastguard Worker agxdecode_find_handle(struct agxdecode_ctx *ctx, unsigned handle, unsigned type)
77*61046927SAndroid Build Coastguard Worker {
78*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&ctx->mmap_array, struct agx_bo, it) {
79*61046927SAndroid Build Coastguard Worker       if (it->handle == handle)
80*61046927SAndroid Build Coastguard Worker          return it;
81*61046927SAndroid Build Coastguard Worker    }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    return NULL;
84*61046927SAndroid Build Coastguard Worker }
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker static size_t
__agxdecode_fetch_gpu_mem(struct agxdecode_ctx * ctx,const struct agx_bo * mem,uint64_t gpu_va,size_t size,void * buf,int line,const char * filename)87*61046927SAndroid Build Coastguard Worker __agxdecode_fetch_gpu_mem(struct agxdecode_ctx *ctx, const struct agx_bo *mem,
88*61046927SAndroid Build Coastguard Worker                           uint64_t gpu_va, size_t size, void *buf, int line,
89*61046927SAndroid Build Coastguard Worker                           const char *filename)
90*61046927SAndroid Build Coastguard Worker {
91*61046927SAndroid Build Coastguard Worker    if (lib_config.read_gpu_mem)
92*61046927SAndroid Build Coastguard Worker       return lib_config.read_gpu_mem(gpu_va, size, buf);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    if (!mem)
95*61046927SAndroid Build Coastguard Worker       mem = agxdecode_find_mapped_gpu_mem_containing(ctx, gpu_va);
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    if (!mem) {
98*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Access to unknown memory %" PRIx64 " in %s:%d\n", gpu_va,
99*61046927SAndroid Build Coastguard Worker               filename, line);
100*61046927SAndroid Build Coastguard Worker       fflush(agxdecode_dump_stream);
101*61046927SAndroid Build Coastguard Worker       assert(0);
102*61046927SAndroid Build Coastguard Worker    }
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    assert(mem);
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker    if (size + (gpu_va - mem->va->addr) > mem->size) {
107*61046927SAndroid Build Coastguard Worker       fprintf(stderr,
108*61046927SAndroid Build Coastguard Worker               "Overflowing to unknown memory %" PRIx64
109*61046927SAndroid Build Coastguard Worker               " of size %zu (max size %zu) in %s:%d\n",
110*61046927SAndroid Build Coastguard Worker               gpu_va, size, (size_t)(mem->size - (gpu_va - mem->va->addr)),
111*61046927SAndroid Build Coastguard Worker               filename, line);
112*61046927SAndroid Build Coastguard Worker       fflush(agxdecode_dump_stream);
113*61046927SAndroid Build Coastguard Worker       assert(0);
114*61046927SAndroid Build Coastguard Worker    }
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    memcpy(buf, mem->map + gpu_va - mem->va->addr, size);
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    return size;
119*61046927SAndroid Build Coastguard Worker }
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker #define agxdecode_fetch_gpu_mem(ctx, gpu_va, size, buf)                        \
122*61046927SAndroid Build Coastguard Worker    __agxdecode_fetch_gpu_mem(ctx, NULL, gpu_va, size, buf, __LINE__, __FILE__)
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker #define agxdecode_fetch_gpu_array(ctx, gpu_va, buf)                            \
125*61046927SAndroid Build Coastguard Worker    agxdecode_fetch_gpu_mem(ctx, gpu_va, sizeof(buf), buf)
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker /* Helpers for parsing the cmdstream */
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker #define DUMP_UNPACKED(T, var, str)                                             \
130*61046927SAndroid Build Coastguard Worker    {                                                                           \
131*61046927SAndroid Build Coastguard Worker       agxdecode_log(str);                                                      \
132*61046927SAndroid Build Coastguard Worker       agx_print(agxdecode_dump_stream, T, var, 2);                             \
133*61046927SAndroid Build Coastguard Worker    }
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker #define DUMP_CL(T, cl, str)                                                    \
136*61046927SAndroid Build Coastguard Worker    {                                                                           \
137*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, cl, T, temp);                          \
138*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(T, temp, str "\n");                                        \
139*61046927SAndroid Build Coastguard Worker    }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker #define DUMP_FIELD(struct, fmt, field)                                         \
142*61046927SAndroid Build Coastguard Worker    {                                                                           \
143*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, #field " = " fmt "\n", struct->field);    \
144*61046927SAndroid Build Coastguard Worker    }
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker #define agxdecode_log(str) fputs(str, agxdecode_dump_stream)
147*61046927SAndroid Build Coastguard Worker #define agxdecode_msg(str) fprintf(agxdecode_dump_stream, "// %s", str)
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker typedef struct drm_asahi_params_global decoder_params;
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker /* Abstraction for command stream parsing */
152*61046927SAndroid Build Coastguard Worker typedef unsigned (*decode_cmd)(struct agxdecode_ctx *ctx, const uint8_t *map,
153*61046927SAndroid Build Coastguard Worker                                uint64_t *link, bool verbose,
154*61046927SAndroid Build Coastguard Worker                                decoder_params *params, void *data);
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker #define STATE_DONE (0xFFFFFFFFu)
157*61046927SAndroid Build Coastguard Worker #define STATE_LINK (0xFFFFFFFEu)
158*61046927SAndroid Build Coastguard Worker #define STATE_CALL (0xFFFFFFFDu)
159*61046927SAndroid Build Coastguard Worker #define STATE_RET  (0xFFFFFFFCu)
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker static void
agxdecode_stateful(struct agxdecode_ctx * ctx,uint64_t va,const char * label,decode_cmd decoder,bool verbose,decoder_params * params,void * data)162*61046927SAndroid Build Coastguard Worker agxdecode_stateful(struct agxdecode_ctx *ctx, uint64_t va, const char *label,
163*61046927SAndroid Build Coastguard Worker                    decode_cmd decoder, bool verbose, decoder_params *params,
164*61046927SAndroid Build Coastguard Worker                    void *data)
165*61046927SAndroid Build Coastguard Worker {
166*61046927SAndroid Build Coastguard Worker    uint64_t stack[16];
167*61046927SAndroid Build Coastguard Worker    unsigned sp = 0;
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker    uint8_t buf[1024];
170*61046927SAndroid Build Coastguard Worker    size_t size = sizeof(buf);
171*61046927SAndroid Build Coastguard Worker    if (!lib_config.read_gpu_mem) {
172*61046927SAndroid Build Coastguard Worker       struct agx_bo *alloc = agxdecode_find_mapped_gpu_mem_containing(ctx, va);
173*61046927SAndroid Build Coastguard Worker       assert(alloc != NULL && "nonexistent object");
174*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "%s (%" PRIx64 ", handle %u)\n", label, va,
175*61046927SAndroid Build Coastguard Worker               alloc->handle);
176*61046927SAndroid Build Coastguard Worker       size = MIN2(size, alloc->size - (va - alloc->va->addr));
177*61046927SAndroid Build Coastguard Worker    } else {
178*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "%s (%" PRIx64 ")\n", label, va);
179*61046927SAndroid Build Coastguard Worker    }
180*61046927SAndroid Build Coastguard Worker    fflush(agxdecode_dump_stream);
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    int len = agxdecode_fetch_gpu_mem(ctx, va, size, buf);
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker    int left = len;
185*61046927SAndroid Build Coastguard Worker    uint8_t *map = buf;
186*61046927SAndroid Build Coastguard Worker    uint64_t link = 0;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker    fflush(agxdecode_dump_stream);
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    while (left) {
191*61046927SAndroid Build Coastguard Worker       if (len <= 0) {
192*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "!! Failed to read GPU memory\n");
193*61046927SAndroid Build Coastguard Worker          fflush(agxdecode_dump_stream);
194*61046927SAndroid Build Coastguard Worker          return;
195*61046927SAndroid Build Coastguard Worker       }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker       unsigned count = decoder(ctx, map, &link, verbose, params, data);
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker       /* If we fail to decode, default to a hexdump (don't hang) */
200*61046927SAndroid Build Coastguard Worker       if (count == 0) {
201*61046927SAndroid Build Coastguard Worker          u_hexdump(agxdecode_dump_stream, map, 8, false);
202*61046927SAndroid Build Coastguard Worker          count = 8;
203*61046927SAndroid Build Coastguard Worker       }
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker       fflush(agxdecode_dump_stream);
206*61046927SAndroid Build Coastguard Worker       if (count == STATE_DONE) {
207*61046927SAndroid Build Coastguard Worker          break;
208*61046927SAndroid Build Coastguard Worker       } else if (count == STATE_LINK) {
209*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Linking to 0x%" PRIx64 "\n\n", link);
210*61046927SAndroid Build Coastguard Worker          va = link;
211*61046927SAndroid Build Coastguard Worker          left = len = agxdecode_fetch_gpu_array(ctx, va, buf);
212*61046927SAndroid Build Coastguard Worker          map = buf;
213*61046927SAndroid Build Coastguard Worker       } else if (count == STATE_CALL) {
214*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream,
215*61046927SAndroid Build Coastguard Worker                  "Calling 0x%" PRIx64 " (return = 0x%" PRIx64 ")\n\n", link,
216*61046927SAndroid Build Coastguard Worker                  va + 8);
217*61046927SAndroid Build Coastguard Worker          assert(sp < ARRAY_SIZE(stack));
218*61046927SAndroid Build Coastguard Worker          stack[sp++] = va + 8;
219*61046927SAndroid Build Coastguard Worker          va = link;
220*61046927SAndroid Build Coastguard Worker          left = len = agxdecode_fetch_gpu_array(ctx, va, buf);
221*61046927SAndroid Build Coastguard Worker          map = buf;
222*61046927SAndroid Build Coastguard Worker       } else if (count == STATE_RET) {
223*61046927SAndroid Build Coastguard Worker          assert(sp > 0);
224*61046927SAndroid Build Coastguard Worker          va = stack[--sp];
225*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Returning to 0x%" PRIx64 "\n\n", va);
226*61046927SAndroid Build Coastguard Worker          left = len = agxdecode_fetch_gpu_array(ctx, va, buf);
227*61046927SAndroid Build Coastguard Worker          map = buf;
228*61046927SAndroid Build Coastguard Worker       } else {
229*61046927SAndroid Build Coastguard Worker          va += count;
230*61046927SAndroid Build Coastguard Worker          map += count;
231*61046927SAndroid Build Coastguard Worker          left -= count;
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker          if (left < 512 && len == sizeof(buf)) {
234*61046927SAndroid Build Coastguard Worker             left = len = agxdecode_fetch_gpu_array(ctx, va, buf);
235*61046927SAndroid Build Coastguard Worker             map = buf;
236*61046927SAndroid Build Coastguard Worker          }
237*61046927SAndroid Build Coastguard Worker       }
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker static void
agxdecode_texture_pbe(struct agxdecode_ctx * ctx,const void * map)242*61046927SAndroid Build Coastguard Worker agxdecode_texture_pbe(struct agxdecode_ctx *ctx, const void *map)
243*61046927SAndroid Build Coastguard Worker {
244*61046927SAndroid Build Coastguard Worker    struct AGX_TEXTURE tex;
245*61046927SAndroid Build Coastguard Worker    struct AGX_PBE pbe;
246*61046927SAndroid Build Coastguard Worker 
247*61046927SAndroid Build Coastguard Worker    bool valid_texture = AGX_TEXTURE_unpack(NULL, map, &tex);
248*61046927SAndroid Build Coastguard Worker    bool valid_pbe = AGX_PBE_unpack(NULL, map, &pbe);
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker    /* Try to guess if it's texture or PBE */
251*61046927SAndroid Build Coastguard Worker    valid_texture &=
252*61046927SAndroid Build Coastguard Worker       tex.swizzle_r <= AGX_CHANNEL_0 && tex.swizzle_g <= AGX_CHANNEL_0 &&
253*61046927SAndroid Build Coastguard Worker       tex.swizzle_b <= AGX_CHANNEL_0 && tex.swizzle_a <= AGX_CHANNEL_0;
254*61046927SAndroid Build Coastguard Worker 
255*61046927SAndroid Build Coastguard Worker    if (valid_texture && !valid_pbe) {
256*61046927SAndroid Build Coastguard Worker       DUMP_CL(TEXTURE, map, "Texture");
257*61046927SAndroid Build Coastguard Worker    } else if (valid_pbe && !valid_texture) {
258*61046927SAndroid Build Coastguard Worker       DUMP_CL(PBE, map, "PBE");
259*61046927SAndroid Build Coastguard Worker    } else {
260*61046927SAndroid Build Coastguard Worker       if (!valid_texture) {
261*61046927SAndroid Build Coastguard Worker          assert(!valid_pbe);
262*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "XXX: invalid texture/PBE\n");
263*61046927SAndroid Build Coastguard Worker       }
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker       DUMP_CL(TEXTURE, map, "Texture");
266*61046927SAndroid Build Coastguard Worker       DUMP_CL(PBE, map, "PBE");
267*61046927SAndroid Build Coastguard Worker    }
268*61046927SAndroid Build Coastguard Worker }
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker static unsigned
agxdecode_usc(struct agxdecode_ctx * ctx,const uint8_t * map,UNUSED uint64_t * link,UNUSED bool verbose,decoder_params * params,UNUSED void * data)271*61046927SAndroid Build Coastguard Worker agxdecode_usc(struct agxdecode_ctx *ctx, const uint8_t *map,
272*61046927SAndroid Build Coastguard Worker               UNUSED uint64_t *link, UNUSED bool verbose,
273*61046927SAndroid Build Coastguard Worker               decoder_params *params, UNUSED void *data)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker    enum agx_sampler_states *sampler_states = data;
276*61046927SAndroid Build Coastguard Worker    enum agx_usc_control type = map[0];
277*61046927SAndroid Build Coastguard Worker    uint8_t buf[8192];
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker    bool extended_samplers =
280*61046927SAndroid Build Coastguard Worker       (sampler_states != NULL) &&
281*61046927SAndroid Build Coastguard Worker       (((*sampler_states) == AGX_SAMPLER_STATES_8_EXTENDED) ||
282*61046927SAndroid Build Coastguard Worker        ((*sampler_states) == AGX_SAMPLER_STATES_16_EXTENDED));
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker #define USC_CASE(name, human)                                                  \
285*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_##name: {                                              \
286*61046927SAndroid Build Coastguard Worker       DUMP_CL(USC_##name, map, human);                                         \
287*61046927SAndroid Build Coastguard Worker       return AGX_USC_##name##_LENGTH;                                          \
288*61046927SAndroid Build Coastguard Worker    }
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker    switch (type) {
291*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_NO_PRESHADER: {
292*61046927SAndroid Build Coastguard Worker       DUMP_CL(USC_NO_PRESHADER, map, "No preshader");
293*61046927SAndroid Build Coastguard Worker       return STATE_DONE;
294*61046927SAndroid Build Coastguard Worker    }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_PRESHADER: {
297*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_PRESHADER, ctrl);
298*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_PRESHADER, ctrl, "Preshader\n");
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker       agx_disassemble(
301*61046927SAndroid Build Coastguard Worker          buf, agxdecode_fetch_gpu_array(ctx, decode_usc(ctx, ctrl.code), buf),
302*61046927SAndroid Build Coastguard Worker          agxdecode_dump_stream);
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker       return STATE_DONE;
305*61046927SAndroid Build Coastguard Worker    }
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_SHADER: {
308*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_SHADER, ctrl);
309*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_SHADER, ctrl, "Shader\n");
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker       agxdecode_log("\n");
312*61046927SAndroid Build Coastguard Worker       agx_disassemble(
313*61046927SAndroid Build Coastguard Worker          buf, agxdecode_fetch_gpu_array(ctx, decode_usc(ctx, ctrl.code), buf),
314*61046927SAndroid Build Coastguard Worker          agxdecode_dump_stream);
315*61046927SAndroid Build Coastguard Worker       agxdecode_log("\n");
316*61046927SAndroid Build Coastguard Worker 
317*61046927SAndroid Build Coastguard Worker       return AGX_USC_SHADER_LENGTH;
318*61046927SAndroid Build Coastguard Worker    }
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_SAMPLER: {
321*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_SAMPLER, temp);
322*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_SAMPLER, temp, "Sampler state\n");
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker       size_t stride =
325*61046927SAndroid Build Coastguard Worker          AGX_SAMPLER_LENGTH + (extended_samplers ? AGX_BORDER_LENGTH : 0);
326*61046927SAndroid Build Coastguard Worker       uint8_t *samp = alloca(stride * temp.count);
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker       agxdecode_fetch_gpu_mem(ctx, temp.buffer, stride * temp.count, samp);
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < temp.count; ++i) {
331*61046927SAndroid Build Coastguard Worker          DUMP_CL(SAMPLER, samp, "Sampler");
332*61046927SAndroid Build Coastguard Worker          samp += AGX_SAMPLER_LENGTH;
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker          if (extended_samplers) {
335*61046927SAndroid Build Coastguard Worker             DUMP_CL(BORDER, samp, "Border");
336*61046927SAndroid Build Coastguard Worker             samp += AGX_BORDER_LENGTH;
337*61046927SAndroid Build Coastguard Worker          }
338*61046927SAndroid Build Coastguard Worker       }
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker       return AGX_USC_SAMPLER_LENGTH;
341*61046927SAndroid Build Coastguard Worker    }
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_TEXTURE: {
344*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_TEXTURE, temp);
345*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_TEXTURE, temp, "Texture state\n");
346*61046927SAndroid Build Coastguard Worker 
347*61046927SAndroid Build Coastguard Worker       uint8_t buf[AGX_TEXTURE_LENGTH * temp.count];
348*61046927SAndroid Build Coastguard Worker       uint8_t *tex = buf;
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker       agxdecode_fetch_gpu_array(ctx, temp.buffer, buf);
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker       /* Note: samplers only need 8 byte alignment? */
353*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < temp.count; ++i) {
354*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "ts%u: \n", temp.start + i);
355*61046927SAndroid Build Coastguard Worker          agxdecode_texture_pbe(ctx, tex);
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker          tex += AGX_TEXTURE_LENGTH;
358*61046927SAndroid Build Coastguard Worker       }
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker       return AGX_USC_TEXTURE_LENGTH;
361*61046927SAndroid Build Coastguard Worker    }
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_UNIFORM: {
364*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_UNIFORM, temp);
365*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_UNIFORM, temp, "Uniform\n");
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker       uint8_t buf[2 * temp.size_halfs];
368*61046927SAndroid Build Coastguard Worker       agxdecode_fetch_gpu_array(ctx, temp.buffer, buf);
369*61046927SAndroid Build Coastguard Worker       u_hexdump(agxdecode_dump_stream, buf, 2 * temp.size_halfs, false);
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker       return AGX_USC_UNIFORM_LENGTH;
372*61046927SAndroid Build Coastguard Worker    }
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    case AGX_USC_CONTROL_UNIFORM_HIGH: {
375*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, USC_UNIFORM_HIGH, temp);
376*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(USC_UNIFORM_HIGH, temp, "Uniform (high)\n");
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker       uint8_t buf[2 * temp.size_halfs];
379*61046927SAndroid Build Coastguard Worker       agxdecode_fetch_gpu_array(ctx, temp.buffer, buf);
380*61046927SAndroid Build Coastguard Worker       u_hexdump(agxdecode_dump_stream, buf, 2 * temp.size_halfs, false);
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker       return AGX_USC_UNIFORM_HIGH_LENGTH;
383*61046927SAndroid Build Coastguard Worker    }
384*61046927SAndroid Build Coastguard Worker 
385*61046927SAndroid Build Coastguard Worker       USC_CASE(FRAGMENT_PROPERTIES, "Fragment properties");
386*61046927SAndroid Build Coastguard Worker       USC_CASE(SHARED, "Shared");
387*61046927SAndroid Build Coastguard Worker       USC_CASE(REGISTERS, "Registers");
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker    default:
390*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "Unknown USC control type: %u\n", type);
391*61046927SAndroid Build Coastguard Worker       u_hexdump(agxdecode_dump_stream, map, 8, false);
392*61046927SAndroid Build Coastguard Worker       return 8;
393*61046927SAndroid Build Coastguard Worker    }
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker #undef USC_CASE
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker #define PPP_PRINT(map, header_name, struct_name, human)                        \
399*61046927SAndroid Build Coastguard Worker    if (hdr.header_name) {                                                      \
400*61046927SAndroid Build Coastguard Worker       if (((map + AGX_##struct_name##_LENGTH) > (base + size))) {              \
401*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Buffer overrun in PPP update\n");     \
402*61046927SAndroid Build Coastguard Worker          return;                                                               \
403*61046927SAndroid Build Coastguard Worker       }                                                                        \
404*61046927SAndroid Build Coastguard Worker       DUMP_CL(struct_name, map, human);                                        \
405*61046927SAndroid Build Coastguard Worker       map += AGX_##struct_name##_LENGTH;                                       \
406*61046927SAndroid Build Coastguard Worker       fflush(agxdecode_dump_stream);                                           \
407*61046927SAndroid Build Coastguard Worker    }
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker static void
agxdecode_record(struct agxdecode_ctx * ctx,uint64_t va,size_t size,bool verbose,decoder_params * params)410*61046927SAndroid Build Coastguard Worker agxdecode_record(struct agxdecode_ctx *ctx, uint64_t va, size_t size,
411*61046927SAndroid Build Coastguard Worker                  bool verbose, decoder_params *params)
412*61046927SAndroid Build Coastguard Worker {
413*61046927SAndroid Build Coastguard Worker    uint8_t buf[size];
414*61046927SAndroid Build Coastguard Worker    uint8_t *base = buf;
415*61046927SAndroid Build Coastguard Worker    uint8_t *map = base;
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker    agxdecode_fetch_gpu_array(ctx, va, buf);
418*61046927SAndroid Build Coastguard Worker 
419*61046927SAndroid Build Coastguard Worker    agx_unpack(agxdecode_dump_stream, map, PPP_HEADER, hdr);
420*61046927SAndroid Build Coastguard Worker    map += AGX_PPP_HEADER_LENGTH;
421*61046927SAndroid Build Coastguard Worker 
422*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_control, FRAGMENT_CONTROL, "Fragment control");
423*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_control_2, FRAGMENT_CONTROL, "Fragment control 2");
424*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_front_face, FRAGMENT_FACE, "Front face");
425*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_front_face_2, FRAGMENT_FACE_2, "Front face 2");
426*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_front_stencil, FRAGMENT_STENCIL, "Front stencil");
427*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_back_face, FRAGMENT_FACE, "Back face");
428*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_back_face_2, FRAGMENT_FACE_2, "Back face 2");
429*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, fragment_back_stencil, FRAGMENT_STENCIL, "Back stencil");
430*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, depth_bias_scissor, DEPTH_BIAS_SCISSOR, "Depth bias/scissor");
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker    if (hdr.region_clip) {
433*61046927SAndroid Build Coastguard Worker       if (((map + (AGX_REGION_CLIP_LENGTH * hdr.viewport_count)) >
434*61046927SAndroid Build Coastguard Worker            (base + size))) {
435*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Buffer overrun in PPP update\n");
436*61046927SAndroid Build Coastguard Worker          return;
437*61046927SAndroid Build Coastguard Worker       }
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < hdr.viewport_count; ++i) {
440*61046927SAndroid Build Coastguard Worker          DUMP_CL(REGION_CLIP, map, "Region clip");
441*61046927SAndroid Build Coastguard Worker          map += AGX_REGION_CLIP_LENGTH;
442*61046927SAndroid Build Coastguard Worker          fflush(agxdecode_dump_stream);
443*61046927SAndroid Build Coastguard Worker       }
444*61046927SAndroid Build Coastguard Worker    }
445*61046927SAndroid Build Coastguard Worker 
446*61046927SAndroid Build Coastguard Worker    if (hdr.viewport) {
447*61046927SAndroid Build Coastguard Worker       if (((map + AGX_VIEWPORT_CONTROL_LENGTH +
448*61046927SAndroid Build Coastguard Worker             (AGX_VIEWPORT_LENGTH * hdr.viewport_count)) > (base + size))) {
449*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Buffer overrun in PPP update\n");
450*61046927SAndroid Build Coastguard Worker          return;
451*61046927SAndroid Build Coastguard Worker       }
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker       DUMP_CL(VIEWPORT_CONTROL, map, "Viewport control");
454*61046927SAndroid Build Coastguard Worker       map += AGX_VIEWPORT_CONTROL_LENGTH;
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < hdr.viewport_count; ++i) {
457*61046927SAndroid Build Coastguard Worker          DUMP_CL(VIEWPORT, map, "Viewport");
458*61046927SAndroid Build Coastguard Worker          map += AGX_VIEWPORT_LENGTH;
459*61046927SAndroid Build Coastguard Worker          fflush(agxdecode_dump_stream);
460*61046927SAndroid Build Coastguard Worker       }
461*61046927SAndroid Build Coastguard Worker    }
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, w_clamp, W_CLAMP, "W clamp");
464*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, output_select, OUTPUT_SELECT, "Output select");
465*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, varying_counts_32, VARYING_COUNTS, "Varying counts 32");
466*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, varying_counts_16, VARYING_COUNTS, "Varying counts 16");
467*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, cull, CULL, "Cull");
468*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, cull_2, CULL_2, "Cull 2");
469*61046927SAndroid Build Coastguard Worker 
470*61046927SAndroid Build Coastguard Worker    if (hdr.fragment_shader) {
471*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, FRAGMENT_SHADER_WORD_0, frag_0);
472*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map + 4, FRAGMENT_SHADER_WORD_1,
473*61046927SAndroid Build Coastguard Worker                  frag_1);
474*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map + 8, FRAGMENT_SHADER_WORD_2,
475*61046927SAndroid Build Coastguard Worker                  frag_2);
476*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, frag_1.pipeline),
477*61046927SAndroid Build Coastguard Worker                          "Fragment pipeline", agxdecode_usc, verbose, params,
478*61046927SAndroid Build Coastguard Worker                          &frag_0.sampler_state_register_count);
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker       if (frag_2.cf_bindings) {
481*61046927SAndroid Build Coastguard Worker          uint8_t buf[128];
482*61046927SAndroid Build Coastguard Worker          uint8_t *cf = buf;
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker          agxdecode_fetch_gpu_array(ctx, decode_usc(ctx, frag_2.cf_bindings),
485*61046927SAndroid Build Coastguard Worker                                    buf);
486*61046927SAndroid Build Coastguard Worker          u_hexdump(agxdecode_dump_stream, cf, 128, false);
487*61046927SAndroid Build Coastguard Worker 
488*61046927SAndroid Build Coastguard Worker          DUMP_CL(CF_BINDING_HEADER, cf, "Coefficient binding header:");
489*61046927SAndroid Build Coastguard Worker          cf += AGX_CF_BINDING_HEADER_LENGTH;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker          for (unsigned i = 0; i < frag_0.cf_binding_count; ++i) {
492*61046927SAndroid Build Coastguard Worker             DUMP_CL(CF_BINDING, cf, "Coefficient binding:");
493*61046927SAndroid Build Coastguard Worker             cf += AGX_CF_BINDING_LENGTH;
494*61046927SAndroid Build Coastguard Worker          }
495*61046927SAndroid Build Coastguard Worker       }
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker       DUMP_CL(FRAGMENT_SHADER_WORD_0, map, "Fragment shader word 0");
498*61046927SAndroid Build Coastguard Worker       DUMP_CL(FRAGMENT_SHADER_WORD_1, map + 4, "Fragment shader word 1");
499*61046927SAndroid Build Coastguard Worker       DUMP_CL(FRAGMENT_SHADER_WORD_2, map + 8, "Fragment shader word 2");
500*61046927SAndroid Build Coastguard Worker       DUMP_CL(FRAGMENT_SHADER_WORD_3, map + 12, "Fragment shader word 3");
501*61046927SAndroid Build Coastguard Worker       map += 16;
502*61046927SAndroid Build Coastguard Worker    }
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, occlusion_query, FRAGMENT_OCCLUSION_QUERY, "Occlusion query");
505*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, occlusion_query_2, FRAGMENT_OCCLUSION_QUERY_2,
506*61046927SAndroid Build Coastguard Worker              "Occlusion query 2");
507*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, output_unknown, OUTPUT_UNKNOWN, "Output unknown");
508*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, output_size, OUTPUT_SIZE, "Output size");
509*61046927SAndroid Build Coastguard Worker    PPP_PRINT(map, varying_word_2, VARYING_2, "Varying word 2");
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker    /* PPP print checks we don't read too much, now check we read enough */
512*61046927SAndroid Build Coastguard Worker    assert(map == (base + size) && "invalid size of PPP update");
513*61046927SAndroid Build Coastguard Worker }
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker static unsigned
agxdecode_cdm(struct agxdecode_ctx * ctx,const uint8_t * map,uint64_t * link,bool verbose,decoder_params * params,UNUSED void * data)516*61046927SAndroid Build Coastguard Worker agxdecode_cdm(struct agxdecode_ctx *ctx, const uint8_t *map, uint64_t *link,
517*61046927SAndroid Build Coastguard Worker               bool verbose, decoder_params *params, UNUSED void *data)
518*61046927SAndroid Build Coastguard Worker {
519*61046927SAndroid Build Coastguard Worker    /* Bits 29-31 contain the block type */
520*61046927SAndroid Build Coastguard Worker    enum agx_cdm_block_type block_type = (map[3] >> 5);
521*61046927SAndroid Build Coastguard Worker 
522*61046927SAndroid Build Coastguard Worker    switch (block_type) {
523*61046927SAndroid Build Coastguard Worker    case AGX_CDM_BLOCK_TYPE_LAUNCH: {
524*61046927SAndroid Build Coastguard Worker       size_t length =
525*61046927SAndroid Build Coastguard Worker          AGX_CDM_LAUNCH_WORD_0_LENGTH + AGX_CDM_LAUNCH_WORD_1_LENGTH;
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker #define CDM_PRINT(STRUCT_NAME, human)                                          \
528*61046927SAndroid Build Coastguard Worker    do {                                                                        \
529*61046927SAndroid Build Coastguard Worker       DUMP_CL(CDM_##STRUCT_NAME, map, human);                                  \
530*61046927SAndroid Build Coastguard Worker       map += AGX_CDM_##STRUCT_NAME##_LENGTH;                                   \
531*61046927SAndroid Build Coastguard Worker       length += AGX_CDM_##STRUCT_NAME##_LENGTH;                                \
532*61046927SAndroid Build Coastguard Worker    } while (0);
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map + 0, CDM_LAUNCH_WORD_0, hdr0);
535*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map + 4, CDM_LAUNCH_WORD_1, hdr1);
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, hdr1.pipeline), "Pipeline",
538*61046927SAndroid Build Coastguard Worker                          agxdecode_usc, verbose, params,
539*61046927SAndroid Build Coastguard Worker                          &hdr0.sampler_state_register_count);
540*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(CDM_LAUNCH_WORD_0, hdr0, "Compute\n");
541*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(CDM_LAUNCH_WORD_1, hdr1, "Compute\n");
542*61046927SAndroid Build Coastguard Worker       map += 8;
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker       /* Added in G14X */
545*61046927SAndroid Build Coastguard Worker       if (params->gpu_generation >= 14 && params->num_clusters_total > 1)
546*61046927SAndroid Build Coastguard Worker          CDM_PRINT(UNK_G14X, "Unknown G14X");
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker       switch (hdr0.mode) {
549*61046927SAndroid Build Coastguard Worker       case AGX_CDM_MODE_DIRECT:
550*61046927SAndroid Build Coastguard Worker          CDM_PRINT(GLOBAL_SIZE, "Global size");
551*61046927SAndroid Build Coastguard Worker          CDM_PRINT(LOCAL_SIZE, "Local size");
552*61046927SAndroid Build Coastguard Worker          break;
553*61046927SAndroid Build Coastguard Worker       case AGX_CDM_MODE_INDIRECT_GLOBAL:
554*61046927SAndroid Build Coastguard Worker          CDM_PRINT(INDIRECT, "Indirect buffer");
555*61046927SAndroid Build Coastguard Worker          CDM_PRINT(LOCAL_SIZE, "Local size");
556*61046927SAndroid Build Coastguard Worker          break;
557*61046927SAndroid Build Coastguard Worker       case AGX_CDM_MODE_INDIRECT_LOCAL:
558*61046927SAndroid Build Coastguard Worker          CDM_PRINT(INDIRECT, "Indirect buffer");
559*61046927SAndroid Build Coastguard Worker          break;
560*61046927SAndroid Build Coastguard Worker       default:
561*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Unknown CDM mode: %u\n", hdr0.mode);
562*61046927SAndroid Build Coastguard Worker          break;
563*61046927SAndroid Build Coastguard Worker       }
564*61046927SAndroid Build Coastguard Worker 
565*61046927SAndroid Build Coastguard Worker       return length;
566*61046927SAndroid Build Coastguard Worker    }
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker    case AGX_CDM_BLOCK_TYPE_STREAM_LINK: {
569*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, CDM_STREAM_LINK, hdr);
570*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(CDM_STREAM_LINK, hdr, "Stream Link\n");
571*61046927SAndroid Build Coastguard Worker       *link = hdr.target_lo | (((uint64_t)hdr.target_hi) << 32);
572*61046927SAndroid Build Coastguard Worker       return STATE_LINK;
573*61046927SAndroid Build Coastguard Worker    }
574*61046927SAndroid Build Coastguard Worker 
575*61046927SAndroid Build Coastguard Worker    case AGX_CDM_BLOCK_TYPE_STREAM_TERMINATE: {
576*61046927SAndroid Build Coastguard Worker       DUMP_CL(CDM_STREAM_TERMINATE, map, "Stream Terminate");
577*61046927SAndroid Build Coastguard Worker       return STATE_DONE;
578*61046927SAndroid Build Coastguard Worker    }
579*61046927SAndroid Build Coastguard Worker 
580*61046927SAndroid Build Coastguard Worker    case AGX_CDM_BLOCK_TYPE_BARRIER: {
581*61046927SAndroid Build Coastguard Worker       DUMP_CL(CDM_BARRIER, map, "Barrier");
582*61046927SAndroid Build Coastguard Worker       return AGX_CDM_BARRIER_LENGTH;
583*61046927SAndroid Build Coastguard Worker    }
584*61046927SAndroid Build Coastguard Worker 
585*61046927SAndroid Build Coastguard Worker    default:
586*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "Unknown CDM block type: %u\n",
587*61046927SAndroid Build Coastguard Worker               block_type);
588*61046927SAndroid Build Coastguard Worker       u_hexdump(agxdecode_dump_stream, map, 8, false);
589*61046927SAndroid Build Coastguard Worker       return 8;
590*61046927SAndroid Build Coastguard Worker    }
591*61046927SAndroid Build Coastguard Worker }
592*61046927SAndroid Build Coastguard Worker 
593*61046927SAndroid Build Coastguard Worker static unsigned
agxdecode_vdm(struct agxdecode_ctx * ctx,const uint8_t * map,uint64_t * link,bool verbose,decoder_params * params,UNUSED void * data)594*61046927SAndroid Build Coastguard Worker agxdecode_vdm(struct agxdecode_ctx *ctx, const uint8_t *map, uint64_t *link,
595*61046927SAndroid Build Coastguard Worker               bool verbose, decoder_params *params, UNUSED void *data)
596*61046927SAndroid Build Coastguard Worker {
597*61046927SAndroid Build Coastguard Worker    /* Bits 29-31 contain the block type */
598*61046927SAndroid Build Coastguard Worker    enum agx_vdm_block_type block_type = (map[3] >> 5);
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker    switch (block_type) {
601*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_BARRIER: {
602*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, VDM_BARRIER, hdr);
603*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(VDM_BARRIER, hdr, "Barrier\n");
604*61046927SAndroid Build Coastguard Worker       return hdr.returns ? STATE_RET : AGX_VDM_BARRIER_LENGTH;
605*61046927SAndroid Build Coastguard Worker    }
606*61046927SAndroid Build Coastguard Worker 
607*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_PPP_STATE_UPDATE: {
608*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, PPP_STATE, cmd);
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker       uint64_t address = (((uint64_t)cmd.pointer_hi) << 32) | cmd.pointer_lo;
611*61046927SAndroid Build Coastguard Worker 
612*61046927SAndroid Build Coastguard Worker       if (!lib_config.read_gpu_mem) {
613*61046927SAndroid Build Coastguard Worker          struct agx_bo *mem =
614*61046927SAndroid Build Coastguard Worker             agxdecode_find_mapped_gpu_mem_containing(ctx, address);
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker          if (!mem) {
617*61046927SAndroid Build Coastguard Worker             DUMP_UNPACKED(PPP_STATE, cmd, "Non-existent record (XXX)\n");
618*61046927SAndroid Build Coastguard Worker             return AGX_PPP_STATE_LENGTH;
619*61046927SAndroid Build Coastguard Worker          }
620*61046927SAndroid Build Coastguard Worker       }
621*61046927SAndroid Build Coastguard Worker 
622*61046927SAndroid Build Coastguard Worker       agxdecode_record(ctx, address, cmd.size_words * 4, verbose, params);
623*61046927SAndroid Build Coastguard Worker       return AGX_PPP_STATE_LENGTH;
624*61046927SAndroid Build Coastguard Worker    }
625*61046927SAndroid Build Coastguard Worker 
626*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_VDM_STATE_UPDATE: {
627*61046927SAndroid Build Coastguard Worker       size_t length = AGX_VDM_STATE_LENGTH;
628*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, VDM_STATE, hdr);
629*61046927SAndroid Build Coastguard Worker       map += AGX_VDM_STATE_LENGTH;
630*61046927SAndroid Build Coastguard Worker 
631*61046927SAndroid Build Coastguard Worker #define VDM_PRINT(header_name, STRUCT_NAME, human)                             \
632*61046927SAndroid Build Coastguard Worker    if (hdr.header_name##_present) {                                            \
633*61046927SAndroid Build Coastguard Worker       DUMP_CL(VDM_STATE_##STRUCT_NAME, map, human);                            \
634*61046927SAndroid Build Coastguard Worker       map += AGX_VDM_STATE_##STRUCT_NAME##_LENGTH;                             \
635*61046927SAndroid Build Coastguard Worker       length += AGX_VDM_STATE_##STRUCT_NAME##_LENGTH;                          \
636*61046927SAndroid Build Coastguard Worker    }
637*61046927SAndroid Build Coastguard Worker 
638*61046927SAndroid Build Coastguard Worker       VDM_PRINT(restart_index, RESTART_INDEX, "Restart index");
639*61046927SAndroid Build Coastguard Worker 
640*61046927SAndroid Build Coastguard Worker       /* If word 1 is present but word 0 is not, fallback to compact samplers */
641*61046927SAndroid Build Coastguard Worker       enum agx_sampler_states sampler_states = 0;
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker       if (hdr.vertex_shader_word_0_present) {
644*61046927SAndroid Build Coastguard Worker          agx_unpack(agxdecode_dump_stream, map, VDM_STATE_VERTEX_SHADER_WORD_0,
645*61046927SAndroid Build Coastguard Worker                     word_0);
646*61046927SAndroid Build Coastguard Worker          sampler_states = word_0.sampler_state_register_count;
647*61046927SAndroid Build Coastguard Worker       }
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker       VDM_PRINT(vertex_shader_word_0, VERTEX_SHADER_WORD_0,
650*61046927SAndroid Build Coastguard Worker                 "Vertex shader word 0");
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker       if (hdr.vertex_shader_word_1_present) {
653*61046927SAndroid Build Coastguard Worker          agx_unpack(agxdecode_dump_stream, map, VDM_STATE_VERTEX_SHADER_WORD_1,
654*61046927SAndroid Build Coastguard Worker                     word_1);
655*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Pipeline %X\n",
656*61046927SAndroid Build Coastguard Worker                  (uint32_t)word_1.pipeline);
657*61046927SAndroid Build Coastguard Worker          agxdecode_stateful(ctx, decode_usc(ctx, word_1.pipeline), "Pipeline",
658*61046927SAndroid Build Coastguard Worker                             agxdecode_usc, verbose, params, &sampler_states);
659*61046927SAndroid Build Coastguard Worker       }
660*61046927SAndroid Build Coastguard Worker 
661*61046927SAndroid Build Coastguard Worker       VDM_PRINT(vertex_shader_word_1, VERTEX_SHADER_WORD_1,
662*61046927SAndroid Build Coastguard Worker                 "Vertex shader word 1");
663*61046927SAndroid Build Coastguard Worker       VDM_PRINT(vertex_outputs, VERTEX_OUTPUTS, "Vertex outputs");
664*61046927SAndroid Build Coastguard Worker       VDM_PRINT(tessellation, TESSELLATION, "Tessellation");
665*61046927SAndroid Build Coastguard Worker       VDM_PRINT(vertex_unknown, VERTEX_UNKNOWN, "Vertex unknown");
666*61046927SAndroid Build Coastguard Worker       VDM_PRINT(tessellation_scale, TESSELLATION_SCALE, "Tessellation scale");
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker #undef VDM_PRINT
669*61046927SAndroid Build Coastguard Worker       return hdr.tessellation_scale_present ? length : ALIGN_POT(length, 8);
670*61046927SAndroid Build Coastguard Worker    }
671*61046927SAndroid Build Coastguard Worker 
672*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_INDEX_LIST: {
673*61046927SAndroid Build Coastguard Worker       size_t length = AGX_INDEX_LIST_LENGTH;
674*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, INDEX_LIST, hdr);
675*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(INDEX_LIST, hdr, "Index List\n");
676*61046927SAndroid Build Coastguard Worker       map += AGX_INDEX_LIST_LENGTH;
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker #define IDX_PRINT(header_name, STRUCT_NAME, human)                             \
679*61046927SAndroid Build Coastguard Worker    if (hdr.header_name##_present) {                                            \
680*61046927SAndroid Build Coastguard Worker       DUMP_CL(INDEX_LIST_##STRUCT_NAME, map, human);                           \
681*61046927SAndroid Build Coastguard Worker       map += AGX_INDEX_LIST_##STRUCT_NAME##_LENGTH;                            \
682*61046927SAndroid Build Coastguard Worker       length += AGX_INDEX_LIST_##STRUCT_NAME##_LENGTH;                         \
683*61046927SAndroid Build Coastguard Worker    }
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker       IDX_PRINT(index_buffer, BUFFER_LO, "Index buffer");
686*61046927SAndroid Build Coastguard Worker       IDX_PRINT(index_count, COUNT, "Index count");
687*61046927SAndroid Build Coastguard Worker       IDX_PRINT(instance_count, INSTANCES, "Instance count");
688*61046927SAndroid Build Coastguard Worker       IDX_PRINT(start, START, "Start");
689*61046927SAndroid Build Coastguard Worker       IDX_PRINT(indirect_buffer, INDIRECT_BUFFER, "Indirect buffer");
690*61046927SAndroid Build Coastguard Worker       IDX_PRINT(index_buffer_size, BUFFER_SIZE, "Index buffer size");
691*61046927SAndroid Build Coastguard Worker 
692*61046927SAndroid Build Coastguard Worker #undef IDX_PRINT
693*61046927SAndroid Build Coastguard Worker       return length;
694*61046927SAndroid Build Coastguard Worker    }
695*61046927SAndroid Build Coastguard Worker 
696*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_STREAM_LINK: {
697*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, VDM_STREAM_LINK, hdr);
698*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(VDM_STREAM_LINK, hdr, "Stream Link\n");
699*61046927SAndroid Build Coastguard Worker       *link = hdr.target_lo | (((uint64_t)hdr.target_hi) << 32);
700*61046927SAndroid Build Coastguard Worker       return hdr.with_return ? STATE_CALL : STATE_LINK;
701*61046927SAndroid Build Coastguard Worker    }
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_STREAM_TERMINATE: {
704*61046927SAndroid Build Coastguard Worker       DUMP_CL(VDM_STREAM_TERMINATE, map, "Stream Terminate");
705*61046927SAndroid Build Coastguard Worker       return STATE_DONE;
706*61046927SAndroid Build Coastguard Worker    }
707*61046927SAndroid Build Coastguard Worker 
708*61046927SAndroid Build Coastguard Worker    case AGX_VDM_BLOCK_TYPE_TESSELLATE: {
709*61046927SAndroid Build Coastguard Worker       size_t length = AGX_VDM_TESSELLATE_LENGTH;
710*61046927SAndroid Build Coastguard Worker       agx_unpack(agxdecode_dump_stream, map, VDM_TESSELLATE, hdr);
711*61046927SAndroid Build Coastguard Worker       DUMP_UNPACKED(VDM_TESSELLATE, hdr, "Tessellate List\n");
712*61046927SAndroid Build Coastguard Worker       map += AGX_VDM_TESSELLATE_LENGTH;
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker #define TESS_PRINT(header_name, STRUCT_NAME, human)                            \
715*61046927SAndroid Build Coastguard Worker    if (hdr.header_name##_present) {                                            \
716*61046927SAndroid Build Coastguard Worker       DUMP_CL(VDM_TESSELLATE_##STRUCT_NAME, map, human);                       \
717*61046927SAndroid Build Coastguard Worker       map += AGX_VDM_TESSELLATE_##STRUCT_NAME##_LENGTH;                        \
718*61046927SAndroid Build Coastguard Worker       length += AGX_VDM_TESSELLATE_##STRUCT_NAME##_LENGTH;                     \
719*61046927SAndroid Build Coastguard Worker    }
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker       TESS_PRINT(factor_buffer, FACTOR_BUFFER, "Factor buffer");
722*61046927SAndroid Build Coastguard Worker       TESS_PRINT(patch_count, PATCH_COUNT, "Patch");
723*61046927SAndroid Build Coastguard Worker       TESS_PRINT(instance_count, INSTANCE_COUNT, "Instance count");
724*61046927SAndroid Build Coastguard Worker       TESS_PRINT(base_patch, BASE_PATCH, "Base patch");
725*61046927SAndroid Build Coastguard Worker       TESS_PRINT(base_instance, BASE_INSTANCE, "Base instance");
726*61046927SAndroid Build Coastguard Worker       TESS_PRINT(instance_stride, INSTANCE_STRIDE, "Instance stride");
727*61046927SAndroid Build Coastguard Worker       TESS_PRINT(indirect, INDIRECT, "Indirect");
728*61046927SAndroid Build Coastguard Worker       TESS_PRINT(unknown, UNKNOWN, "Unknown");
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker #undef TESS_PRINT
731*61046927SAndroid Build Coastguard Worker       return length;
732*61046927SAndroid Build Coastguard Worker    }
733*61046927SAndroid Build Coastguard Worker 
734*61046927SAndroid Build Coastguard Worker    default:
735*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "Unknown VDM block type: %u\n",
736*61046927SAndroid Build Coastguard Worker               block_type);
737*61046927SAndroid Build Coastguard Worker       u_hexdump(agxdecode_dump_stream, map, 8, false);
738*61046927SAndroid Build Coastguard Worker       return 8;
739*61046927SAndroid Build Coastguard Worker    }
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker static void
agxdecode_cs(struct agxdecode_ctx * ctx,uint32_t * cmdbuf,uint64_t encoder,bool verbose,decoder_params * params)743*61046927SAndroid Build Coastguard Worker agxdecode_cs(struct agxdecode_ctx *ctx, uint32_t *cmdbuf, uint64_t encoder,
744*61046927SAndroid Build Coastguard Worker              bool verbose, decoder_params *params)
745*61046927SAndroid Build Coastguard Worker {
746*61046927SAndroid Build Coastguard Worker    agx_unpack(agxdecode_dump_stream, cmdbuf + 16, IOGPU_COMPUTE, cs);
747*61046927SAndroid Build Coastguard Worker    DUMP_UNPACKED(IOGPU_COMPUTE, cs, "Compute\n");
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, encoder, "Encoder", agxdecode_cdm, verbose, params,
750*61046927SAndroid Build Coastguard Worker                       NULL);
751*61046927SAndroid Build Coastguard Worker 
752*61046927SAndroid Build Coastguard Worker    fprintf(agxdecode_dump_stream, "Context switch program:\n");
753*61046927SAndroid Build Coastguard Worker    uint8_t buf[1024];
754*61046927SAndroid Build Coastguard Worker    agx_disassemble(buf,
755*61046927SAndroid Build Coastguard Worker                    agxdecode_fetch_gpu_array(
756*61046927SAndroid Build Coastguard Worker                       ctx, decode_usc(ctx, cs.context_switch_program), buf),
757*61046927SAndroid Build Coastguard Worker                    agxdecode_dump_stream);
758*61046927SAndroid Build Coastguard Worker }
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker static void
agxdecode_gfx(struct agxdecode_ctx * ctx,uint32_t * cmdbuf,uint64_t encoder,bool verbose,decoder_params * params)761*61046927SAndroid Build Coastguard Worker agxdecode_gfx(struct agxdecode_ctx *ctx, uint32_t *cmdbuf, uint64_t encoder,
762*61046927SAndroid Build Coastguard Worker               bool verbose, decoder_params *params)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker    agx_unpack(agxdecode_dump_stream, cmdbuf + 16, IOGPU_GRAPHICS, gfx);
765*61046927SAndroid Build Coastguard Worker    DUMP_UNPACKED(IOGPU_GRAPHICS, gfx, "Graphics\n");
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, encoder, "Encoder", agxdecode_vdm, verbose, params,
768*61046927SAndroid Build Coastguard Worker                       NULL);
769*61046927SAndroid Build Coastguard Worker 
770*61046927SAndroid Build Coastguard Worker    if (gfx.clear_pipeline_unk) {
771*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "Unk: %X\n", gfx.clear_pipeline_unk);
772*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, gfx.clear_pipeline),
773*61046927SAndroid Build Coastguard Worker                          "Clear pipeline", agxdecode_usc, verbose, params,
774*61046927SAndroid Build Coastguard Worker                          NULL);
775*61046927SAndroid Build Coastguard Worker    }
776*61046927SAndroid Build Coastguard Worker 
777*61046927SAndroid Build Coastguard Worker    if (gfx.store_pipeline_unk) {
778*61046927SAndroid Build Coastguard Worker       assert(gfx.store_pipeline_unk == 0x4);
779*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, gfx.store_pipeline),
780*61046927SAndroid Build Coastguard Worker                          "Store pipeline", agxdecode_usc, verbose, params,
781*61046927SAndroid Build Coastguard Worker                          NULL);
782*61046927SAndroid Build Coastguard Worker    }
783*61046927SAndroid Build Coastguard Worker 
784*61046927SAndroid Build Coastguard Worker    assert((gfx.partial_reload_pipeline_unk & 0xF) == 0x4);
785*61046927SAndroid Build Coastguard Worker    if (gfx.partial_reload_pipeline) {
786*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, gfx.partial_reload_pipeline),
787*61046927SAndroid Build Coastguard Worker                          "Partial reload pipeline", agxdecode_usc, verbose,
788*61046927SAndroid Build Coastguard Worker                          params, NULL);
789*61046927SAndroid Build Coastguard Worker    }
790*61046927SAndroid Build Coastguard Worker 
791*61046927SAndroid Build Coastguard Worker    if (gfx.partial_store_pipeline) {
792*61046927SAndroid Build Coastguard Worker       agxdecode_stateful(ctx, decode_usc(ctx, gfx.partial_store_pipeline),
793*61046927SAndroid Build Coastguard Worker                          "Partial store pipeline", agxdecode_usc, verbose,
794*61046927SAndroid Build Coastguard Worker                          params, NULL);
795*61046927SAndroid Build Coastguard Worker    }
796*61046927SAndroid Build Coastguard Worker }
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker static void
agxdecode_sampler_heap(struct agxdecode_ctx * ctx,uint64_t heap,unsigned count)799*61046927SAndroid Build Coastguard Worker agxdecode_sampler_heap(struct agxdecode_ctx *ctx, uint64_t heap, unsigned count)
800*61046927SAndroid Build Coastguard Worker {
801*61046927SAndroid Build Coastguard Worker    if (!heap)
802*61046927SAndroid Build Coastguard Worker       return;
803*61046927SAndroid Build Coastguard Worker 
804*61046927SAndroid Build Coastguard Worker    struct agx_sampler_packed samp[1024];
805*61046927SAndroid Build Coastguard Worker    agxdecode_fetch_gpu_array(ctx, heap, samp);
806*61046927SAndroid Build Coastguard Worker 
807*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < count; ++i) {
808*61046927SAndroid Build Coastguard Worker       bool nonzero = false;
809*61046927SAndroid Build Coastguard Worker       for (unsigned j = 0; j < ARRAY_SIZE(samp[i].opaque); ++j) {
810*61046927SAndroid Build Coastguard Worker          nonzero |= samp[i].opaque[j] != 0;
811*61046927SAndroid Build Coastguard Worker       }
812*61046927SAndroid Build Coastguard Worker 
813*61046927SAndroid Build Coastguard Worker       if (nonzero) {
814*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "Heap sampler %u\n", i);
815*61046927SAndroid Build Coastguard Worker 
816*61046927SAndroid Build Coastguard Worker          agx_unpack(agxdecode_dump_stream, samp + i, SAMPLER, temp);
817*61046927SAndroid Build Coastguard Worker          agx_print(agxdecode_dump_stream, SAMPLER, temp, 2);
818*61046927SAndroid Build Coastguard Worker       }
819*61046927SAndroid Build Coastguard Worker    }
820*61046927SAndroid Build Coastguard Worker }
821*61046927SAndroid Build Coastguard Worker 
822*61046927SAndroid Build Coastguard Worker void
agxdecode_image_heap(struct agxdecode_ctx * ctx,uint64_t heap,unsigned nr_entries)823*61046927SAndroid Build Coastguard Worker agxdecode_image_heap(struct agxdecode_ctx *ctx, uint64_t heap,
824*61046927SAndroid Build Coastguard Worker                      unsigned nr_entries)
825*61046927SAndroid Build Coastguard Worker {
826*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_open();
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker    fprintf(agxdecode_dump_stream, "Image heap:\n");
829*61046927SAndroid Build Coastguard Worker    struct agx_texture_packed *map = calloc(nr_entries, AGX_TEXTURE_LENGTH);
830*61046927SAndroid Build Coastguard Worker    agxdecode_fetch_gpu_mem(ctx, heap, AGX_TEXTURE_LENGTH * nr_entries, map);
831*61046927SAndroid Build Coastguard Worker 
832*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < nr_entries; ++i) {
833*61046927SAndroid Build Coastguard Worker       bool nonzero = false;
834*61046927SAndroid Build Coastguard Worker       for (unsigned j = 0; j < ARRAY_SIZE(map[i].opaque); ++j) {
835*61046927SAndroid Build Coastguard Worker          nonzero |= map[i].opaque[j] != 0;
836*61046927SAndroid Build Coastguard Worker       }
837*61046927SAndroid Build Coastguard Worker 
838*61046927SAndroid Build Coastguard Worker       if (nonzero) {
839*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "%u: \n", i);
840*61046927SAndroid Build Coastguard Worker          agxdecode_texture_pbe(ctx, map + i);
841*61046927SAndroid Build Coastguard Worker          fprintf(agxdecode_dump_stream, "\n");
842*61046927SAndroid Build Coastguard Worker       }
843*61046927SAndroid Build Coastguard Worker    }
844*61046927SAndroid Build Coastguard Worker 
845*61046927SAndroid Build Coastguard Worker    free(map);
846*61046927SAndroid Build Coastguard Worker }
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker void
agxdecode_drm_cmd_render(struct agxdecode_ctx * ctx,struct drm_asahi_params_global * params,struct drm_asahi_cmd_render * c,bool verbose)849*61046927SAndroid Build Coastguard Worker agxdecode_drm_cmd_render(struct agxdecode_ctx *ctx,
850*61046927SAndroid Build Coastguard Worker                          struct drm_asahi_params_global *params,
851*61046927SAndroid Build Coastguard Worker                          struct drm_asahi_cmd_render *c, bool verbose)
852*61046927SAndroid Build Coastguard Worker {
853*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_open();
854*61046927SAndroid Build Coastguard Worker 
855*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%llx", flags);
856*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", encoder_ptr);
857*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, c->encoder_ptr, "Encoder", agxdecode_vdm, verbose,
858*61046927SAndroid Build Coastguard Worker                       params, NULL);
859*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", encoder_id);
860*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", cmd_ta_id);
861*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", cmd_3d_id);
862*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", ppp_ctrl);
863*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", ppp_multisamplectl);
864*61046927SAndroid Build Coastguard Worker    DUMP_CL(ZLS_CONTROL, &c->zls_ctrl, "ZLS Control");
865*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", depth_buffer_load);
866*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", depth_buffer_store);
867*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", depth_buffer_partial);
868*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", stencil_buffer_load);
869*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", stencil_buffer_store);
870*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", stencil_buffer_partial);
871*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", scissor_array);
872*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", depth_bias_array);
873*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", fb_width);
874*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", fb_height);
875*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", layers);
876*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", samples);
877*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", sample_size);
878*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", tib_blocks);
879*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", utile_width);
880*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", utile_height);
881*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", load_pipeline);
882*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", load_pipeline_bind);
883*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, decode_usc(ctx, c->load_pipeline & ~0x7),
884*61046927SAndroid Build Coastguard Worker                       "Load pipeline", agxdecode_usc, verbose, params, NULL);
885*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", store_pipeline);
886*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", store_pipeline_bind);
887*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, decode_usc(ctx, c->store_pipeline & ~0x7),
888*61046927SAndroid Build Coastguard Worker                       "Store pipeline", agxdecode_usc, verbose, params, NULL);
889*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", partial_reload_pipeline);
890*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", partial_reload_pipeline_bind);
891*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, decode_usc(ctx, c->partial_reload_pipeline & ~0x7),
892*61046927SAndroid Build Coastguard Worker                       "Partial reload pipeline", agxdecode_usc, verbose, params,
893*61046927SAndroid Build Coastguard Worker                       NULL);
894*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", partial_store_pipeline);
895*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", partial_store_pipeline_bind);
896*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, decode_usc(ctx, c->partial_store_pipeline & ~0x7),
897*61046927SAndroid Build Coastguard Worker                       "Partial store pipeline", agxdecode_usc, verbose, params,
898*61046927SAndroid Build Coastguard Worker                       NULL);
899*61046927SAndroid Build Coastguard Worker 
900*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", depth_dimensions);
901*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", isp_bgobjdepth);
902*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", isp_bgobjvals);
903*61046927SAndroid Build Coastguard Worker 
904*61046927SAndroid Build Coastguard Worker    agxdecode_sampler_heap(ctx, c->vertex_sampler_array,
905*61046927SAndroid Build Coastguard Worker                           c->vertex_sampler_count);
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker    /* Linux driver doesn't use this, at least for now */
908*61046927SAndroid Build Coastguard Worker    assert(c->fragment_sampler_array == c->vertex_sampler_array);
909*61046927SAndroid Build Coastguard Worker    assert(c->fragment_sampler_count == c->vertex_sampler_count);
910*61046927SAndroid Build Coastguard Worker 
911*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", vertex_attachment_count);
912*61046927SAndroid Build Coastguard Worker    struct drm_asahi_attachment *vertex_attachments =
913*61046927SAndroid Build Coastguard Worker       (void *)c->vertex_attachments;
914*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < c->vertex_attachment_count; i++) {
915*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&vertex_attachments[i]), "0x%x", order);
916*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&vertex_attachments[i]), "0x%llx", size);
917*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&vertex_attachments[i]), "0x%llx", pointer);
918*61046927SAndroid Build Coastguard Worker    }
919*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%d", fragment_attachment_count);
920*61046927SAndroid Build Coastguard Worker    struct drm_asahi_attachment *fragment_attachments =
921*61046927SAndroid Build Coastguard Worker       (void *)c->fragment_attachments;
922*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < c->fragment_attachment_count; i++) {
923*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&fragment_attachments[i]), "0x%x", order);
924*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&fragment_attachments[i]), "0x%llx", size);
925*61046927SAndroid Build Coastguard Worker       DUMP_FIELD((&fragment_attachments[i]), "0x%llx", pointer);
926*61046927SAndroid Build Coastguard Worker    }
927*61046927SAndroid Build Coastguard Worker }
928*61046927SAndroid Build Coastguard Worker 
929*61046927SAndroid Build Coastguard Worker void
agxdecode_drm_cmd_compute(struct agxdecode_ctx * ctx,struct drm_asahi_params_global * params,struct drm_asahi_cmd_compute * c,bool verbose)930*61046927SAndroid Build Coastguard Worker agxdecode_drm_cmd_compute(struct agxdecode_ctx *ctx,
931*61046927SAndroid Build Coastguard Worker                           struct drm_asahi_params_global *params,
932*61046927SAndroid Build Coastguard Worker                           struct drm_asahi_cmd_compute *c, bool verbose)
933*61046927SAndroid Build Coastguard Worker {
934*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_open();
935*61046927SAndroid Build Coastguard Worker 
936*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "%llx", flags);
937*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%llx", encoder_ptr);
938*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, c->encoder_ptr, "Encoder", agxdecode_cdm, verbose,
939*61046927SAndroid Build Coastguard Worker                       params, NULL);
940*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", encoder_id);
941*61046927SAndroid Build Coastguard Worker    DUMP_FIELD(c, "0x%x", cmd_id);
942*61046927SAndroid Build Coastguard Worker 
943*61046927SAndroid Build Coastguard Worker    agxdecode_sampler_heap(ctx, c->sampler_array, c->sampler_count);
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker    if (c->helper_program & 1) {
946*61046927SAndroid Build Coastguard Worker       fprintf(agxdecode_dump_stream, "Helper program:\n");
947*61046927SAndroid Build Coastguard Worker       uint8_t buf[1024];
948*61046927SAndroid Build Coastguard Worker       agx_disassemble(buf,
949*61046927SAndroid Build Coastguard Worker                       agxdecode_fetch_gpu_array(
950*61046927SAndroid Build Coastguard Worker                          ctx, decode_usc(ctx, c->helper_program & ~1), buf),
951*61046927SAndroid Build Coastguard Worker                       agxdecode_dump_stream);
952*61046927SAndroid Build Coastguard Worker    }
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker 
955*61046927SAndroid Build Coastguard Worker static void
chip_id_to_params(decoder_params * params,uint32_t chip_id)956*61046927SAndroid Build Coastguard Worker chip_id_to_params(decoder_params *params, uint32_t chip_id)
957*61046927SAndroid Build Coastguard Worker {
958*61046927SAndroid Build Coastguard Worker    switch (chip_id) {
959*61046927SAndroid Build Coastguard Worker    case 0x6000 ... 0x6002:
960*61046927SAndroid Build Coastguard Worker       *params = (decoder_params){
961*61046927SAndroid Build Coastguard Worker          .gpu_generation = 13,
962*61046927SAndroid Build Coastguard Worker          .gpu_variant = "SCD"[chip_id & 15],
963*61046927SAndroid Build Coastguard Worker          .chip_id = chip_id,
964*61046927SAndroid Build Coastguard Worker          .num_clusters_total = 2 << (chip_id & 15),
965*61046927SAndroid Build Coastguard Worker       };
966*61046927SAndroid Build Coastguard Worker       break;
967*61046927SAndroid Build Coastguard Worker    case 0x6020 ... 0x6022:
968*61046927SAndroid Build Coastguard Worker       *params = (decoder_params){
969*61046927SAndroid Build Coastguard Worker          .gpu_generation = 14,
970*61046927SAndroid Build Coastguard Worker          .gpu_variant = "SCD"[chip_id & 15],
971*61046927SAndroid Build Coastguard Worker          .chip_id = chip_id,
972*61046927SAndroid Build Coastguard Worker          .num_clusters_total = 2 << (chip_id & 15),
973*61046927SAndroid Build Coastguard Worker       };
974*61046927SAndroid Build Coastguard Worker       break;
975*61046927SAndroid Build Coastguard Worker    case 0x8112:
976*61046927SAndroid Build Coastguard Worker       *params = (decoder_params){
977*61046927SAndroid Build Coastguard Worker          .gpu_generation = 14,
978*61046927SAndroid Build Coastguard Worker          .gpu_variant = 'G',
979*61046927SAndroid Build Coastguard Worker          .chip_id = chip_id,
980*61046927SAndroid Build Coastguard Worker          .num_clusters_total = 1,
981*61046927SAndroid Build Coastguard Worker       };
982*61046927SAndroid Build Coastguard Worker       break;
983*61046927SAndroid Build Coastguard Worker    case 0x8103:
984*61046927SAndroid Build Coastguard Worker    default:
985*61046927SAndroid Build Coastguard Worker       *params = (decoder_params){
986*61046927SAndroid Build Coastguard Worker          .gpu_generation = 13,
987*61046927SAndroid Build Coastguard Worker          .gpu_variant = 'G',
988*61046927SAndroid Build Coastguard Worker          .chip_id = chip_id,
989*61046927SAndroid Build Coastguard Worker          .num_clusters_total = 1,
990*61046927SAndroid Build Coastguard Worker       };
991*61046927SAndroid Build Coastguard Worker       break;
992*61046927SAndroid Build Coastguard Worker    }
993*61046927SAndroid Build Coastguard Worker }
994*61046927SAndroid Build Coastguard Worker 
995*61046927SAndroid Build Coastguard Worker #ifdef __APPLE__
996*61046927SAndroid Build Coastguard Worker 
997*61046927SAndroid Build Coastguard Worker void
agxdecode_cmdstream(struct agxdecode_ctx * ctx,unsigned cmdbuf_handle,unsigned map_handle,bool verbose)998*61046927SAndroid Build Coastguard Worker agxdecode_cmdstream(struct agxdecode_ctx *ctx, unsigned cmdbuf_handle,
999*61046927SAndroid Build Coastguard Worker                     unsigned map_handle, bool verbose)
1000*61046927SAndroid Build Coastguard Worker {
1001*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_open();
1002*61046927SAndroid Build Coastguard Worker 
1003*61046927SAndroid Build Coastguard Worker    struct agx_bo *cmdbuf =
1004*61046927SAndroid Build Coastguard Worker       agxdecode_find_handle(cmdbuf_handle, AGX_ALLOC_CMDBUF);
1005*61046927SAndroid Build Coastguard Worker    struct agx_bo *map = agxdecode_find_handle(map_handle, AGX_ALLOC_MEMMAP);
1006*61046927SAndroid Build Coastguard Worker    assert(cmdbuf != NULL && "nonexistent command buffer");
1007*61046927SAndroid Build Coastguard Worker    assert(map != NULL && "nonexistent mapping");
1008*61046927SAndroid Build Coastguard Worker 
1009*61046927SAndroid Build Coastguard Worker    /* Print the IOGPU stuff */
1010*61046927SAndroid Build Coastguard Worker    agx_unpack(agxdecode_dump_stream, cmdbuf->map, IOGPU_HEADER, cmd);
1011*61046927SAndroid Build Coastguard Worker    DUMP_UNPACKED(IOGPU_HEADER, cmd, "IOGPU Header\n");
1012*61046927SAndroid Build Coastguard Worker 
1013*61046927SAndroid Build Coastguard Worker    DUMP_CL(IOGPU_ATTACHMENT_COUNT,
1014*61046927SAndroid Build Coastguard Worker            ((uint8_t *)cmdbuf->map + cmd.attachment_offset),
1015*61046927SAndroid Build Coastguard Worker            "Attachment count");
1016*61046927SAndroid Build Coastguard Worker 
1017*61046927SAndroid Build Coastguard Worker    uint32_t *attachments =
1018*61046927SAndroid Build Coastguard Worker       (uint32_t *)((uint8_t *)cmdbuf->map + cmd.attachment_offset);
1019*61046927SAndroid Build Coastguard Worker    unsigned attachment_count = attachments[3];
1020*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < attachment_count; ++i) {
1021*61046927SAndroid Build Coastguard Worker       uint32_t *ptr = attachments + 4 + (i * AGX_IOGPU_ATTACHMENT_LENGTH / 4);
1022*61046927SAndroid Build Coastguard Worker       DUMP_CL(IOGPU_ATTACHMENT, ptr, "Attachment");
1023*61046927SAndroid Build Coastguard Worker    }
1024*61046927SAndroid Build Coastguard Worker 
1025*61046927SAndroid Build Coastguard Worker    struct drm_asahi_params_global params;
1026*61046927SAndroid Build Coastguard Worker 
1027*61046927SAndroid Build Coastguard Worker    chip_id_to_params(&params, 0x8103);
1028*61046927SAndroid Build Coastguard Worker 
1029*61046927SAndroid Build Coastguard Worker    if (cmd.unk_5 == 3)
1030*61046927SAndroid Build Coastguard Worker       agxdecode_cs((uint32_t *)cmdbuf->map, cmd.encoder, verbose, &params);
1031*61046927SAndroid Build Coastguard Worker    else
1032*61046927SAndroid Build Coastguard Worker       agxdecode_gfx((uint32_t *)cmdbuf->map, cmd.encoder, verbose, &params);
1033*61046927SAndroid Build Coastguard Worker }
1034*61046927SAndroid Build Coastguard Worker 
1035*61046927SAndroid Build Coastguard Worker #endif
1036*61046927SAndroid Build Coastguard Worker 
1037*61046927SAndroid Build Coastguard Worker void
agxdecode_track_alloc(struct agxdecode_ctx * ctx,struct agx_bo * alloc)1038*61046927SAndroid Build Coastguard Worker agxdecode_track_alloc(struct agxdecode_ctx *ctx, struct agx_bo *alloc)
1039*61046927SAndroid Build Coastguard Worker {
1040*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&ctx->mmap_array, struct agx_bo, it) {
1041*61046927SAndroid Build Coastguard Worker       bool match = (it->handle == alloc->handle);
1042*61046927SAndroid Build Coastguard Worker       assert(!match && "tried to alloc already allocated BO");
1043*61046927SAndroid Build Coastguard Worker    }
1044*61046927SAndroid Build Coastguard Worker 
1045*61046927SAndroid Build Coastguard Worker    util_dynarray_append(&ctx->mmap_array, struct agx_bo, *alloc);
1046*61046927SAndroid Build Coastguard Worker }
1047*61046927SAndroid Build Coastguard Worker 
1048*61046927SAndroid Build Coastguard Worker void
agxdecode_track_free(struct agxdecode_ctx * ctx,struct agx_bo * bo)1049*61046927SAndroid Build Coastguard Worker agxdecode_track_free(struct agxdecode_ctx *ctx, struct agx_bo *bo)
1050*61046927SAndroid Build Coastguard Worker {
1051*61046927SAndroid Build Coastguard Worker    bool found = false;
1052*61046927SAndroid Build Coastguard Worker 
1053*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&ctx->mmap_array, struct agx_bo, it) {
1054*61046927SAndroid Build Coastguard Worker       if (it->handle == bo->handle) {
1055*61046927SAndroid Build Coastguard Worker          assert(!found && "mapped multiple times!");
1056*61046927SAndroid Build Coastguard Worker          found = true;
1057*61046927SAndroid Build Coastguard Worker 
1058*61046927SAndroid Build Coastguard Worker          memset(it, 0, sizeof(*it));
1059*61046927SAndroid Build Coastguard Worker       }
1060*61046927SAndroid Build Coastguard Worker    }
1061*61046927SAndroid Build Coastguard Worker 
1062*61046927SAndroid Build Coastguard Worker    assert(found && "freed unmapped memory");
1063*61046927SAndroid Build Coastguard Worker }
1064*61046927SAndroid Build Coastguard Worker 
1065*61046927SAndroid Build Coastguard Worker static int agxdecode_dump_frame_count = 0;
1066*61046927SAndroid Build Coastguard Worker 
1067*61046927SAndroid Build Coastguard Worker void
agxdecode_dump_file_open(void)1068*61046927SAndroid Build Coastguard Worker agxdecode_dump_file_open(void)
1069*61046927SAndroid Build Coastguard Worker {
1070*61046927SAndroid Build Coastguard Worker    if (agxdecode_dump_stream)
1071*61046927SAndroid Build Coastguard Worker       return;
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker    /* This does a getenv every frame, so it is possible to use
1074*61046927SAndroid Build Coastguard Worker     * setenv to change the base at runtime.
1075*61046927SAndroid Build Coastguard Worker     */
1076*61046927SAndroid Build Coastguard Worker    const char *dump_file_base =
1077*61046927SAndroid Build Coastguard Worker       getenv("AGXDECODE_DUMP_FILE") ?: "agxdecode.dump";
1078*61046927SAndroid Build Coastguard Worker    if (!strcmp(dump_file_base, "stderr"))
1079*61046927SAndroid Build Coastguard Worker       agxdecode_dump_stream = stderr;
1080*61046927SAndroid Build Coastguard Worker    else {
1081*61046927SAndroid Build Coastguard Worker       char buffer[1024];
1082*61046927SAndroid Build Coastguard Worker       snprintf(buffer, sizeof(buffer), "%s.%04d", dump_file_base,
1083*61046927SAndroid Build Coastguard Worker                agxdecode_dump_frame_count);
1084*61046927SAndroid Build Coastguard Worker       printf("agxdecode: dump command stream to file %s\n", buffer);
1085*61046927SAndroid Build Coastguard Worker       agxdecode_dump_stream = fopen(buffer, "w");
1086*61046927SAndroid Build Coastguard Worker       if (!agxdecode_dump_stream) {
1087*61046927SAndroid Build Coastguard Worker          fprintf(stderr,
1088*61046927SAndroid Build Coastguard Worker                  "agxdecode: failed to open command stream log file %s\n",
1089*61046927SAndroid Build Coastguard Worker                  buffer);
1090*61046927SAndroid Build Coastguard Worker       }
1091*61046927SAndroid Build Coastguard Worker    }
1092*61046927SAndroid Build Coastguard Worker }
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker static void
agxdecode_dump_file_close(void)1095*61046927SAndroid Build Coastguard Worker agxdecode_dump_file_close(void)
1096*61046927SAndroid Build Coastguard Worker {
1097*61046927SAndroid Build Coastguard Worker    if (agxdecode_dump_stream && agxdecode_dump_stream != stderr) {
1098*61046927SAndroid Build Coastguard Worker       fclose(agxdecode_dump_stream);
1099*61046927SAndroid Build Coastguard Worker       agxdecode_dump_stream = NULL;
1100*61046927SAndroid Build Coastguard Worker    }
1101*61046927SAndroid Build Coastguard Worker }
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker void
agxdecode_next_frame(void)1104*61046927SAndroid Build Coastguard Worker agxdecode_next_frame(void)
1105*61046927SAndroid Build Coastguard Worker {
1106*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_close();
1107*61046927SAndroid Build Coastguard Worker    agxdecode_dump_frame_count++;
1108*61046927SAndroid Build Coastguard Worker }
1109*61046927SAndroid Build Coastguard Worker 
1110*61046927SAndroid Build Coastguard Worker void
agxdecode_close(void)1111*61046927SAndroid Build Coastguard Worker agxdecode_close(void)
1112*61046927SAndroid Build Coastguard Worker {
1113*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_close();
1114*61046927SAndroid Build Coastguard Worker }
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker static ssize_t
libagxdecode_writer(void * cookie,const char * buffer,size_t size)1117*61046927SAndroid Build Coastguard Worker libagxdecode_writer(void *cookie, const char *buffer, size_t size)
1118*61046927SAndroid Build Coastguard Worker {
1119*61046927SAndroid Build Coastguard Worker    return lib_config.stream_write(buffer, size);
1120*61046927SAndroid Build Coastguard Worker }
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker #ifdef _GNU_SOURCE
1123*61046927SAndroid Build Coastguard Worker static cookie_io_functions_t funcs = {.write = libagxdecode_writer};
1124*61046927SAndroid Build Coastguard Worker #endif
1125*61046927SAndroid Build Coastguard Worker 
1126*61046927SAndroid Build Coastguard Worker static decoder_params lib_params;
1127*61046927SAndroid Build Coastguard Worker 
1128*61046927SAndroid Build Coastguard Worker void
libagxdecode_init(struct libagxdecode_config * config)1129*61046927SAndroid Build Coastguard Worker libagxdecode_init(struct libagxdecode_config *config)
1130*61046927SAndroid Build Coastguard Worker {
1131*61046927SAndroid Build Coastguard Worker #ifdef _GNU_SOURCE
1132*61046927SAndroid Build Coastguard Worker    lib_config = *config;
1133*61046927SAndroid Build Coastguard Worker    agxdecode_dump_stream = fopencookie(NULL, "w", funcs);
1134*61046927SAndroid Build Coastguard Worker 
1135*61046927SAndroid Build Coastguard Worker    chip_id_to_params(&lib_params, config->chip_id);
1136*61046927SAndroid Build Coastguard Worker #else
1137*61046927SAndroid Build Coastguard Worker    /* fopencookie is a glibc extension */
1138*61046927SAndroid Build Coastguard Worker    unreachable("libagxdecode only available with glibc");
1139*61046927SAndroid Build Coastguard Worker #endif
1140*61046927SAndroid Build Coastguard Worker }
1141*61046927SAndroid Build Coastguard Worker 
1142*61046927SAndroid Build Coastguard Worker void
libagxdecode_vdm(struct agxdecode_ctx * ctx,uint64_t addr,const char * label,bool verbose)1143*61046927SAndroid Build Coastguard Worker libagxdecode_vdm(struct agxdecode_ctx *ctx, uint64_t addr, const char *label,
1144*61046927SAndroid Build Coastguard Worker                  bool verbose)
1145*61046927SAndroid Build Coastguard Worker {
1146*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, addr, label, agxdecode_vdm, verbose, &lib_params,
1147*61046927SAndroid Build Coastguard Worker                       NULL);
1148*61046927SAndroid Build Coastguard Worker }
1149*61046927SAndroid Build Coastguard Worker 
1150*61046927SAndroid Build Coastguard Worker void
libagxdecode_cdm(struct agxdecode_ctx * ctx,uint64_t addr,const char * label,bool verbose)1151*61046927SAndroid Build Coastguard Worker libagxdecode_cdm(struct agxdecode_ctx *ctx, uint64_t addr, const char *label,
1152*61046927SAndroid Build Coastguard Worker                  bool verbose)
1153*61046927SAndroid Build Coastguard Worker {
1154*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, addr, label, agxdecode_cdm, verbose, &lib_params,
1155*61046927SAndroid Build Coastguard Worker                       NULL);
1156*61046927SAndroid Build Coastguard Worker }
1157*61046927SAndroid Build Coastguard Worker void
libagxdecode_usc(struct agxdecode_ctx * ctx,uint64_t addr,const char * label,bool verbose)1158*61046927SAndroid Build Coastguard Worker libagxdecode_usc(struct agxdecode_ctx *ctx, uint64_t addr, const char *label,
1159*61046927SAndroid Build Coastguard Worker                  bool verbose)
1160*61046927SAndroid Build Coastguard Worker {
1161*61046927SAndroid Build Coastguard Worker    agxdecode_stateful(ctx, addr, label, agxdecode_usc, verbose, &lib_params,
1162*61046927SAndroid Build Coastguard Worker                       NULL);
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker void
libagxdecode_shutdown(void)1165*61046927SAndroid Build Coastguard Worker libagxdecode_shutdown(void)
1166*61046927SAndroid Build Coastguard Worker {
1167*61046927SAndroid Build Coastguard Worker    agxdecode_dump_file_close();
1168*61046927SAndroid Build Coastguard Worker }
1169