397a9ef4214b2aaa9c1e15fb38fd8b5f49226b16
[mesa.git] / src / amd / vulkan / radv_debug.c
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30
31 #include "sid.h"
32 #include "gfx9d.h"
33 #include "ac_debug.h"
34 #include "radv_debug.h"
35 #include "radv_shader.h"
36
37 #define TRACE_BO_SIZE 4096
38
39 #define COLOR_RESET "\033[0m"
40 #define COLOR_RED "\033[31m"
41 #define COLOR_GREEN "\033[1;32m"
42 #define COLOR_YELLOW "\033[1;33m"
43 #define COLOR_CYAN "\033[1;36m"
44
45 /* Trace BO layout (offsets are 4 bytes):
46 *
47 * [0]: primary trace ID
48 * [1]: secondary trace ID
49 * [2-3]: 64-bit GFX pipeline pointer
50 * [4-5]: 64-bit COMPUTE pipeline pointer
51 * [6-7]: 64-bit descriptor set #0 pointer
52 * ...
53 * [68-69]: 64-bit descriptor set #31 pointer
54 */
55
56 bool
57 radv_init_trace(struct radv_device *device)
58 {
59 struct radeon_winsys *ws = device->ws;
60
61 device->trace_bo = ws->buffer_create(ws, TRACE_BO_SIZE, 8,
62 RADEON_DOMAIN_VRAM,
63 RADEON_FLAG_CPU_ACCESS);
64 if (!device->trace_bo)
65 return false;
66
67 device->trace_id_ptr = ws->buffer_map(device->trace_bo);
68 if (!device->trace_id_ptr)
69 return false;
70
71 memset(device->trace_id_ptr, 0, TRACE_BO_SIZE);
72
73 ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
74 &device->dmesg_timestamp, NULL);
75
76 return true;
77 }
78
79 static void
80 radv_dump_trace(struct radv_device *device, struct radeon_winsys_cs *cs)
81 {
82 const char *filename = getenv("RADV_TRACE_FILE");
83 FILE *f = fopen(filename, "w");
84
85 if (!f) {
86 fprintf(stderr, "Failed to write trace dump to %s\n", filename);
87 return;
88 }
89
90 fprintf(f, "Trace ID: %x\n", *device->trace_id_ptr);
91 device->ws->cs_dump(cs, f, (const int*)device->trace_id_ptr, 2);
92 fclose(f);
93 }
94
95 static void
96 radv_dump_mmapped_reg(struct radv_device *device, FILE *f, unsigned offset)
97 {
98 struct radeon_winsys *ws = device->ws;
99 uint32_t value;
100
101 if (ws->read_registers(ws, offset, 1, &value))
102 ac_dump_reg(f, device->physical_device->rad_info.chip_class,
103 offset, value, ~0);
104 }
105
106 static void
107 radv_dump_debug_registers(struct radv_device *device, FILE *f)
108 {
109 struct radeon_info *info = &device->physical_device->rad_info;
110
111 if (info->drm_major == 2 && info->drm_minor < 42)
112 return; /* no radeon support */
113
114 fprintf(f, "Memory-mapped registers:\n");
115 radv_dump_mmapped_reg(device, f, R_008010_GRBM_STATUS);
116
117 /* No other registers can be read on DRM < 3.1.0. */
118 if (info->drm_major < 3 || info->drm_minor < 1) {
119 fprintf(f, "\n");
120 return;
121 }
122
123 radv_dump_mmapped_reg(device, f, R_008008_GRBM_STATUS2);
124 radv_dump_mmapped_reg(device, f, R_008014_GRBM_STATUS_SE0);
125 radv_dump_mmapped_reg(device, f, R_008018_GRBM_STATUS_SE1);
126 radv_dump_mmapped_reg(device, f, R_008038_GRBM_STATUS_SE2);
127 radv_dump_mmapped_reg(device, f, R_00803C_GRBM_STATUS_SE3);
128 radv_dump_mmapped_reg(device, f, R_00D034_SDMA0_STATUS_REG);
129 radv_dump_mmapped_reg(device, f, R_00D834_SDMA1_STATUS_REG);
130 if (info->chip_class <= VI) {
131 radv_dump_mmapped_reg(device, f, R_000E50_SRBM_STATUS);
132 radv_dump_mmapped_reg(device, f, R_000E4C_SRBM_STATUS2);
133 radv_dump_mmapped_reg(device, f, R_000E54_SRBM_STATUS3);
134 }
135 radv_dump_mmapped_reg(device, f, R_008680_CP_STAT);
136 radv_dump_mmapped_reg(device, f, R_008674_CP_STALLED_STAT1);
137 radv_dump_mmapped_reg(device, f, R_008678_CP_STALLED_STAT2);
138 radv_dump_mmapped_reg(device, f, R_008670_CP_STALLED_STAT3);
139 radv_dump_mmapped_reg(device, f, R_008210_CP_CPC_STATUS);
140 radv_dump_mmapped_reg(device, f, R_008214_CP_CPC_BUSY_STAT);
141 radv_dump_mmapped_reg(device, f, R_008218_CP_CPC_STALLED_STAT1);
142 radv_dump_mmapped_reg(device, f, R_00821C_CP_CPF_STATUS);
143 radv_dump_mmapped_reg(device, f, R_008220_CP_CPF_BUSY_STAT);
144 radv_dump_mmapped_reg(device, f, R_008224_CP_CPF_STALLED_STAT1);
145 fprintf(f, "\n");
146 }
147
148 struct radv_shader_inst {
149 char text[160]; /* one disasm line */
150 unsigned offset; /* instruction offset */
151 unsigned size; /* instruction size = 4 or 8 */
152 };
153
154 /* Split a disassembly string into lines and add them to the array pointed
155 * to by "instructions". */
156 static void si_add_split_disasm(const char *disasm,
157 uint64_t start_addr,
158 unsigned *num,
159 struct radv_shader_inst *instructions)
160 {
161 struct radv_shader_inst *last_inst = *num ? &instructions[*num - 1] : NULL;
162 char *next;
163
164 while ((next = strchr(disasm, '\n'))) {
165 struct radv_shader_inst *inst = &instructions[*num];
166 unsigned len = next - disasm;
167
168 assert(len < ARRAY_SIZE(inst->text));
169 memcpy(inst->text, disasm, len);
170 inst->text[len] = 0;
171 inst->offset = last_inst ? last_inst->offset + last_inst->size : 0;
172
173 const char *semicolon = strchr(disasm, ';');
174 assert(semicolon);
175 /* More than 16 chars after ";" means the instruction is 8 bytes long. */
176 inst->size = next - semicolon > 16 ? 8 : 4;
177
178 snprintf(inst->text + len, ARRAY_SIZE(inst->text) - len,
179 " [PC=0x%"PRIx64", off=%u, size=%u]",
180 start_addr + inst->offset, inst->offset, inst->size);
181
182 last_inst = inst;
183 (*num)++;
184 disasm = next + 1;
185 }
186 }
187
188 static void
189 radv_dump_annotated_shader(struct radv_pipeline *pipeline,
190 struct radv_shader_variant *shader,
191 gl_shader_stage stage,
192 struct ac_wave_info *waves, unsigned num_waves,
193 FILE *f)
194 {
195 struct radv_device *device = pipeline->device;
196 uint64_t start_addr, end_addr;
197 unsigned i;
198
199 if (!shader)
200 return;
201
202 start_addr = device->ws->buffer_get_va(shader->bo) + shader->bo_offset;
203 end_addr = start_addr + shader->code_size;
204
205 /* See if any wave executes the shader. */
206 for (i = 0; i < num_waves; i++) {
207 if (start_addr <= waves[i].pc && waves[i].pc <= end_addr)
208 break;
209 }
210
211 if (i == num_waves)
212 return; /* the shader is not being executed */
213
214 /* Remember the first found wave. The waves are sorted according to PC. */
215 waves = &waves[i];
216 num_waves -= i;
217
218 /* Get the list of instructions.
219 * Buffer size / 4 is the upper bound of the instruction count.
220 */
221 unsigned num_inst = 0;
222 struct radv_shader_inst *instructions =
223 calloc(shader->code_size / 4, sizeof(struct radv_shader_inst));
224
225 si_add_split_disasm(shader->disasm_string,
226 start_addr, &num_inst, instructions);
227
228 fprintf(f, COLOR_YELLOW "%s - annotated disassembly:" COLOR_RESET "\n",
229 radv_get_shader_name(shader, stage));
230
231 /* Print instructions with annotations. */
232 for (i = 0; i < num_inst; i++) {
233 struct radv_shader_inst *inst = &instructions[i];
234
235 fprintf(f, "%s\n", inst->text);
236
237 /* Print which waves execute the instruction right now. */
238 while (num_waves && start_addr + inst->offset == waves->pc) {
239 fprintf(f,
240 " " COLOR_GREEN "^ SE%u SH%u CU%u "
241 "SIMD%u WAVE%u EXEC=%016"PRIx64 " ",
242 waves->se, waves->sh, waves->cu, waves->simd,
243 waves->wave, waves->exec);
244
245 if (inst->size == 4) {
246 fprintf(f, "INST32=%08X" COLOR_RESET "\n",
247 waves->inst_dw0);
248 } else {
249 fprintf(f, "INST64=%08X %08X" COLOR_RESET "\n",
250 waves->inst_dw0, waves->inst_dw1);
251 }
252
253 waves->matched = true;
254 waves = &waves[1];
255 num_waves--;
256 }
257 }
258
259 fprintf(f, "\n\n");
260 free(instructions);
261 }
262
263 static void
264 radv_dump_annotated_shaders(struct radv_pipeline *pipeline,
265 struct radv_shader_variant *compute_shader,
266 FILE *f)
267 {
268 struct ac_wave_info waves[AC_MAX_WAVES_PER_CHIP];
269 unsigned num_waves = ac_get_wave_info(waves);
270 unsigned mask;
271
272 fprintf(f, COLOR_CYAN "The number of active waves = %u" COLOR_RESET
273 "\n\n", num_waves);
274
275 /* Dump annotated active graphics shaders. */
276 mask = pipeline->active_stages;
277 while (mask) {
278 int stage = u_bit_scan(&mask);
279
280 radv_dump_annotated_shader(pipeline, pipeline->shaders[stage],
281 stage, waves, num_waves, f);
282 }
283
284 radv_dump_annotated_shader(pipeline, compute_shader,
285 MESA_SHADER_COMPUTE, waves, num_waves, f);
286
287 /* Print waves executing shaders that are not currently bound. */
288 unsigned i;
289 bool found = false;
290 for (i = 0; i < num_waves; i++) {
291 if (waves[i].matched)
292 continue;
293
294 if (!found) {
295 fprintf(f, COLOR_CYAN
296 "Waves not executing currently-bound shaders:"
297 COLOR_RESET "\n");
298 found = true;
299 }
300 fprintf(f, " SE%u SH%u CU%u SIMD%u WAVE%u EXEC=%016"PRIx64
301 " INST=%08X %08X PC=%"PRIx64"\n",
302 waves[i].se, waves[i].sh, waves[i].cu, waves[i].simd,
303 waves[i].wave, waves[i].exec, waves[i].inst_dw0,
304 waves[i].inst_dw1, waves[i].pc);
305 }
306 if (found)
307 fprintf(f, "\n\n");
308 }
309
310 static void
311 radv_dump_shader(struct radv_pipeline *pipeline,
312 struct radv_shader_variant *shader, gl_shader_stage stage,
313 FILE *f)
314 {
315 if (!shader)
316 return;
317
318 fprintf(f, "%s:\n%s\n\n", radv_get_shader_name(shader, stage),
319 shader->disasm_string);
320
321 radv_shader_dump_stats(pipeline->device, shader, stage, f);
322 }
323
324 static void
325 radv_dump_shaders(struct radv_pipeline *pipeline,
326 struct radv_shader_variant *compute_shader, FILE *f)
327 {
328 unsigned mask;
329
330 /* Dump active graphics shaders. */
331 mask = pipeline->active_stages;
332 while (mask) {
333 int stage = u_bit_scan(&mask);
334
335 radv_dump_shader(pipeline, pipeline->shaders[stage], stage, f);
336 }
337
338 radv_dump_shader(pipeline, compute_shader, MESA_SHADER_COMPUTE, f);
339 }
340
341 static void
342 radv_dump_graphics_state(struct radv_pipeline *graphics_pipeline,
343 struct radv_pipeline *compute_pipeline, FILE *f)
344 {
345 struct radv_shader_variant *compute_shader =
346 compute_pipeline ? compute_pipeline->shaders[MESA_SHADER_COMPUTE] : NULL;
347
348 if (!graphics_pipeline)
349 return;
350
351 radv_dump_shaders(graphics_pipeline, compute_shader, f);
352 radv_dump_annotated_shaders(graphics_pipeline, compute_shader, f);
353 }
354
355 static void
356 radv_dump_compute_state(struct radv_pipeline *compute_pipeline, FILE *f)
357 {
358 if (!compute_pipeline)
359 return;
360
361 radv_dump_shaders(compute_pipeline,
362 compute_pipeline->shaders[MESA_SHADER_COMPUTE], f);
363 radv_dump_annotated_shaders(compute_pipeline,
364 compute_pipeline->shaders[MESA_SHADER_COMPUTE],
365 f);
366 }
367
368 static struct radv_pipeline *
369 radv_get_saved_graphics_pipeline(struct radv_device *device)
370 {
371 uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
372
373 return (struct radv_pipeline *)ptr[1];
374 }
375
376 static struct radv_pipeline *
377 radv_get_saved_compute_pipeline(struct radv_device *device)
378 {
379 uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
380
381 return (struct radv_pipeline *)ptr[2];
382 }
383
384 static bool
385 radv_gpu_hang_occured(struct radv_queue *queue, enum ring_type ring)
386 {
387 struct radeon_winsys *ws = queue->device->ws;
388
389 if (!ws->ctx_wait_idle(queue->hw_ctx, ring, queue->queue_idx))
390 return true;
391
392 return false;
393 }
394
395 void
396 radv_check_gpu_hangs(struct radv_queue *queue, struct radeon_winsys_cs *cs)
397 {
398 struct radv_pipeline *graphics_pipeline, *compute_pipeline;
399 struct radv_device *device = queue->device;
400 enum ring_type ring;
401 uint64_t addr;
402
403 ring = radv_queue_family_to_ring(queue->queue_family_index);
404
405 bool hang_occurred = radv_gpu_hang_occured(queue, ring);
406 bool vm_fault_occurred = false;
407 if (queue->device->instance->debug_flags & RADV_DEBUG_VM_FAULTS)
408 vm_fault_occurred = ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
409 &device->dmesg_timestamp, &addr);
410 if (!hang_occurred && !vm_fault_occurred)
411 return;
412
413 graphics_pipeline = radv_get_saved_graphics_pipeline(device);
414 compute_pipeline = radv_get_saved_compute_pipeline(device);
415
416 if (vm_fault_occurred) {
417 fprintf(stderr, "VM fault report.\n\n");
418 fprintf(stderr, "Failing VM page: 0x%08"PRIx64"\n\n", addr);
419 }
420
421 radv_dump_debug_registers(device, stderr);
422
423 switch (ring) {
424 case RING_GFX:
425 radv_dump_graphics_state(graphics_pipeline, compute_pipeline,
426 stderr);
427 break;
428 case RING_COMPUTE:
429 radv_dump_compute_state(compute_pipeline, stderr);
430 break;
431 default:
432 assert(0);
433 break;
434 }
435
436 radv_dump_trace(queue->device, cs);
437 abort();
438 }
439
440 void
441 radv_print_spirv(struct radv_shader_module *module, FILE *fp)
442 {
443 char path[] = "/tmp/fileXXXXXX";
444 char line[2048], command[128];
445 FILE *p;
446 int fd;
447
448 /* Dump the binary into a temporary file. */
449 fd = mkstemp(path);
450 if (fd < 0)
451 return;
452
453 if (write(fd, module->data, module->size) == -1)
454 goto fail;
455
456 sprintf(command, "spirv-dis %s", path);
457
458 /* Disassemble using spirv-dis if installed. */
459 p = popen(command, "r");
460 if (p) {
461 while (fgets(line, sizeof(line), p))
462 fprintf(fp, "%s", line);
463 pclose(p);
464 }
465
466 fail:
467 close(fd);
468 unlink(path);
469 }