xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/radeonsi/si_debug.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "ac_debug.h"
8 #include "ac_rtld.h"
9 #include "driver_ddebug/dd_util.h"
10 #include "si_pipe.h"
11 #include "sid.h"
12 #include "sid_tables.h"
13 #include "tgsi/tgsi_from_mesa.h"
14 #include "util/u_dump.h"
15 #include "util/u_log.h"
16 #include "util/u_memory.h"
17 #include "util/u_process.h"
18 #include "util/u_string.h"
19 
20 static void si_dump_bo_list(struct si_context *sctx, const struct radeon_saved_cs *saved, FILE *f);
21 
22 DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL)
23 
si_get_context_ip_type(struct si_context * sctx)24 static enum amd_ip_type si_get_context_ip_type(struct si_context *sctx)
25 {
26    return sctx->has_graphics ? AMD_IP_GFX : AMD_IP_COMPUTE;
27 }
28 
29 /**
30  * Store a linearized copy of all chunks of \p cs together with the buffer
31  * list in \p saved.
32  */
si_save_cs(struct radeon_winsys * ws,struct radeon_cmdbuf * cs,struct radeon_saved_cs * saved,bool get_buffer_list)33 void si_save_cs(struct radeon_winsys *ws, struct radeon_cmdbuf *cs, struct radeon_saved_cs *saved,
34                 bool get_buffer_list)
35 {
36    uint32_t *buf;
37    unsigned i;
38 
39    /* Save the IB chunks. */
40    saved->num_dw = cs->prev_dw + cs->current.cdw;
41    saved->ib = MALLOC(4 * saved->num_dw);
42    if (!saved->ib)
43       goto oom;
44 
45    buf = saved->ib;
46    for (i = 0; i < cs->num_prev; ++i) {
47       memcpy(buf, cs->prev[i].buf, cs->prev[i].cdw * 4);
48       buf += cs->prev[i].cdw;
49    }
50    memcpy(buf, cs->current.buf, cs->current.cdw * 4);
51 
52    if (!get_buffer_list)
53       return;
54 
55    /* Save the buffer list. */
56    saved->bo_count = ws->cs_get_buffer_list(cs, NULL);
57    saved->bo_list = CALLOC(saved->bo_count, sizeof(saved->bo_list[0]));
58    if (!saved->bo_list) {
59       FREE(saved->ib);
60       goto oom;
61    }
62    ws->cs_get_buffer_list(cs, saved->bo_list);
63 
64    return;
65 
66 oom:
67    fprintf(stderr, "%s: out of memory\n", __func__);
68    memset(saved, 0, sizeof(*saved));
69 }
70 
si_clear_saved_cs(struct radeon_saved_cs * saved)71 void si_clear_saved_cs(struct radeon_saved_cs *saved)
72 {
73    FREE(saved->ib);
74    FREE(saved->bo_list);
75 
76    memset(saved, 0, sizeof(*saved));
77 }
78 
si_destroy_saved_cs(struct si_saved_cs * scs)79 void si_destroy_saved_cs(struct si_saved_cs *scs)
80 {
81    si_clear_saved_cs(&scs->gfx);
82    si_resource_reference(&scs->trace_buf, NULL);
83    free(scs);
84 }
85 
si_dump_shader(struct si_screen * sscreen,struct si_shader * shader,FILE * f)86 static void si_dump_shader(struct si_screen *sscreen, struct si_shader *shader, FILE *f)
87 {
88    if (shader->shader_log)
89       fwrite(shader->shader_log, shader->shader_log_size, 1, f);
90    else
91       si_shader_dump(sscreen, shader, NULL, f, false);
92 
93    if (shader->bo && sscreen->options.dump_shader_binary) {
94       unsigned size = shader->bo->b.b.width0;
95       fprintf(f, "BO: VA=%" PRIx64 " Size=%u\n", shader->bo->gpu_address, size);
96 
97       const char *mapped = sscreen->ws->buffer_map(sscreen->ws,
98          shader->bo->buf, NULL,
99          PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_READ | RADEON_MAP_TEMPORARY);
100 
101       for (unsigned i = 0; i < size; i += 4) {
102          fprintf(f, " %4x: %08x\n", i, *(uint32_t *)(mapped + i));
103       }
104 
105       sscreen->ws->buffer_unmap(sscreen->ws, shader->bo->buf);
106 
107       fprintf(f, "\n");
108    }
109 }
110 
111 struct si_log_chunk_shader {
112    /* The shader destroy code assumes a current context for unlinking of
113     * PM4 packets etc.
114     *
115     * While we should be able to destroy shaders without a context, doing
116     * so would happen only very rarely and be therefore likely to fail
117     * just when you're trying to debug something. Let's just remember the
118     * current context in the chunk.
119     */
120    struct si_context *ctx;
121    struct si_shader *shader;
122 
123    /* For keep-alive reference counts */
124    struct si_shader_selector *sel;
125    struct si_compute *program;
126 };
127 
si_log_chunk_shader_destroy(void * data)128 static void si_log_chunk_shader_destroy(void *data)
129 {
130    struct si_log_chunk_shader *chunk = data;
131    si_shader_selector_reference(chunk->ctx, &chunk->sel, NULL);
132    si_compute_reference(&chunk->program, NULL);
133    FREE(chunk);
134 }
135 
si_log_chunk_shader_print(void * data,FILE * f)136 static void si_log_chunk_shader_print(void *data, FILE *f)
137 {
138    struct si_log_chunk_shader *chunk = data;
139    struct si_screen *sscreen = chunk->ctx->screen;
140    si_dump_shader(sscreen, chunk->shader, f);
141 }
142 
143 static struct u_log_chunk_type si_log_chunk_type_shader = {
144    .destroy = si_log_chunk_shader_destroy,
145    .print = si_log_chunk_shader_print,
146 };
147 
si_dump_gfx_shader(struct si_context * ctx,const struct si_shader_ctx_state * state,struct u_log_context * log)148 static void si_dump_gfx_shader(struct si_context *ctx, const struct si_shader_ctx_state *state,
149                                struct u_log_context *log)
150 {
151    struct si_shader *current = state->current;
152 
153    if (!state->cso || !current)
154       return;
155 
156    struct si_log_chunk_shader *chunk = CALLOC_STRUCT(si_log_chunk_shader);
157    chunk->ctx = ctx;
158    chunk->shader = current;
159    si_shader_selector_reference(ctx, &chunk->sel, current->selector);
160    u_log_chunk(log, &si_log_chunk_type_shader, chunk);
161 }
162 
si_dump_compute_shader(struct si_context * ctx,struct u_log_context * log)163 static void si_dump_compute_shader(struct si_context *ctx, struct u_log_context *log)
164 {
165    const struct si_cs_shader_state *state = &ctx->cs_shader_state;
166 
167    if (!state->program)
168       return;
169 
170    struct si_log_chunk_shader *chunk = CALLOC_STRUCT(si_log_chunk_shader);
171    chunk->ctx = ctx;
172    chunk->shader = &state->program->shader;
173    si_compute_reference(&chunk->program, state->program);
174    u_log_chunk(log, &si_log_chunk_type_shader, chunk);
175 }
176 
177 /**
178  * Shader compiles can be overridden with arbitrary ELF objects by setting
179  * the environment variable RADEON_REPLACE_SHADERS=num1:filename1[;num2:filename2]
180  *
181  * TODO: key this off some hash
182  */
si_replace_shader(unsigned num,struct si_shader_binary * binary)183 bool si_replace_shader(unsigned num, struct si_shader_binary *binary)
184 {
185    const char *p = debug_get_option_replace_shaders();
186    const char *semicolon;
187    char *copy = NULL;
188    FILE *f;
189    long filesize, nread;
190    bool replaced = false;
191 
192    if (!p)
193       return false;
194 
195    while (*p) {
196       unsigned long i;
197       char *endp;
198       i = strtoul(p, &endp, 0);
199 
200       p = endp;
201       if (*p != ':') {
202          fprintf(stderr, "RADEON_REPLACE_SHADERS formatted badly.\n");
203          exit(1);
204       }
205       ++p;
206 
207       if (i == num)
208          break;
209 
210       p = strchr(p, ';');
211       if (!p)
212          return false;
213       ++p;
214    }
215    if (!*p)
216       return false;
217 
218    semicolon = strchr(p, ';');
219    if (semicolon) {
220       p = copy = strndup(p, semicolon - p);
221       if (!copy) {
222          fprintf(stderr, "out of memory\n");
223          return false;
224       }
225    }
226 
227    fprintf(stderr, "radeonsi: replace shader %u by %s\n", num, p);
228 
229    f = fopen(p, "r");
230    if (!f) {
231       perror("radeonsi: failed to open file");
232       goto out_free;
233    }
234 
235    if (fseek(f, 0, SEEK_END) != 0)
236       goto file_error;
237 
238    filesize = ftell(f);
239    if (filesize < 0)
240       goto file_error;
241 
242    if (fseek(f, 0, SEEK_SET) != 0)
243       goto file_error;
244 
245    binary->code_buffer = MALLOC(filesize);
246    if (!binary->code_buffer) {
247       fprintf(stderr, "out of memory\n");
248       goto out_close;
249    }
250 
251    nread = fread((void *)binary->code_buffer, 1, filesize, f);
252    if (nread != filesize) {
253       FREE((void *)binary->code_buffer);
254       binary->code_buffer = NULL;
255       goto file_error;
256    }
257 
258    binary->type = SI_SHADER_BINARY_ELF;
259    binary->code_size = nread;
260    replaced = true;
261 
262 out_close:
263    fclose(f);
264 out_free:
265    free(copy);
266    return replaced;
267 
268 file_error:
269    perror("radeonsi: reading shader");
270    goto out_close;
271 }
272 
273 /* Parsed IBs are difficult to read without colors. Use "less -R file" to
274  * read them, or use "aha -b -f file" to convert them to html.
275  */
276 #define COLOR_RESET  "\033[0m"
277 #define COLOR_RED    "\033[31m"
278 #define COLOR_GREEN  "\033[1;32m"
279 #define COLOR_YELLOW "\033[1;33m"
280 #define COLOR_CYAN   "\033[1;36m"
281 
si_dump_mmapped_reg(struct si_context * sctx,FILE * f,unsigned offset)282 static void si_dump_mmapped_reg(struct si_context *sctx, FILE *f, unsigned offset)
283 {
284    struct radeon_winsys *ws = sctx->ws;
285    uint32_t value;
286 
287    if (ws->read_registers(ws, offset, 1, &value))
288       ac_dump_reg(f, sctx->gfx_level, sctx->family, offset, value, ~0);
289 }
290 
si_dump_debug_registers(struct si_context * sctx,FILE * f)291 static void si_dump_debug_registers(struct si_context *sctx, FILE *f)
292 {
293    fprintf(f, "Memory-mapped registers:\n");
294    si_dump_mmapped_reg(sctx, f, R_008010_GRBM_STATUS);
295 
296    /* No other registers can be read on radeon. */
297    if (!sctx->screen->info.is_amdgpu) {
298       fprintf(f, "\n");
299       return;
300    }
301 
302    si_dump_mmapped_reg(sctx, f, R_008008_GRBM_STATUS2);
303    si_dump_mmapped_reg(sctx, f, R_008014_GRBM_STATUS_SE0);
304    si_dump_mmapped_reg(sctx, f, R_008018_GRBM_STATUS_SE1);
305    si_dump_mmapped_reg(sctx, f, R_008038_GRBM_STATUS_SE2);
306    si_dump_mmapped_reg(sctx, f, R_00803C_GRBM_STATUS_SE3);
307    si_dump_mmapped_reg(sctx, f, R_00D034_SDMA0_STATUS_REG);
308    si_dump_mmapped_reg(sctx, f, R_00D834_SDMA1_STATUS_REG);
309    if (sctx->gfx_level <= GFX8) {
310       si_dump_mmapped_reg(sctx, f, R_000E50_SRBM_STATUS);
311       si_dump_mmapped_reg(sctx, f, R_000E4C_SRBM_STATUS2);
312       si_dump_mmapped_reg(sctx, f, R_000E54_SRBM_STATUS3);
313    }
314    si_dump_mmapped_reg(sctx, f, R_008680_CP_STAT);
315    si_dump_mmapped_reg(sctx, f, R_008674_CP_STALLED_STAT1);
316    si_dump_mmapped_reg(sctx, f, R_008678_CP_STALLED_STAT2);
317    si_dump_mmapped_reg(sctx, f, R_008670_CP_STALLED_STAT3);
318    si_dump_mmapped_reg(sctx, f, R_008210_CP_CPC_STATUS);
319    si_dump_mmapped_reg(sctx, f, R_008214_CP_CPC_BUSY_STAT);
320    si_dump_mmapped_reg(sctx, f, R_008218_CP_CPC_STALLED_STAT1);
321    si_dump_mmapped_reg(sctx, f, R_00821C_CP_CPF_STATUS);
322    si_dump_mmapped_reg(sctx, f, R_008220_CP_CPF_BUSY_STAT);
323    si_dump_mmapped_reg(sctx, f, R_008224_CP_CPF_STALLED_STAT1);
324    fprintf(f, "\n");
325 }
326 
327 struct si_log_chunk_cs {
328    struct si_context *ctx;
329    struct si_saved_cs *cs;
330    enum amd_ip_type ip_type;
331    bool dump_bo_list;
332    unsigned gfx_begin, gfx_end;
333 };
334 
si_log_chunk_type_cs_destroy(void * data)335 static void si_log_chunk_type_cs_destroy(void *data)
336 {
337    struct si_log_chunk_cs *chunk = data;
338    si_saved_cs_reference(&chunk->cs, NULL);
339    free(chunk);
340 }
341 
si_parse_current_ib(FILE * f,struct radeon_cmdbuf * cs,unsigned begin,unsigned end,int * last_trace_id,unsigned trace_id_count,enum amd_ip_type ip_type,enum amd_gfx_level gfx_level,enum radeon_family family)342 static void si_parse_current_ib(FILE *f, struct radeon_cmdbuf *cs, unsigned begin, unsigned end,
343                                 int *last_trace_id, unsigned trace_id_count,
344                                 enum amd_ip_type ip_type, enum amd_gfx_level gfx_level,
345                                 enum radeon_family family)
346 {
347    unsigned orig_end = end;
348    const char *ip_name = ac_get_ip_type_string(NULL, ip_type);
349 
350    assert(begin <= end);
351 
352    fprintf(f, "------------------ %s begin (dw = %u) ------------------\n", ip_name, begin);
353 
354    for (unsigned prev_idx = 0; prev_idx < cs->num_prev; ++prev_idx) {
355       struct radeon_cmdbuf_chunk *chunk = &cs->prev[prev_idx];
356 
357       if (begin < chunk->cdw) {
358          struct ac_ib_parser ib_parser = {
359             .f = f,
360             .ib = chunk->buf + begin,
361             .num_dw = MIN2(end, chunk->cdw) - begin,
362             .trace_ids = last_trace_id,
363             .trace_id_count = trace_id_count,
364             .gfx_level = gfx_level,
365             .family = family,
366             .ip_type = ip_type,
367          };
368 
369          ac_parse_ib_chunk(&ib_parser);
370       }
371 
372       if (end <= chunk->cdw)
373          return;
374 
375       if (begin < chunk->cdw)
376          fprintf(f, "\n---------- %s next chunk ----------\n\n", ip_name);
377 
378       begin -= MIN2(begin, chunk->cdw);
379       end -= chunk->cdw;
380    }
381 
382    assert(end <= cs->current.cdw);
383 
384    struct ac_ib_parser ib_parser = {
385       .f = f,
386       .ib = cs->current.buf + begin,
387       .num_dw = end - begin,
388       .trace_ids = last_trace_id,
389       .trace_id_count = trace_id_count,
390       .gfx_level = gfx_level,
391       .family = family,
392       .ip_type = ip_type,
393    };
394 
395    ac_parse_ib_chunk(&ib_parser);
396 
397    fprintf(f, "------------------- %s end (dw = %u) -------------------\n\n", ip_name, orig_end);
398 }
399 
si_print_current_ib(struct si_context * sctx,FILE * f)400 void si_print_current_ib(struct si_context *sctx, FILE *f)
401 {
402    si_parse_current_ib(f, &sctx->gfx_cs, 0, sctx->gfx_cs.prev_dw + sctx->gfx_cs.current.cdw,
403                        NULL, 0, si_get_context_ip_type(sctx), sctx->gfx_level,
404                        sctx->family);
405 }
406 
si_log_chunk_type_cs_print(void * data,FILE * f)407 static void si_log_chunk_type_cs_print(void *data, FILE *f)
408 {
409    struct si_log_chunk_cs *chunk = data;
410    struct si_context *ctx = chunk->ctx;
411    struct si_saved_cs *scs = chunk->cs;
412    int last_trace_id = -1;
413 
414    /* We are expecting that the ddebug pipe has already
415     * waited for the context, so this buffer should be idle.
416     * If the GPU is hung, there is no point in waiting for it.
417     */
418    uint32_t *map = ctx->ws->buffer_map(ctx->ws, scs->trace_buf->buf, NULL,
419                                        PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_READ);
420    if (map)
421       last_trace_id = map[0];
422 
423    if (chunk->gfx_end != chunk->gfx_begin) {
424       if (scs->flushed) {
425          struct ac_ib_parser ib_parser = {
426             .f = f,
427             .ib = scs->gfx.ib + chunk->gfx_begin,
428             .num_dw = chunk->gfx_end - chunk->gfx_begin,
429             .trace_ids = &last_trace_id,
430             .trace_id_count = map ? 1 : 0,
431             .gfx_level = ctx->gfx_level,
432             .family = ctx->family,
433             .ip_type = chunk->ip_type,
434          };
435 
436          ac_parse_ib(&ib_parser, "IB");
437       } else {
438          si_parse_current_ib(f, &ctx->gfx_cs, chunk->gfx_begin, chunk->gfx_end, &last_trace_id,
439                              map ? 1 : 0, chunk->ip_type, ctx->gfx_level, ctx->family);
440       }
441    }
442 
443    if (chunk->dump_bo_list) {
444       fprintf(f, "Flushing. Time: ");
445       util_dump_ns(f, scs->time_flush);
446       fprintf(f, "\n\n");
447       si_dump_bo_list(ctx, &scs->gfx, f);
448    }
449 }
450 
451 static const struct u_log_chunk_type si_log_chunk_type_cs = {
452    .destroy = si_log_chunk_type_cs_destroy,
453    .print = si_log_chunk_type_cs_print,
454 };
455 
si_log_cs(struct si_context * ctx,struct u_log_context * log,bool dump_bo_list)456 static void si_log_cs(struct si_context *ctx, struct u_log_context *log, bool dump_bo_list)
457 {
458    assert(ctx->current_saved_cs);
459 
460    struct si_saved_cs *scs = ctx->current_saved_cs;
461    unsigned gfx_cur = ctx->gfx_cs.prev_dw + ctx->gfx_cs.current.cdw;
462 
463    if (!dump_bo_list && gfx_cur == scs->gfx_last_dw)
464       return;
465 
466    struct si_log_chunk_cs *chunk = calloc(1, sizeof(*chunk));
467 
468    chunk->ctx = ctx;
469    si_saved_cs_reference(&chunk->cs, scs);
470    chunk->ip_type = si_get_context_ip_type(ctx);
471    chunk->dump_bo_list = dump_bo_list;
472 
473    chunk->gfx_begin = scs->gfx_last_dw;
474    chunk->gfx_end = gfx_cur;
475    scs->gfx_last_dw = gfx_cur;
476 
477    u_log_chunk(log, &si_log_chunk_type_cs, chunk);
478 }
479 
si_auto_log_cs(void * data,struct u_log_context * log)480 void si_auto_log_cs(void *data, struct u_log_context *log)
481 {
482    struct si_context *ctx = (struct si_context *)data;
483    si_log_cs(ctx, log, false);
484 }
485 
si_log_hw_flush(struct si_context * sctx)486 void si_log_hw_flush(struct si_context *sctx)
487 {
488    if (!sctx->log)
489       return;
490 
491    si_log_cs(sctx, sctx->log, true);
492 
493    if (sctx->context_flags & SI_CONTEXT_FLAG_AUX) {
494       /* The aux context isn't captured by the ddebug wrapper,
495        * so we dump it on a flush-by-flush basis here.
496        */
497       FILE *f = dd_get_debug_file(false);
498       if (!f) {
499          fprintf(stderr, "radeonsi: error opening aux context dump file.\n");
500       } else {
501          dd_write_header(f, &sctx->screen->b, 0);
502 
503          fprintf(f, "Aux context dump:\n\n");
504          u_log_new_page_print(sctx->log, f);
505 
506          fclose(f);
507       }
508    }
509 }
510 
priority_to_string(unsigned priority)511 static const char *priority_to_string(unsigned priority)
512 {
513 #define ITEM(x) if (priority == RADEON_PRIO_##x) return #x
514    ITEM(FENCE_TRACE);
515    ITEM(SO_FILLED_SIZE);
516    ITEM(QUERY);
517    ITEM(IB);
518    ITEM(DRAW_INDIRECT);
519    ITEM(INDEX_BUFFER);
520    ITEM(CP_DMA);
521    ITEM(BORDER_COLORS);
522    ITEM(CONST_BUFFER);
523    ITEM(DESCRIPTORS);
524    ITEM(SAMPLER_BUFFER);
525    ITEM(VERTEX_BUFFER);
526    ITEM(SHADER_RW_BUFFER);
527    ITEM(SAMPLER_TEXTURE);
528    ITEM(SHADER_RW_IMAGE);
529    ITEM(SAMPLER_TEXTURE_MSAA);
530    ITEM(COLOR_BUFFER);
531    ITEM(DEPTH_BUFFER);
532    ITEM(COLOR_BUFFER_MSAA);
533    ITEM(DEPTH_BUFFER_MSAA);
534    ITEM(SEPARATE_META);
535    ITEM(SHADER_BINARY);
536    ITEM(SHADER_RINGS);
537    ITEM(SCRATCH_BUFFER);
538 #undef ITEM
539 
540    return "";
541 }
542 
bo_list_compare_va(const struct radeon_bo_list_item * a,const struct radeon_bo_list_item * b)543 static int bo_list_compare_va(const struct radeon_bo_list_item *a,
544                               const struct radeon_bo_list_item *b)
545 {
546    return a->vm_address < b->vm_address ? -1 : a->vm_address > b->vm_address ? 1 : 0;
547 }
548 
si_dump_bo_list(struct si_context * sctx,const struct radeon_saved_cs * saved,FILE * f)549 static void si_dump_bo_list(struct si_context *sctx, const struct radeon_saved_cs *saved, FILE *f)
550 {
551    unsigned i, j;
552 
553    if (!saved->bo_list)
554       return;
555 
556    /* Sort the list according to VM addresses first. */
557    qsort(saved->bo_list, saved->bo_count, sizeof(saved->bo_list[0]), (void *)bo_list_compare_va);
558 
559    fprintf(f, "Buffer list (in units of pages = 4kB):\n" COLOR_YELLOW
560               "        Size    VM start page         "
561               "VM end page           Usage" COLOR_RESET "\n");
562 
563    for (i = 0; i < saved->bo_count; i++) {
564       /* Note: Buffer sizes are expected to be aligned to 4k by the winsys. */
565       const unsigned page_size = sctx->screen->info.gart_page_size;
566       uint64_t va = saved->bo_list[i].vm_address;
567       uint64_t size = saved->bo_list[i].bo_size;
568       bool hit = false;
569 
570       /* If there's unused virtual memory between 2 buffers, print it. */
571       if (i) {
572          uint64_t previous_va_end =
573             saved->bo_list[i - 1].vm_address + saved->bo_list[i - 1].bo_size;
574 
575          if (va > previous_va_end) {
576             fprintf(f, "  %10" PRIu64 "    -- hole --\n", (va - previous_va_end) / page_size);
577          }
578       }
579 
580       /* Print the buffer. */
581       fprintf(f, "  %10" PRIu64 "    0x%013" PRIX64 "       0x%013" PRIX64 "       ",
582               size / page_size, va / page_size, (va + size) / page_size);
583 
584       /* Print the usage. */
585       for (j = 0; j < 32; j++) {
586          if (!(saved->bo_list[i].priority_usage & (1u << j)))
587             continue;
588 
589          fprintf(f, "%s%s", !hit ? "" : ", ", priority_to_string(1u << j));
590          hit = true;
591       }
592       fprintf(f, "\n");
593    }
594    fprintf(f, "\nNote: The holes represent memory not used by the IB.\n"
595               "      Other buffers can still be allocated there.\n\n");
596 }
597 
si_dump_framebuffer(struct si_context * sctx,struct u_log_context * log)598 static void si_dump_framebuffer(struct si_context *sctx, struct u_log_context *log)
599 {
600    struct pipe_framebuffer_state *state = &sctx->framebuffer.state;
601    struct si_texture *tex;
602    int i;
603 
604    for (i = 0; i < state->nr_cbufs; i++) {
605       if (!state->cbufs[i])
606          continue;
607 
608       tex = (struct si_texture *)state->cbufs[i]->texture;
609       u_log_printf(log, COLOR_YELLOW "Color buffer %i:" COLOR_RESET "\n", i);
610       si_print_texture_info(sctx->screen, tex, log);
611       u_log_printf(log, "\n");
612    }
613 
614    if (state->zsbuf) {
615       tex = (struct si_texture *)state->zsbuf->texture;
616       u_log_printf(log, COLOR_YELLOW "Depth-stencil buffer:" COLOR_RESET "\n");
617       si_print_texture_info(sctx->screen, tex, log);
618       u_log_printf(log, "\n");
619    }
620 }
621 
622 typedef unsigned (*slot_remap_func)(unsigned);
623 
624 struct si_log_chunk_desc_list {
625    /** Pointer to memory map of buffer where the list is uploader */
626    uint32_t *gpu_list;
627    /** Reference of buffer where the list is uploaded, so that gpu_list
628     * is kept live. */
629    struct si_resource *buf;
630 
631    const char *shader_name;
632    const char *elem_name;
633    slot_remap_func slot_remap;
634    enum amd_gfx_level gfx_level;
635    enum radeon_family family;
636    unsigned element_dw_size;
637    unsigned num_elements;
638 
639    uint32_t list[0];
640 };
641 
si_log_chunk_desc_list_destroy(void * data)642 static void si_log_chunk_desc_list_destroy(void *data)
643 {
644    struct si_log_chunk_desc_list *chunk = data;
645    si_resource_reference(&chunk->buf, NULL);
646    FREE(chunk);
647 }
648 
si_log_chunk_desc_list_print(void * data,FILE * f)649 static void si_log_chunk_desc_list_print(void *data, FILE *f)
650 {
651    struct si_log_chunk_desc_list *chunk = data;
652    unsigned sq_img_rsrc_word0 =
653       chunk->gfx_level >= GFX10 ? R_00A000_SQ_IMG_RSRC_WORD0 : R_008F10_SQ_IMG_RSRC_WORD0;
654 
655    for (unsigned i = 0; i < chunk->num_elements; i++) {
656       unsigned cpu_dw_offset = i * chunk->element_dw_size;
657       unsigned gpu_dw_offset = chunk->slot_remap(i) * chunk->element_dw_size;
658       const char *list_note = chunk->gpu_list ? "GPU list" : "CPU list";
659       uint32_t *cpu_list = chunk->list + cpu_dw_offset;
660       uint32_t *gpu_list = chunk->gpu_list ? chunk->gpu_list + gpu_dw_offset : cpu_list;
661 
662       fprintf(f, COLOR_GREEN "%s%s slot %u (%s):" COLOR_RESET "\n", chunk->shader_name,
663               chunk->elem_name, i, list_note);
664 
665       switch (chunk->element_dw_size) {
666       case 4:
667          for (unsigned j = 0; j < 4; j++)
668             ac_dump_reg(f, chunk->gfx_level, chunk->family,
669                         R_008F00_SQ_BUF_RSRC_WORD0 + j * 4, gpu_list[j], 0xffffffff);
670          break;
671       case 8:
672          for (unsigned j = 0; j < 8; j++)
673             ac_dump_reg(f, chunk->gfx_level, chunk->family,
674                         sq_img_rsrc_word0 + j * 4, gpu_list[j], 0xffffffff);
675 
676          fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
677          for (unsigned j = 0; j < 4; j++)
678             ac_dump_reg(f, chunk->gfx_level, chunk->family,
679                         R_008F00_SQ_BUF_RSRC_WORD0 + j * 4, gpu_list[4 + j], 0xffffffff);
680          break;
681       case 16:
682          for (unsigned j = 0; j < 8; j++)
683             ac_dump_reg(f, chunk->gfx_level,  chunk->family,
684                         sq_img_rsrc_word0 + j * 4, gpu_list[j], 0xffffffff);
685 
686          fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
687          for (unsigned j = 0; j < 4; j++)
688             ac_dump_reg(f, chunk->gfx_level, chunk->family,
689                         R_008F00_SQ_BUF_RSRC_WORD0 + j * 4, gpu_list[4 + j], 0xffffffff);
690 
691          fprintf(f, COLOR_CYAN "    FMASK:" COLOR_RESET "\n");
692          for (unsigned j = 0; j < 8; j++)
693             ac_dump_reg(f, chunk->gfx_level, chunk->family,
694                         sq_img_rsrc_word0 + j * 4, gpu_list[8 + j], 0xffffffff);
695 
696          fprintf(f, COLOR_CYAN "    Sampler state:" COLOR_RESET "\n");
697          for (unsigned j = 0; j < 4; j++)
698             ac_dump_reg(f, chunk->gfx_level, chunk->family,
699                         R_008F30_SQ_IMG_SAMP_WORD0 + j * 4, gpu_list[12 + j], 0xffffffff);
700          break;
701       }
702 
703       if (memcmp(gpu_list, cpu_list, chunk->element_dw_size * 4) != 0) {
704          fprintf(f, COLOR_RED "!!!!! This slot was corrupted in GPU memory !!!!!" COLOR_RESET "\n");
705       }
706 
707       fprintf(f, "\n");
708    }
709 }
710 
711 static const struct u_log_chunk_type si_log_chunk_type_descriptor_list = {
712    .destroy = si_log_chunk_desc_list_destroy,
713    .print = si_log_chunk_desc_list_print,
714 };
715 
si_dump_descriptor_list(struct si_screen * screen,struct si_descriptors * desc,const char * shader_name,const char * elem_name,unsigned element_dw_size,unsigned num_elements,slot_remap_func slot_remap,struct u_log_context * log)716 static void si_dump_descriptor_list(struct si_screen *screen, struct si_descriptors *desc,
717                                     const char *shader_name, const char *elem_name,
718                                     unsigned element_dw_size, unsigned num_elements,
719                                     slot_remap_func slot_remap, struct u_log_context *log)
720 {
721    if (!desc->list)
722       return;
723 
724    /* In some cases, the caller doesn't know how many elements are really
725     * uploaded. Reduce num_elements to fit in the range of active slots. */
726    unsigned active_range_dw_begin = desc->first_active_slot * desc->element_dw_size;
727    unsigned active_range_dw_end =
728       active_range_dw_begin + desc->num_active_slots * desc->element_dw_size;
729 
730    while (num_elements > 0) {
731       int i = slot_remap(num_elements - 1);
732       unsigned dw_begin = i * element_dw_size;
733       unsigned dw_end = dw_begin + element_dw_size;
734 
735       if (dw_begin >= active_range_dw_begin && dw_end <= active_range_dw_end)
736          break;
737 
738       num_elements--;
739    }
740 
741    struct si_log_chunk_desc_list *chunk =
742       CALLOC_VARIANT_LENGTH_STRUCT(si_log_chunk_desc_list, 4 * element_dw_size * num_elements);
743    chunk->shader_name = shader_name;
744    chunk->elem_name = elem_name;
745    chunk->element_dw_size = element_dw_size;
746    chunk->num_elements = num_elements;
747    chunk->slot_remap = slot_remap;
748    chunk->gfx_level = screen->info.gfx_level;
749    chunk->family = screen->info.family;
750 
751    si_resource_reference(&chunk->buf, desc->buffer);
752    chunk->gpu_list = desc->gpu_list;
753 
754    for (unsigned i = 0; i < num_elements; ++i) {
755       memcpy(&chunk->list[i * element_dw_size], &desc->list[slot_remap(i) * element_dw_size],
756              4 * element_dw_size);
757    }
758 
759    u_log_chunk(log, &si_log_chunk_type_descriptor_list, chunk);
760 }
761 
si_identity(unsigned slot)762 static unsigned si_identity(unsigned slot)
763 {
764    return slot;
765 }
766 
si_dump_descriptors(struct si_context * sctx,gl_shader_stage stage,const struct si_shader_info * info,struct u_log_context * log)767 static void si_dump_descriptors(struct si_context *sctx, gl_shader_stage stage,
768                                 const struct si_shader_info *info, struct u_log_context *log)
769 {
770    enum pipe_shader_type processor = pipe_shader_type_from_mesa(stage);
771    struct si_descriptors *descs =
772       &sctx->descriptors[SI_DESCS_FIRST_SHADER + processor * SI_NUM_SHADER_DESCS];
773    static const char *shader_name[] = {"VS", "PS", "GS", "TCS", "TES", "CS"};
774    const char *name = shader_name[processor];
775    unsigned enabled_constbuf, enabled_shaderbuf, enabled_samplers;
776    unsigned enabled_images;
777 
778    if (info) {
779       enabled_constbuf = u_bit_consecutive(0, info->base.num_ubos);
780       enabled_shaderbuf = u_bit_consecutive(0, info->base.num_ssbos);
781       enabled_samplers = info->base.textures_used[0];
782       enabled_images = u_bit_consecutive(0, info->base.num_images);
783    } else {
784       enabled_constbuf =
785          sctx->const_and_shader_buffers[processor].enabled_mask >> SI_NUM_SHADER_BUFFERS;
786       enabled_shaderbuf = 0;
787       for (int i = 0; i < SI_NUM_SHADER_BUFFERS; i++) {
788          enabled_shaderbuf |=
789             (sctx->const_and_shader_buffers[processor].enabled_mask &
790              1llu << (SI_NUM_SHADER_BUFFERS - i - 1)) << i;
791       }
792       enabled_samplers = sctx->samplers[processor].enabled_mask;
793       enabled_images = sctx->images[processor].enabled_mask;
794    }
795 
796    si_dump_descriptor_list(sctx->screen, &descs[SI_SHADER_DESCS_CONST_AND_SHADER_BUFFERS], name,
797                            " - Constant buffer", 4, util_last_bit(enabled_constbuf),
798                            si_get_constbuf_slot, log);
799    si_dump_descriptor_list(sctx->screen, &descs[SI_SHADER_DESCS_CONST_AND_SHADER_BUFFERS], name,
800                            " - Shader buffer", 4, util_last_bit(enabled_shaderbuf),
801                            si_get_shaderbuf_slot, log);
802    si_dump_descriptor_list(sctx->screen, &descs[SI_SHADER_DESCS_SAMPLERS_AND_IMAGES], name,
803                            " - Sampler", 16, util_last_bit(enabled_samplers), si_get_sampler_slot,
804                            log);
805    si_dump_descriptor_list(sctx->screen, &descs[SI_SHADER_DESCS_SAMPLERS_AND_IMAGES], name,
806                            " - Image", 8, util_last_bit(enabled_images), si_get_image_slot, log);
807 }
808 
si_dump_gfx_descriptors(struct si_context * sctx,const struct si_shader_ctx_state * state,struct u_log_context * log)809 static void si_dump_gfx_descriptors(struct si_context *sctx,
810                                     const struct si_shader_ctx_state *state,
811                                     struct u_log_context *log)
812 {
813    if (!state->cso || !state->current)
814       return;
815 
816    si_dump_descriptors(sctx, state->cso->stage, &state->cso->info, log);
817 }
818 
si_dump_compute_descriptors(struct si_context * sctx,struct u_log_context * log)819 static void si_dump_compute_descriptors(struct si_context *sctx, struct u_log_context *log)
820 {
821    if (!sctx->cs_shader_state.program)
822       return;
823 
824    si_dump_descriptors(sctx, MESA_SHADER_COMPUTE, NULL, log);
825 }
826 
827 struct si_shader_inst {
828    const char *text; /* start of disassembly for this instruction */
829    unsigned textlen;
830    unsigned size; /* instruction size = 4 or 8 */
831    uint64_t addr; /* instruction address */
832 };
833 
834 /**
835  * Open the given \p binary as \p rtld_binary and split the contained
836  * disassembly string into instructions and add them to the array
837  * pointed to by \p instructions, which must be sufficiently large.
838  *
839  * Labels are considered to be part of the following instruction.
840  *
841  * The caller must keep \p rtld_binary alive as long as \p instructions are
842  * used and then close it afterwards.
843  */
si_add_split_disasm(struct si_screen * screen,struct ac_rtld_binary * rtld_binary,struct si_shader_binary * binary,uint64_t * addr,unsigned * num,struct si_shader_inst * instructions,gl_shader_stage stage,unsigned wave_size)844 static void si_add_split_disasm(struct si_screen *screen, struct ac_rtld_binary *rtld_binary,
845                                 struct si_shader_binary *binary, uint64_t *addr, unsigned *num,
846                                 struct si_shader_inst *instructions,
847                                 gl_shader_stage stage, unsigned wave_size)
848 {
849    if (!ac_rtld_open(rtld_binary, (struct ac_rtld_open_info){
850                                      .info = &screen->info,
851                                      .shader_type = stage,
852                                      .wave_size = wave_size,
853                                      .num_parts = 1,
854                                      .elf_ptrs = &binary->code_buffer,
855                                      .elf_sizes = &binary->code_size}))
856       return;
857 
858    const char *disasm;
859    size_t nbytes;
860    if (!ac_rtld_get_section_by_name(rtld_binary, ".AMDGPU.disasm", &disasm, &nbytes))
861       return;
862 
863    const char *end = disasm + nbytes;
864    while (disasm < end) {
865       const char *semicolon = memchr(disasm, ';', end - disasm);
866       if (!semicolon)
867          break;
868 
869       struct si_shader_inst *inst = &instructions[(*num)++];
870       const char *inst_end = memchr(semicolon + 1, '\n', end - semicolon - 1);
871       if (!inst_end)
872          inst_end = end;
873 
874       inst->text = disasm;
875       inst->textlen = inst_end - disasm;
876 
877       inst->addr = *addr;
878       /* More than 16 chars after ";" means the instruction is 8 bytes long. */
879       inst->size = inst_end - semicolon > 16 ? 8 : 4;
880       *addr += inst->size;
881 
882       if (inst_end == end)
883          break;
884       disasm = inst_end + 1;
885    }
886 }
887 
888 /* If the shader is being executed, print its asm instructions, and annotate
889  * those that are being executed right now with information about waves that
890  * execute them. This is most useful during a GPU hang.
891  */
si_print_annotated_shader(struct si_shader * shader,struct ac_wave_info * waves,unsigned num_waves,FILE * f)892 static void si_print_annotated_shader(struct si_shader *shader, struct ac_wave_info *waves,
893                                       unsigned num_waves, FILE *f)
894 {
895    if (!shader)
896       return;
897 
898    struct si_screen *screen = shader->selector->screen;
899    gl_shader_stage stage = shader->selector->stage;
900    uint64_t start_addr = shader->bo->gpu_address;
901    uint64_t end_addr = start_addr + shader->bo->b.b.width0;
902    unsigned i;
903 
904    /* See if any wave executes the shader. */
905    for (i = 0; i < num_waves; i++) {
906       if (start_addr <= waves[i].pc && waves[i].pc <= end_addr)
907          break;
908    }
909    if (i == num_waves)
910       return; /* the shader is not being executed */
911 
912    /* Remember the first found wave. The waves are sorted according to PC. */
913    waves = &waves[i];
914    num_waves -= i;
915 
916    /* Get the list of instructions.
917     * Buffer size / 4 is the upper bound of the instruction count.
918     */
919    unsigned num_inst = 0;
920    uint64_t inst_addr = start_addr;
921    struct ac_rtld_binary rtld_binaries[5] = {};
922    struct si_shader_inst *instructions =
923       calloc(shader->bo->b.b.width0 / 4, sizeof(struct si_shader_inst));
924 
925    if (shader->prolog) {
926       si_add_split_disasm(screen, &rtld_binaries[0], &shader->prolog->binary, &inst_addr, &num_inst,
927                           instructions, stage, shader->wave_size);
928    }
929    if (shader->previous_stage) {
930       si_add_split_disasm(screen, &rtld_binaries[1], &shader->previous_stage->binary, &inst_addr,
931                           &num_inst, instructions, stage, shader->wave_size);
932    }
933    si_add_split_disasm(screen, &rtld_binaries[3], &shader->binary, &inst_addr, &num_inst,
934                        instructions, stage, shader->wave_size);
935    if (shader->epilog) {
936       si_add_split_disasm(screen, &rtld_binaries[4], &shader->epilog->binary, &inst_addr, &num_inst,
937                           instructions, stage, shader->wave_size);
938    }
939 
940    fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET "\n",
941            si_get_shader_name(shader));
942 
943    /* Print instructions with annotations. */
944    for (i = 0; i < num_inst; i++) {
945       struct si_shader_inst *inst = &instructions[i];
946 
947       fprintf(f, "%.*s [PC=0x%" PRIx64 ", size=%u]\n", inst->textlen, inst->text, inst->addr,
948               inst->size);
949 
950       /* Print which waves execute the instruction right now. */
951       while (num_waves && inst->addr == waves->pc) {
952          fprintf(f,
953                  "          " COLOR_GREEN "^ SE%u SH%u CU%u "
954                  "SIMD%u WAVE%u  EXEC=%016" PRIx64 "  ",
955                  waves->se, waves->sh, waves->cu, waves->simd, waves->wave, waves->exec);
956 
957          if (inst->size == 4) {
958             fprintf(f, "INST32=%08X" COLOR_RESET "\n", waves->inst_dw0);
959          } else {
960             fprintf(f, "INST64=%08X %08X" COLOR_RESET "\n", waves->inst_dw0, waves->inst_dw1);
961          }
962 
963          waves->matched = true;
964          waves = &waves[1];
965          num_waves--;
966       }
967    }
968 
969    fprintf(f, "\n\n");
970    free(instructions);
971    for (unsigned i = 0; i < ARRAY_SIZE(rtld_binaries); ++i)
972       ac_rtld_close(&rtld_binaries[i]);
973 }
974 
si_dump_annotated_shaders(struct si_context * sctx,FILE * f)975 static void si_dump_annotated_shaders(struct si_context *sctx, FILE *f)
976 {
977    struct ac_wave_info waves[AC_MAX_WAVES_PER_CHIP];
978    unsigned num_waves = ac_get_wave_info(sctx->gfx_level, &sctx->screen->info, NULL, waves);
979 
980    fprintf(f, COLOR_CYAN "The number of active waves = %u" COLOR_RESET "\n\n", num_waves);
981 
982    si_print_annotated_shader(sctx->shader.vs.current, waves, num_waves, f);
983    si_print_annotated_shader(sctx->shader.tcs.current, waves, num_waves, f);
984    si_print_annotated_shader(sctx->shader.tes.current, waves, num_waves, f);
985    si_print_annotated_shader(sctx->shader.gs.current, waves, num_waves, f);
986    si_print_annotated_shader(sctx->shader.ps.current, waves, num_waves, f);
987 
988    /* Print waves executing shaders that are not currently bound. */
989    unsigned i;
990    bool found = false;
991    for (i = 0; i < num_waves; i++) {
992       if (waves[i].matched)
993          continue;
994 
995       if (!found) {
996          fprintf(f, COLOR_CYAN "Waves not executing currently-bound shaders:" COLOR_RESET "\n");
997          found = true;
998       }
999       fprintf(f,
1000               "    SE%u SH%u CU%u SIMD%u WAVE%u  EXEC=%016" PRIx64 "  INST=%08X %08X  PC=%" PRIx64
1001               "\n",
1002               waves[i].se, waves[i].sh, waves[i].cu, waves[i].simd, waves[i].wave, waves[i].exec,
1003               waves[i].inst_dw0, waves[i].inst_dw1, waves[i].pc);
1004    }
1005    if (found)
1006       fprintf(f, "\n\n");
1007 }
1008 
si_dump_command(const char * title,const char * command,FILE * f)1009 static void si_dump_command(const char *title, const char *command, FILE *f)
1010 {
1011    char line[2000];
1012 
1013    FILE *p = popen(command, "r");
1014    if (!p)
1015       return;
1016 
1017    fprintf(f, COLOR_YELLOW "%s: " COLOR_RESET "\n", title);
1018    while (fgets(line, sizeof(line), p))
1019       fputs(line, f);
1020    fprintf(f, "\n\n");
1021    pclose(p);
1022 }
1023 
si_dump_debug_state(struct pipe_context * ctx,FILE * f,unsigned flags)1024 static void si_dump_debug_state(struct pipe_context *ctx, FILE *f, unsigned flags)
1025 {
1026    struct si_context *sctx = (struct si_context *)ctx;
1027 
1028    if (sctx->log)
1029       u_log_flush(sctx->log);
1030 
1031    if (flags & PIPE_DUMP_DEVICE_STATUS_REGISTERS) {
1032       si_dump_debug_registers(sctx, f);
1033 
1034       si_dump_annotated_shaders(sctx, f);
1035       si_dump_command("Active waves (raw data)", "umr -O halt_waves -wa | column -t", f);
1036       si_dump_command("Wave information", "umr -O halt_waves,bits -wa", f);
1037    }
1038 }
1039 
si_log_draw_state(struct si_context * sctx,struct u_log_context * log)1040 void si_log_draw_state(struct si_context *sctx, struct u_log_context *log)
1041 {
1042    if (!log)
1043       return;
1044 
1045    si_dump_framebuffer(sctx, log);
1046 
1047    si_dump_gfx_shader(sctx, &sctx->shader.vs, log);
1048    si_dump_gfx_shader(sctx, &sctx->shader.tcs, log);
1049    si_dump_gfx_shader(sctx, &sctx->shader.tes, log);
1050    si_dump_gfx_shader(sctx, &sctx->shader.gs, log);
1051    si_dump_gfx_shader(sctx, &sctx->shader.ps, log);
1052 
1053    si_dump_descriptor_list(sctx->screen, &sctx->descriptors[SI_DESCS_INTERNAL], "", "RW buffers",
1054                            4, sctx->descriptors[SI_DESCS_INTERNAL].num_active_slots, si_identity,
1055                            log);
1056    si_dump_gfx_descriptors(sctx, &sctx->shader.vs, log);
1057    si_dump_gfx_descriptors(sctx, &sctx->shader.tcs, log);
1058    si_dump_gfx_descriptors(sctx, &sctx->shader.tes, log);
1059    si_dump_gfx_descriptors(sctx, &sctx->shader.gs, log);
1060    si_dump_gfx_descriptors(sctx, &sctx->shader.ps, log);
1061 }
1062 
si_log_compute_state(struct si_context * sctx,struct u_log_context * log)1063 void si_log_compute_state(struct si_context *sctx, struct u_log_context *log)
1064 {
1065    if (!log)
1066       return;
1067 
1068    si_dump_compute_shader(sctx, log);
1069    si_dump_compute_descriptors(sctx, log);
1070 }
1071 
si_check_vm_faults(struct si_context * sctx,struct radeon_saved_cs * saved)1072 void si_check_vm_faults(struct si_context *sctx, struct radeon_saved_cs *saved)
1073 {
1074    struct pipe_screen *screen = sctx->b.screen;
1075    FILE *f;
1076    uint64_t addr;
1077    char cmd_line[4096];
1078 
1079    if (!ac_vm_fault_occurred(sctx->gfx_level, &sctx->dmesg_timestamp, &addr))
1080       return;
1081 
1082    f = dd_get_debug_file(false);
1083    if (!f)
1084       return;
1085 
1086    fprintf(f, "VM fault report.\n\n");
1087    if (util_get_command_line(cmd_line, sizeof(cmd_line)))
1088       fprintf(f, "Command: %s\n", cmd_line);
1089    fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
1090    fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
1091    fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
1092    fprintf(f, "Failing VM page: 0x%08" PRIx64 "\n\n", addr);
1093 
1094    if (sctx->apitrace_call_number)
1095       fprintf(f, "Last apitrace call: %u\n\n", sctx->apitrace_call_number);
1096 
1097    switch (si_get_context_ip_type(sctx)) {
1098    case AMD_IP_GFX:
1099    case AMD_IP_COMPUTE: {
1100       struct u_log_context log;
1101       u_log_context_init(&log);
1102 
1103       si_log_draw_state(sctx, &log);
1104       si_log_compute_state(sctx, &log);
1105       si_log_cs(sctx, &log, true);
1106 
1107       u_log_new_page_print(&log, f);
1108       u_log_context_destroy(&log);
1109       break;
1110    }
1111 
1112    default:
1113       break;
1114    }
1115 
1116    fclose(f);
1117 
1118    fprintf(stderr, "Detected a VM fault, exiting...\n");
1119    exit(0);
1120 }
1121 
si_gather_context_rolls(struct si_context * sctx)1122 void si_gather_context_rolls(struct si_context *sctx)
1123 {
1124    struct radeon_cmdbuf *cs = &sctx->gfx_cs;
1125    uint32_t **ibs = alloca(sizeof(ibs[0]) * (cs->num_prev + 1));
1126    uint32_t *ib_dw_sizes = alloca(sizeof(ib_dw_sizes[0]) * (cs->num_prev + 1));
1127 
1128    for (unsigned i = 0; i < cs->num_prev; i++) {
1129       struct radeon_cmdbuf_chunk *chunk = &cs->prev[i];
1130 
1131       ibs[i] = chunk->buf;
1132       ib_dw_sizes[i] = chunk->cdw;
1133    }
1134 
1135    ibs[cs->num_prev] = cs->current.buf;
1136    ib_dw_sizes[cs->num_prev] = cs->current.cdw;
1137 
1138    FILE *f = fopen(sctx->screen->context_roll_log_filename, "a");
1139    ac_gather_context_rolls(f, ibs, ib_dw_sizes, cs->num_prev + 1, NULL, &sctx->screen->info);
1140    fclose(f);
1141 }
1142 
si_init_debug_functions(struct si_context * sctx)1143 void si_init_debug_functions(struct si_context *sctx)
1144 {
1145    sctx->b.dump_debug_state = si_dump_debug_state;
1146 
1147    /* Set the initial dmesg timestamp for this context, so that
1148     * only new messages will be checked for VM faults.
1149     */
1150    if (sctx->screen->debug_flags & DBG(CHECK_VM))
1151       ac_vm_fault_occurred(sctx->gfx_level, &sctx->dmesg_timestamp, NULL);
1152 }
1153