xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/rdcompiler-utils.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Igalia S.L.
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include <assert.h>
7*61046927SAndroid Build Coastguard Worker #include <err.h>
8*61046927SAndroid Build Coastguard Worker #include <getopt.h>
9*61046927SAndroid Build Coastguard Worker #include <stdint.h>
10*61046927SAndroid Build Coastguard Worker #include <stdio.h>
11*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
12*61046927SAndroid Build Coastguard Worker #include <string.h>
13*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #include "redump.h"
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker #include "adreno_common.xml.h"
20*61046927SAndroid Build Coastguard Worker #include "adreno_pm4.xml.h"
21*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker #include "a6xx.xml.h"
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker #include "ir3/ir3_assembler.h"
26*61046927SAndroid Build Coastguard Worker #include "ir3/ir3_compiler.h"
27*61046927SAndroid Build Coastguard Worker #include "ir3/ir3_shader.h"
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "util/list.h"
30*61046927SAndroid Build Coastguard Worker #include "util/vma.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker struct cmdstream {
33*61046927SAndroid Build Coastguard Worker    struct list_head link;
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker    uint32_t *mem;
36*61046927SAndroid Build Coastguard Worker    uint32_t total_size;
37*61046927SAndroid Build Coastguard Worker    uint32_t cur;
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker    uint64_t iova;
40*61046927SAndroid Build Coastguard Worker };
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker static uint64_t
cs_get_cur_iova(struct cmdstream * cs)43*61046927SAndroid Build Coastguard Worker cs_get_cur_iova(struct cmdstream *cs)
44*61046927SAndroid Build Coastguard Worker {
45*61046927SAndroid Build Coastguard Worker    return cs->iova + cs->cur * sizeof(uint32_t);
46*61046927SAndroid Build Coastguard Worker }
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker struct wrbuf {
49*61046927SAndroid Build Coastguard Worker    struct list_head link;
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker    uint64_t iova;
52*61046927SAndroid Build Coastguard Worker    uint64_t size;
53*61046927SAndroid Build Coastguard Worker    uint64_t clear;
54*61046927SAndroid Build Coastguard Worker    const char *name;
55*61046927SAndroid Build Coastguard Worker };
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker struct replay_context {
58*61046927SAndroid Build Coastguard Worker    void *mem_ctx;
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker    struct util_vma_heap vma;
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    struct cmdstream *submit_cs;
63*61046927SAndroid Build Coastguard Worker    struct cmdstream *state_cs;
64*61046927SAndroid Build Coastguard Worker    struct cmdstream *shader_cs;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    struct cmdstream *shader_log;
67*61046927SAndroid Build Coastguard Worker    struct cmdstream *cp_log;
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    struct list_head cs_list;
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker    struct list_head wrbuf_list;
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    struct ir3_compiler *compiler;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    struct hash_table_u64 *compiled_shaders;
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    const char *output_name;
78*61046927SAndroid Build Coastguard Worker };
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker static void
pkt(struct cmdstream * cs,uint32_t payload)81*61046927SAndroid Build Coastguard Worker pkt(struct cmdstream *cs, uint32_t payload)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker    assert(cs->cur <= cs->total_size);
84*61046927SAndroid Build Coastguard Worker    cs->mem[cs->cur++] = payload;
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker static void
pkt_qw(struct cmdstream * cs,uint64_t payload)88*61046927SAndroid Build Coastguard Worker pkt_qw(struct cmdstream *cs, uint64_t payload)
89*61046927SAndroid Build Coastguard Worker {
90*61046927SAndroid Build Coastguard Worker    pkt(cs, payload);
91*61046927SAndroid Build Coastguard Worker    pkt(cs, payload >> 32);
92*61046927SAndroid Build Coastguard Worker }
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker static uint64_t
pkt_blob(struct cmdstream * cs,void * payload,uint32_t size,uint32_t alignment)95*61046927SAndroid Build Coastguard Worker pkt_blob(struct cmdstream *cs, void *payload, uint32_t size, uint32_t alignment)
96*61046927SAndroid Build Coastguard Worker {
97*61046927SAndroid Build Coastguard Worker    cs->cur = align(cs->cur, alignment / sizeof(uint32_t));
98*61046927SAndroid Build Coastguard Worker    uint64_t start_iova = cs_get_cur_iova(cs);
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    memcpy(cs->mem + cs->cur, payload, size);
101*61046927SAndroid Build Coastguard Worker    cs->cur += size;
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    return start_iova;
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker static void
pkt4(struct cmdstream * cs,uint16_t regindx,uint16_t cnt,uint32_t payload)107*61046927SAndroid Build Coastguard Worker pkt4(struct cmdstream *cs, uint16_t regindx, uint16_t cnt, uint32_t payload)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker    pkt(cs, pm4_pkt4_hdr(regindx, cnt));
110*61046927SAndroid Build Coastguard Worker    pkt(cs, payload);
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker static void
pkt7(struct cmdstream * cs,uint8_t opcode,uint16_t cnt)114*61046927SAndroid Build Coastguard Worker pkt7(struct cmdstream *cs, uint8_t opcode, uint16_t cnt)
115*61046927SAndroid Build Coastguard Worker {
116*61046927SAndroid Build Coastguard Worker    pkt(cs, pm4_pkt7_hdr(opcode, cnt));
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker struct rd_section {
120*61046927SAndroid Build Coastguard Worker    uint32_t type;
121*61046927SAndroid Build Coastguard Worker    uint32_t size;
122*61046927SAndroid Build Coastguard Worker };
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker static struct cmdstream *
cs_alloc(struct replay_context * ctx,uint32_t size)125*61046927SAndroid Build Coastguard Worker cs_alloc(struct replay_context *ctx, uint32_t size)
126*61046927SAndroid Build Coastguard Worker {
127*61046927SAndroid Build Coastguard Worker    struct cmdstream *cs = (struct cmdstream *) calloc(1, sizeof(struct cmdstream));
128*61046927SAndroid Build Coastguard Worker    cs->mem = (uint32_t *)calloc(1, size);
129*61046927SAndroid Build Coastguard Worker    cs->total_size = size / sizeof(uint32_t);
130*61046927SAndroid Build Coastguard Worker    cs->cur = 0;
131*61046927SAndroid Build Coastguard Worker    cs->iova = util_vma_heap_alloc(&ctx->vma, size, 4096);
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker    assert(cs->iova != 0);
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    list_addtail(&cs->link, &ctx->cs_list);
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker    return cs;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker static void
rd_write_gpu_addr_section(FILE * out,struct cmdstream * cs,enum rd_sect_type section)141*61046927SAndroid Build Coastguard Worker rd_write_gpu_addr_section(FILE *out, struct cmdstream *cs, enum rd_sect_type section)
142*61046927SAndroid Build Coastguard Worker {
143*61046927SAndroid Build Coastguard Worker    const uint32_t packet[] = {(uint32_t)cs->iova,
144*61046927SAndroid Build Coastguard Worker                               (uint32_t)(cs->cur * sizeof(uint32_t)),
145*61046927SAndroid Build Coastguard Worker                               (uint32_t)(cs->iova >> 32)};
146*61046927SAndroid Build Coastguard Worker    struct rd_section section_address = {.type = section,
147*61046927SAndroid Build Coastguard Worker                                         .size = sizeof(packet)};
148*61046927SAndroid Build Coastguard Worker    fwrite(&section_address, sizeof(section_address), 1, out);
149*61046927SAndroid Build Coastguard Worker    fwrite(packet, sizeof(packet), 1, out);
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker static void
rd_write_cs_buffer(FILE * out,struct cmdstream * cs)153*61046927SAndroid Build Coastguard Worker rd_write_cs_buffer(FILE *out, struct cmdstream *cs)
154*61046927SAndroid Build Coastguard Worker {
155*61046927SAndroid Build Coastguard Worker    if (cs->cur == 0)
156*61046927SAndroid Build Coastguard Worker       return;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    rd_write_gpu_addr_section(out, cs, RD_GPUADDR);
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker    struct rd_section section_contents = {.type = RD_BUFFER_CONTENTS,
161*61046927SAndroid Build Coastguard Worker                                          .size = uint32_t(cs->cur * sizeof(uint32_t))};
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    fwrite(&section_contents, sizeof(section_contents), 1, out);
164*61046927SAndroid Build Coastguard Worker    fwrite(cs->mem, sizeof(uint32_t), cs->cur, out);
165*61046927SAndroid Build Coastguard Worker }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker static void
rd_write_cs_submit(FILE * out,struct cmdstream * cs)168*61046927SAndroid Build Coastguard Worker rd_write_cs_submit(FILE *out, struct cmdstream *cs)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker    const uint32_t packet[] = {(uint32_t)cs->iova, cs->cur,
171*61046927SAndroid Build Coastguard Worker                               (uint32_t)(cs->iova >> 32)};
172*61046927SAndroid Build Coastguard Worker    struct rd_section section_cmdstream = {.type = RD_CMDSTREAM_ADDR,
173*61046927SAndroid Build Coastguard Worker                                           .size = sizeof(packet)};
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    fwrite(&section_cmdstream, sizeof(section_cmdstream), 1, out);
176*61046927SAndroid Build Coastguard Worker    fwrite(packet, sizeof(packet), 1, out);
177*61046927SAndroid Build Coastguard Worker }
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker static void
rd_write_wrbuffer(FILE * out,struct wrbuf * wrbuf)180*61046927SAndroid Build Coastguard Worker rd_write_wrbuffer(FILE *out, struct wrbuf *wrbuf)
181*61046927SAndroid Build Coastguard Worker {
182*61046927SAndroid Build Coastguard Worker    uint32_t name_len = strlen(wrbuf->name) + 1;
183*61046927SAndroid Build Coastguard Worker    struct rd_section section = {.type = RD_WRBUFFER,
184*61046927SAndroid Build Coastguard Worker                                 .size = (uint32_t)(sizeof(uint64_t) * 3) + name_len};
185*61046927SAndroid Build Coastguard Worker    fwrite(&section, sizeof(section), 1, out);
186*61046927SAndroid Build Coastguard Worker    fwrite(&wrbuf->iova, sizeof(uint64_t), 1, out);
187*61046927SAndroid Build Coastguard Worker    fwrite(&wrbuf->size, sizeof(uint64_t), 1, out);
188*61046927SAndroid Build Coastguard Worker    fwrite(&wrbuf->clear, sizeof(uint64_t), 1, out);
189*61046927SAndroid Build Coastguard Worker    fwrite(wrbuf->name, sizeof(char), name_len, out);
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker static void
print_usage(const char * name)193*61046927SAndroid Build Coastguard Worker print_usage(const char *name)
194*61046927SAndroid Build Coastguard Worker {
195*61046927SAndroid Build Coastguard Worker    /* clang-format off */
196*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "Usage:\n\n"
197*61046927SAndroid Build Coastguard Worker            "\t%s [OPTIONS]... FILE...\n\n"
198*61046927SAndroid Build Coastguard Worker            "Options:\n"
199*61046927SAndroid Build Coastguard Worker            "\t    --vastart=offset\n"
200*61046927SAndroid Build Coastguard Worker            "\t    --vasize=size\n"
201*61046927SAndroid Build Coastguard Worker            "\t-h, --help             - show this message\n"
202*61046927SAndroid Build Coastguard Worker            , name);
203*61046927SAndroid Build Coastguard Worker    /* clang-format on */
204*61046927SAndroid Build Coastguard Worker    exit(2);
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker #define OPT_VA_START 1000
208*61046927SAndroid Build Coastguard Worker #define OPT_VA_SIZE  1001
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker /* clang-format off */
211*61046927SAndroid Build Coastguard Worker static const struct option opts[] = {
212*61046927SAndroid Build Coastguard Worker       { "vastart",  required_argument, 0, OPT_VA_START },
213*61046927SAndroid Build Coastguard Worker       { "vasize",   required_argument, 0, OPT_VA_SIZE },
214*61046927SAndroid Build Coastguard Worker       { "help",     no_argument,       0, 'h' },
215*61046927SAndroid Build Coastguard Worker };
216*61046927SAndroid Build Coastguard Worker /* clang-format on */
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker static void
replay_context_init(struct replay_context * ctx,struct fd_dev_id * dev_id,int argc,char ** argv)219*61046927SAndroid Build Coastguard Worker replay_context_init(struct replay_context *ctx, struct fd_dev_id *dev_id,
220*61046927SAndroid Build Coastguard Worker                     int argc, char **argv)
221*61046927SAndroid Build Coastguard Worker {
222*61046927SAndroid Build Coastguard Worker    uint64_t va_start = 0;
223*61046927SAndroid Build Coastguard Worker    uint64_t va_size = 0;
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker    int c;
226*61046927SAndroid Build Coastguard Worker    while ((c = getopt_long(argc, argv, "h", opts, NULL)) != -1) {
227*61046927SAndroid Build Coastguard Worker       switch (c) {
228*61046927SAndroid Build Coastguard Worker       case OPT_VA_START:
229*61046927SAndroid Build Coastguard Worker          va_start = strtoull(optarg, NULL, 0);
230*61046927SAndroid Build Coastguard Worker          break;
231*61046927SAndroid Build Coastguard Worker       case OPT_VA_SIZE:
232*61046927SAndroid Build Coastguard Worker          va_size = strtoull(optarg, NULL, 0);
233*61046927SAndroid Build Coastguard Worker          break;
234*61046927SAndroid Build Coastguard Worker       case 'h':
235*61046927SAndroid Build Coastguard Worker       default:
236*61046927SAndroid Build Coastguard Worker          print_usage(argv[0]);
237*61046927SAndroid Build Coastguard Worker       }
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker    if (optind < argc) {
241*61046927SAndroid Build Coastguard Worker       ctx->output_name = argv[optind];
242*61046927SAndroid Build Coastguard Worker    } else {
243*61046927SAndroid Build Coastguard Worker    }
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    if (!va_start || !va_size || !ctx->output_name) {
246*61046927SAndroid Build Coastguard Worker       print_usage(argv[0]);
247*61046927SAndroid Build Coastguard Worker       exit(1);
248*61046927SAndroid Build Coastguard Worker    }
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker    ctx->mem_ctx = ralloc_context(NULL);
251*61046927SAndroid Build Coastguard Worker    list_inithead(&ctx->cs_list);
252*61046927SAndroid Build Coastguard Worker    list_inithead(&ctx->wrbuf_list);
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker    util_vma_heap_init(&ctx->vma, va_start, ROUND_DOWN_TO(va_size, 4096));
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker    ctx->submit_cs = cs_alloc(ctx, 1024 * 1024);
257*61046927SAndroid Build Coastguard Worker    ctx->state_cs = cs_alloc(ctx, 2 * 1024 * 1024);
258*61046927SAndroid Build Coastguard Worker    ctx->shader_cs = cs_alloc(ctx, 8 * 1024 * 1024);
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker    ctx->shader_log = cs_alloc(ctx, 1024 * 1024);
261*61046927SAndroid Build Coastguard Worker    ctx->shader_log->mem[0] = (ctx->shader_log->iova & 0xffffffff) + sizeof(uint64_t);
262*61046927SAndroid Build Coastguard Worker    ctx->shader_log->mem[1] = ctx->shader_log->iova >> 32;
263*61046927SAndroid Build Coastguard Worker    ctx->shader_log->cur = ctx->shader_log->total_size;
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker    ctx->cp_log = cs_alloc(ctx, 8 * 1024 * 1024);
266*61046927SAndroid Build Coastguard Worker    ((uint64_t *)ctx->cp_log->mem)[0] = ctx->cp_log->iova + 2 * sizeof(uint64_t);
267*61046927SAndroid Build Coastguard Worker    ((uint64_t *)ctx->cp_log->mem)[1] = sizeof(uint64_t);
268*61046927SAndroid Build Coastguard Worker    ctx->cp_log->cur = ctx->cp_log->total_size;
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker    struct ir3_compiler_options options{
271*61046927SAndroid Build Coastguard Worker       .disable_cache = true,
272*61046927SAndroid Build Coastguard Worker    };
273*61046927SAndroid Build Coastguard Worker    ctx->compiler =
274*61046927SAndroid Build Coastguard Worker       ir3_compiler_create(NULL, dev_id, fd_dev_info_raw(dev_id), &options);
275*61046927SAndroid Build Coastguard Worker    ctx->compiled_shaders = _mesa_hash_table_u64_create(ctx->mem_ctx);
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker static void
replay_context_finish(struct replay_context * ctx)279*61046927SAndroid Build Coastguard Worker replay_context_finish(struct replay_context *ctx)
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker    FILE *out = fopen(ctx->output_name, "w");
282*61046927SAndroid Build Coastguard Worker    if (!out) {
283*61046927SAndroid Build Coastguard Worker       errx(1, "Cannot open '%s' for writing\n", ctx->output_name);
284*61046927SAndroid Build Coastguard Worker    }
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker    static const uint32_t gpu_id = 660;
287*61046927SAndroid Build Coastguard Worker    struct rd_section section_gpu_id = {.type = RD_GPU_ID,
288*61046927SAndroid Build Coastguard Worker                                        .size = 1 * sizeof(uint32_t)};
289*61046927SAndroid Build Coastguard Worker    fwrite(&section_gpu_id, sizeof(section_gpu_id), 1, out);
290*61046927SAndroid Build Coastguard Worker    fwrite(&gpu_id, sizeof(uint32_t), 1, out);
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker    rd_write_gpu_addr_section(out, ctx->shader_log, RD_SHADER_LOG_BUFFER);
293*61046927SAndroid Build Coastguard Worker    rd_write_gpu_addr_section(out, ctx->cp_log, RD_CP_LOG_BUFFER);
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    list_for_each_entry (struct cmdstream, cs, &ctx->cs_list, link) {
296*61046927SAndroid Build Coastguard Worker       rd_write_cs_buffer(out, cs);
297*61046927SAndroid Build Coastguard Worker    }
298*61046927SAndroid Build Coastguard Worker    rd_write_cs_submit(out, ctx->submit_cs);
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker    list_for_each_entry (struct wrbuf, wrbuf, &ctx->wrbuf_list, link) {
301*61046927SAndroid Build Coastguard Worker       rd_write_wrbuffer(out, wrbuf);
302*61046927SAndroid Build Coastguard Worker    }
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    fclose(out);
305*61046927SAndroid Build Coastguard Worker }
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker static void
upload_shader(struct replay_context * ctx,uint64_t id,const char * source)308*61046927SAndroid Build Coastguard Worker upload_shader(struct replay_context *ctx, uint64_t id, const char *source)
309*61046927SAndroid Build Coastguard Worker {
310*61046927SAndroid Build Coastguard Worker    FILE *in = fmemopen((void *)source, strlen(source), "r");
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker    struct ir3_kernel_info info = {
313*61046927SAndroid Build Coastguard Worker       .shader_print_buffer_iova = ctx->shader_log->iova,
314*61046927SAndroid Build Coastguard Worker    };
315*61046927SAndroid Build Coastguard Worker    struct ir3_shader *shader = ir3_parse_asm(ctx->compiler, &info, in);
316*61046927SAndroid Build Coastguard Worker    assert(shader);
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker    fclose(in);
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    uint64_t *shader_iova = ralloc(ctx->mem_ctx, uint64_t);
321*61046927SAndroid Build Coastguard Worker    *shader_iova = pkt_blob(ctx->shader_cs, shader->variants->bin,
322*61046927SAndroid Build Coastguard Worker                            shader->variants->info.size, 128);
323*61046927SAndroid Build Coastguard Worker    ralloc_free(shader);
324*61046927SAndroid Build Coastguard Worker 
325*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_u64_insert(ctx->compiled_shaders, id, shader_iova);
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker static void
emit_shader_iova(struct replay_context * ctx,struct cmdstream * cs,uint64_t id)329*61046927SAndroid Build Coastguard Worker emit_shader_iova(struct replay_context *ctx, struct cmdstream *cs, uint64_t id)
330*61046927SAndroid Build Coastguard Worker {
331*61046927SAndroid Build Coastguard Worker    uint64_t *shader_iova = (uint64_t *)
332*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_u64_search(ctx->compiled_shaders, id);
333*61046927SAndroid Build Coastguard Worker    if (shader_iova) {
334*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, *shader_iova);
335*61046927SAndroid Build Coastguard Worker    } else {
336*61046927SAndroid Build Coastguard Worker       fprintf(stderr,
337*61046927SAndroid Build Coastguard Worker               "Not override for shader at 0x%" PRIx64 ", using original\n", id);
338*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, id);
339*61046927SAndroid Build Coastguard Worker    }
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker #define begin_draw_state()                                                     \
343*61046927SAndroid Build Coastguard Worker    uint64_t subcs_iova_start = cs_get_cur_iova(ctx.state_cs);                  \
344*61046927SAndroid Build Coastguard Worker    struct cmdstream *prev_cs = cs;                                             \
345*61046927SAndroid Build Coastguard Worker    struct cmdstream *cs = ctx.state_cs;
346*61046927SAndroid Build Coastguard Worker 
347*61046927SAndroid Build Coastguard Worker #define end_draw_state(params)                                                 \
348*61046927SAndroid Build Coastguard Worker    uint64_t subcs_iova_end = cs_get_cur_iova(ctx.state_cs);                    \
349*61046927SAndroid Build Coastguard Worker    uint32_t subcs_size =                                                       \
350*61046927SAndroid Build Coastguard Worker       (subcs_iova_end - subcs_iova_start) / sizeof(uint32_t);                  \
351*61046927SAndroid Build Coastguard Worker    pkt7(prev_cs, CP_SET_DRAW_STATE, 3);                                        \
352*61046927SAndroid Build Coastguard Worker    pkt(prev_cs, (params) | subcs_size);                                        \
353*61046927SAndroid Build Coastguard Worker    pkt_qw(prev_cs, subcs_iova_start);
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker #define begin_ib()                                                             \
356*61046927SAndroid Build Coastguard Worker    struct cmdstream *prev_cs = cs;                                             \
357*61046927SAndroid Build Coastguard Worker    struct cmdstream *cs = cs_alloc(&ctx, 1024 * 1024);
358*61046927SAndroid Build Coastguard Worker 
359*61046927SAndroid Build Coastguard Worker #define end_ib()                                                               \
360*61046927SAndroid Build Coastguard Worker    uint64_t ibcs_size = cs->cur;                                               \
361*61046927SAndroid Build Coastguard Worker    pkt7(prev_cs, CP_INDIRECT_BUFFER, 3);                                       \
362*61046927SAndroid Build Coastguard Worker    pkt_qw(prev_cs, cs->iova);                                                  \
363*61046927SAndroid Build Coastguard Worker    pkt(prev_cs, ibcs_size);
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker static void
gpu_print(struct replay_context * ctx,struct cmdstream * _cs,uint64_t iova,uint32_t dwords)366*61046927SAndroid Build Coastguard Worker gpu_print(struct replay_context *ctx, struct cmdstream *_cs, uint64_t iova,
367*61046927SAndroid Build Coastguard Worker           uint32_t dwords)
368*61046927SAndroid Build Coastguard Worker {
369*61046927SAndroid Build Coastguard Worker    uint64_t header_iova, body_iova;
370*61046927SAndroid Build Coastguard Worker    struct cmdstream *prev_cs = _cs;
371*61046927SAndroid Build Coastguard Worker    struct cmdstream *cs = cs_alloc(ctx, 4096);
372*61046927SAndroid Build Coastguard Worker    /* Commands that are being modified should be in a separate cmdstream,
373*61046927SAndroid Build Coastguard Worker     * otherwise they would be prefetched and writes would not be visible.
374*61046927SAndroid Build Coastguard Worker     */
375*61046927SAndroid Build Coastguard Worker    {
376*61046927SAndroid Build Coastguard Worker       /* Write size into entry's header */
377*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_MEM_WRITE, 4);
378*61046927SAndroid Build Coastguard Worker       header_iova = cs_get_cur_iova(cs);
379*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, 0xdeadbeef);
380*61046927SAndroid Build Coastguard Worker       uint64_t size_iova = cs_get_cur_iova(cs);
381*61046927SAndroid Build Coastguard Worker       pkt(cs, dwords * 4);
382*61046927SAndroid Build Coastguard Worker       pkt(cs, 0);
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker       /* Copy the data into entry's body */
385*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_MEMCPY, 5);
386*61046927SAndroid Build Coastguard Worker       pkt(cs, dwords);
387*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, iova);
388*61046927SAndroid Build Coastguard Worker       body_iova = cs_get_cur_iova(cs);
389*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, 0xdeadbeef);
390*61046927SAndroid Build Coastguard Worker 
391*61046927SAndroid Build Coastguard Worker       /* iova = iova + body_size + header_size */
392*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_MEM_TO_MEM, 9);
393*61046927SAndroid Build Coastguard Worker       pkt(cs, CP_MEM_TO_MEM_0_DOUBLE | CP_MEM_TO_MEM_0_WAIT_FOR_MEM_WRITES);
394*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova);
395*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova);
396*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, size_iova);
397*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova + sizeof(uint64_t));
398*61046927SAndroid Build Coastguard Worker    }
399*61046927SAndroid Build Coastguard Worker 
400*61046927SAndroid Build Coastguard Worker    {
401*61046927SAndroid Build Coastguard Worker       struct cmdstream *cs = prev_cs;
402*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_MEM_TO_MEM, 5);
403*61046927SAndroid Build Coastguard Worker       pkt(cs, CP_MEM_TO_MEM_0_DOUBLE | CP_MEM_TO_MEM_0_WAIT_FOR_MEM_WRITES);
404*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, header_iova);
405*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova);
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_MEM_TO_MEM, 7);
408*61046927SAndroid Build Coastguard Worker       pkt(cs, CP_MEM_TO_MEM_0_DOUBLE);
409*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, body_iova);
410*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova);
411*61046927SAndroid Build Coastguard Worker       pkt_qw(cs, ctx->cp_log->iova + sizeof(uint64_t));
412*61046927SAndroid Build Coastguard Worker 
413*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_WAIT_MEM_WRITES, 0);
414*61046927SAndroid Build Coastguard Worker       pkt7(cs, CP_WAIT_FOR_ME, 0);
415*61046927SAndroid Build Coastguard Worker    }
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker    end_ib();
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker /* This function is used to read a buffer from the GPU into a file.
421*61046927SAndroid Build Coastguard Worker  * The buffer can optionally be cleared to 0xdeadbeef at the start
422*61046927SAndroid Build Coastguard Worker  * of the cmdstream by setting the clear parameter to true.
423*61046927SAndroid Build Coastguard Worker  *
424*61046927SAndroid Build Coastguard Worker  * Note: Unlike gpu_print, this function isn't sequenced, it will
425*61046927SAndroid Build Coastguard Worker  * read the state of the buffer at the end of the cmdstream, not
426*61046927SAndroid Build Coastguard Worker  * at the point of the call.
427*61046927SAndroid Build Coastguard Worker  */
428*61046927SAndroid Build Coastguard Worker static void
gpu_read_into_file(struct replay_context * ctx,struct cmdstream * _cs,uint64_t iova,uint64_t size,bool clear,const char * name)429*61046927SAndroid Build Coastguard Worker gpu_read_into_file(struct replay_context *ctx, struct cmdstream *_cs,
430*61046927SAndroid Build Coastguard Worker                     uint64_t iova, uint64_t size, bool clear, const char *name)
431*61046927SAndroid Build Coastguard Worker {
432*61046927SAndroid Build Coastguard Worker    struct wrbuf *wrbuf = (struct wrbuf *) calloc(1, sizeof(struct wrbuf));
433*61046927SAndroid Build Coastguard Worker    wrbuf->iova = iova;
434*61046927SAndroid Build Coastguard Worker    wrbuf->size = size;
435*61046927SAndroid Build Coastguard Worker    wrbuf->clear = clear;
436*61046927SAndroid Build Coastguard Worker    wrbuf->name = strdup(name);
437*61046927SAndroid Build Coastguard Worker 
438*61046927SAndroid Build Coastguard Worker    assert(wrbuf->iova != 0);
439*61046927SAndroid Build Coastguard Worker 
440*61046927SAndroid Build Coastguard Worker    list_addtail(&wrbuf->link, &ctx->wrbuf_list);
441*61046927SAndroid Build Coastguard Worker }