ddebug: write contents of dmesg into hang reports
[mesa.git] / src / gallium / drivers / ddebug / dd_draw.c
1 /**************************************************************************
2 *
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "dd_pipe.h"
29
30 #include "util/u_dump.h"
31 #include "util/u_format.h"
32 #include "tgsi/tgsi_scan.h"
33
34
35 enum call_type
36 {
37 CALL_DRAW_VBO,
38 CALL_LAUNCH_GRID,
39 CALL_RESOURCE_COPY_REGION,
40 CALL_BLIT,
41 CALL_FLUSH_RESOURCE,
42 CALL_CLEAR,
43 CALL_CLEAR_BUFFER,
44 CALL_CLEAR_RENDER_TARGET,
45 CALL_CLEAR_DEPTH_STENCIL,
46 CALL_GENERATE_MIPMAP,
47 };
48
49 struct call_resource_copy_region
50 {
51 struct pipe_resource *dst;
52 unsigned dst_level;
53 unsigned dstx, dsty, dstz;
54 struct pipe_resource *src;
55 unsigned src_level;
56 const struct pipe_box *src_box;
57 };
58
59 struct call_clear
60 {
61 unsigned buffers;
62 const union pipe_color_union *color;
63 double depth;
64 unsigned stencil;
65 };
66
67 struct call_clear_buffer
68 {
69 struct pipe_resource *res;
70 unsigned offset;
71 unsigned size;
72 const void *clear_value;
73 int clear_value_size;
74 };
75
76 struct call_generate_mipmap {
77 struct pipe_resource *res;
78 enum pipe_format format;
79 unsigned base_level;
80 unsigned last_level;
81 unsigned first_layer;
82 unsigned last_layer;
83 };
84
85 struct dd_call
86 {
87 enum call_type type;
88
89 union {
90 struct pipe_draw_info draw_vbo;
91 struct pipe_grid_info launch_grid;
92 struct call_resource_copy_region resource_copy_region;
93 struct pipe_blit_info blit;
94 struct pipe_resource *flush_resource;
95 struct call_clear clear;
96 struct call_clear_buffer clear_buffer;
97 struct call_generate_mipmap generate_mipmap;
98 } info;
99 };
100
101 static FILE *
102 dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number)
103 {
104 struct pipe_screen *screen = dscreen->screen;
105 FILE *f = dd_get_debug_file(dscreen->verbose);
106 if (!f)
107 return NULL;
108
109 fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
110 fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
111 fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
112
113 if (apitrace_call_number)
114 fprintf(f, "Last apitrace call: %u\n\n",
115 apitrace_call_number);
116 return f;
117 }
118
119 static void
120 dd_dump_dmesg(FILE *f)
121 {
122 char line[2000];
123 FILE *p = popen("dmesg | tail -n60", "r");
124
125 if (!p)
126 return;
127
128 fprintf(f, "\nLast 60 lines of dmesg:\n\n");
129 while (fgets(line, sizeof(line), p))
130 fputs(line, f);
131
132 fclose(p);
133 }
134
135 static void
136 dd_close_file_stream(FILE *f)
137 {
138 fclose(f);
139 }
140
141 static unsigned
142 dd_num_active_viewports(struct dd_context *dctx)
143 {
144 struct tgsi_shader_info info;
145 const struct tgsi_token *tokens;
146
147 if (dctx->shaders[PIPE_SHADER_GEOMETRY])
148 tokens = dctx->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens;
149 else if (dctx->shaders[PIPE_SHADER_TESS_EVAL])
150 tokens = dctx->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens;
151 else if (dctx->shaders[PIPE_SHADER_VERTEX])
152 tokens = dctx->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens;
153 else
154 return 1;
155
156 tgsi_scan_shader(tokens, &info);
157 return info.writes_viewport_index ? PIPE_MAX_VIEWPORTS : 1;
158 }
159
160 #define COLOR_RESET "\033[0m"
161 #define COLOR_SHADER "\033[1;32m"
162 #define COLOR_STATE "\033[1;33m"
163
164 #define DUMP(name, var) do { \
165 fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \
166 util_dump_##name(f, var); \
167 fprintf(f, "\n"); \
168 } while(0)
169
170 #define DUMP_I(name, var, i) do { \
171 fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \
172 util_dump_##name(f, var); \
173 fprintf(f, "\n"); \
174 } while(0)
175
176 #define DUMP_M(name, var, member) do { \
177 fprintf(f, " " #member ": "); \
178 util_dump_##name(f, (var)->member); \
179 fprintf(f, "\n"); \
180 } while(0)
181
182 #define DUMP_M_ADDR(name, var, member) do { \
183 fprintf(f, " " #member ": "); \
184 util_dump_##name(f, &(var)->member); \
185 fprintf(f, "\n"); \
186 } while(0)
187
188 static void
189 print_named_value(FILE *f, const char *name, int value)
190 {
191 fprintf(f, COLOR_STATE "%s" COLOR_RESET " = %i\n", name, value);
192 }
193
194 static void
195 print_named_xvalue(FILE *f, const char *name, int value)
196 {
197 fprintf(f, COLOR_STATE "%s" COLOR_RESET " = 0x%08x\n", name, value);
198 }
199
200 static void
201 util_dump_uint(FILE *f, unsigned i)
202 {
203 fprintf(f, "%u", i);
204 }
205
206 static void
207 util_dump_hex(FILE *f, unsigned i)
208 {
209 fprintf(f, "0x%x", i);
210 }
211
212 static void
213 util_dump_double(FILE *f, double d)
214 {
215 fprintf(f, "%f", d);
216 }
217
218 static void
219 util_dump_format(FILE *f, enum pipe_format format)
220 {
221 fprintf(f, "%s", util_format_name(format));
222 }
223
224 static void
225 util_dump_color_union(FILE *f, const union pipe_color_union *color)
226 {
227 fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}",
228 color->f[0], color->f[1], color->f[2], color->f[3],
229 color->ui[0], color->ui[1], color->ui[2], color->ui[3]);
230 }
231
232 static void
233 util_dump_query(FILE *f, struct dd_query *query)
234 {
235 if (query->type >= PIPE_QUERY_DRIVER_SPECIFIC)
236 fprintf(f, "PIPE_QUERY_DRIVER_SPECIFIC + %i",
237 query->type - PIPE_QUERY_DRIVER_SPECIFIC);
238 else
239 fprintf(f, "%s", util_dump_query_type(query->type, false));
240 }
241
242 static void
243 dd_dump_render_condition(struct dd_context *dctx, FILE *f)
244 {
245 if (dctx->render_cond.query) {
246 fprintf(f, "render condition:\n");
247 DUMP_M(query, &dctx->render_cond, query);
248 DUMP_M(uint, &dctx->render_cond, condition);
249 DUMP_M(uint, &dctx->render_cond, mode);
250 fprintf(f, "\n");
251 }
252 }
253
254 static void
255 dd_dump_draw_vbo(struct dd_context *dctx, struct pipe_draw_info *info, FILE *f)
256 {
257 int sh, i;
258 const char *shader_str[PIPE_SHADER_TYPES];
259
260 shader_str[PIPE_SHADER_VERTEX] = "VERTEX";
261 shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL";
262 shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL";
263 shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY";
264 shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT";
265 shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE";
266
267 DUMP(draw_info, info);
268 if (info->indexed) {
269 DUMP(index_buffer, &dctx->index_buffer);
270 if (dctx->index_buffer.buffer)
271 DUMP_M(resource, &dctx->index_buffer, buffer);
272 }
273 if (info->count_from_stream_output)
274 DUMP_M(stream_output_target, info,
275 count_from_stream_output);
276 if (info->indirect)
277 DUMP_M(resource, info, indirect);
278 fprintf(f, "\n");
279
280 /* TODO: dump active queries */
281
282 dd_dump_render_condition(dctx, f);
283
284 for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
285 if (dctx->vertex_buffers[i].buffer ||
286 dctx->vertex_buffers[i].user_buffer) {
287 DUMP_I(vertex_buffer, &dctx->vertex_buffers[i], i);
288 if (dctx->vertex_buffers[i].buffer)
289 DUMP_M(resource, &dctx->vertex_buffers[i], buffer);
290 }
291
292 if (dctx->velems) {
293 print_named_value(f, "num vertex elements",
294 dctx->velems->state.velems.count);
295 for (i = 0; i < dctx->velems->state.velems.count; i++) {
296 fprintf(f, " ");
297 DUMP_I(vertex_element, &dctx->velems->state.velems.velems[i], i);
298 }
299 }
300
301 print_named_value(f, "num stream output targets", dctx->num_so_targets);
302 for (i = 0; i < dctx->num_so_targets; i++)
303 if (dctx->so_targets[i]) {
304 DUMP_I(stream_output_target, dctx->so_targets[i], i);
305 DUMP_M(resource, dctx->so_targets[i], buffer);
306 fprintf(f, " offset = %i\n", dctx->so_offsets[i]);
307 }
308
309 fprintf(f, "\n");
310 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
311 if (sh == PIPE_SHADER_COMPUTE)
312 continue;
313
314 if (sh == PIPE_SHADER_TESS_CTRL &&
315 !dctx->shaders[PIPE_SHADER_TESS_CTRL] &&
316 dctx->shaders[PIPE_SHADER_TESS_EVAL])
317 fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, "
318 "default_inner_level = {%f, %f}}\n",
319 dctx->tess_default_levels[0],
320 dctx->tess_default_levels[1],
321 dctx->tess_default_levels[2],
322 dctx->tess_default_levels[3],
323 dctx->tess_default_levels[4],
324 dctx->tess_default_levels[5]);
325
326 if (sh == PIPE_SHADER_FRAGMENT)
327 if (dctx->rs) {
328 unsigned num_viewports = dd_num_active_viewports(dctx);
329
330 if (dctx->rs->state.rs.clip_plane_enable)
331 DUMP(clip_state, &dctx->clip_state);
332
333 for (i = 0; i < num_viewports; i++)
334 DUMP_I(viewport_state, &dctx->viewports[i], i);
335
336 if (dctx->rs->state.rs.scissor)
337 for (i = 0; i < num_viewports; i++)
338 DUMP_I(scissor_state, &dctx->scissors[i], i);
339
340 DUMP(rasterizer_state, &dctx->rs->state.rs);
341
342 if (dctx->rs->state.rs.poly_stipple_enable)
343 DUMP(poly_stipple, &dctx->polygon_stipple);
344 fprintf(f, "\n");
345 }
346
347 if (!dctx->shaders[sh])
348 continue;
349
350 fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]);
351 DUMP(shader_state, &dctx->shaders[sh]->state.shader);
352
353 for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++)
354 if (dctx->constant_buffers[sh][i].buffer ||
355 dctx->constant_buffers[sh][i].user_buffer) {
356 DUMP_I(constant_buffer, &dctx->constant_buffers[sh][i], i);
357 if (dctx->constant_buffers[sh][i].buffer)
358 DUMP_M(resource, &dctx->constant_buffers[sh][i], buffer);
359 }
360
361 for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
362 if (dctx->sampler_states[sh][i])
363 DUMP_I(sampler_state, &dctx->sampler_states[sh][i]->state.sampler, i);
364
365 for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
366 if (dctx->sampler_views[sh][i]) {
367 DUMP_I(sampler_view, dctx->sampler_views[sh][i], i);
368 DUMP_M(resource, dctx->sampler_views[sh][i], texture);
369 }
370
371 /* TODO: print shader images */
372 /* TODO: print shader buffers */
373
374 fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]);
375 }
376
377 if (dctx->dsa)
378 DUMP(depth_stencil_alpha_state, &dctx->dsa->state.dsa);
379 DUMP(stencil_ref, &dctx->stencil_ref);
380
381 if (dctx->blend)
382 DUMP(blend_state, &dctx->blend->state.blend);
383 DUMP(blend_color, &dctx->blend_color);
384
385 print_named_value(f, "min_samples", dctx->min_samples);
386 print_named_xvalue(f, "sample_mask", dctx->sample_mask);
387 fprintf(f, "\n");
388
389 DUMP(framebuffer_state, &dctx->framebuffer_state);
390 for (i = 0; i < dctx->framebuffer_state.nr_cbufs; i++)
391 if (dctx->framebuffer_state.cbufs[i]) {
392 fprintf(f, " " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n ", i);
393 DUMP(surface, dctx->framebuffer_state.cbufs[i]);
394 fprintf(f, " ");
395 DUMP(resource, dctx->framebuffer_state.cbufs[i]->texture);
396 }
397 if (dctx->framebuffer_state.zsbuf) {
398 fprintf(f, " " COLOR_STATE "zsbuf:" COLOR_RESET "\n ");
399 DUMP(surface, dctx->framebuffer_state.zsbuf);
400 fprintf(f, " ");
401 DUMP(resource, dctx->framebuffer_state.zsbuf->texture);
402 }
403 fprintf(f, "\n");
404 }
405
406 static void
407 dd_dump_launch_grid(struct dd_context *dctx, struct pipe_grid_info *info, FILE *f)
408 {
409 fprintf(f, "%s:\n", __func__+8);
410 /* TODO */
411 }
412
413 static void
414 dd_dump_resource_copy_region(struct dd_context *dctx,
415 struct call_resource_copy_region *info,
416 FILE *f)
417 {
418 fprintf(f, "%s:\n", __func__+8);
419 DUMP_M(resource, info, dst);
420 DUMP_M(uint, info, dst_level);
421 DUMP_M(uint, info, dstx);
422 DUMP_M(uint, info, dsty);
423 DUMP_M(uint, info, dstz);
424 DUMP_M(resource, info, src);
425 DUMP_M(uint, info, src_level);
426 DUMP_M(box, info, src_box);
427 }
428
429 static void
430 dd_dump_blit(struct dd_context *dctx, struct pipe_blit_info *info, FILE *f)
431 {
432 fprintf(f, "%s:\n", __func__+8);
433 DUMP_M(resource, info, dst.resource);
434 DUMP_M(uint, info, dst.level);
435 DUMP_M_ADDR(box, info, dst.box);
436 DUMP_M(format, info, dst.format);
437
438 DUMP_M(resource, info, src.resource);
439 DUMP_M(uint, info, src.level);
440 DUMP_M_ADDR(box, info, src.box);
441 DUMP_M(format, info, src.format);
442
443 DUMP_M(hex, info, mask);
444 DUMP_M(uint, info, filter);
445 DUMP_M(uint, info, scissor_enable);
446 DUMP_M_ADDR(scissor_state, info, scissor);
447 DUMP_M(uint, info, render_condition_enable);
448
449 if (info->render_condition_enable)
450 dd_dump_render_condition(dctx, f);
451 }
452
453 static void
454 dd_dump_generate_mipmap(struct dd_context *dctx, FILE *f)
455 {
456 fprintf(f, "%s:\n", __func__+8);
457 /* TODO */
458 }
459
460 static void
461 dd_dump_flush_resource(struct dd_context *dctx, struct pipe_resource *res,
462 FILE *f)
463 {
464 fprintf(f, "%s:\n", __func__+8);
465 DUMP(resource, res);
466 }
467
468 static void
469 dd_dump_clear(struct dd_context *dctx, struct call_clear *info, FILE *f)
470 {
471 fprintf(f, "%s:\n", __func__+8);
472 DUMP_M(uint, info, buffers);
473 DUMP_M(color_union, info, color);
474 DUMP_M(double, info, depth);
475 DUMP_M(hex, info, stencil);
476 }
477
478 static void
479 dd_dump_clear_buffer(struct dd_context *dctx, struct call_clear_buffer *info,
480 FILE *f)
481 {
482 int i;
483 const char *value = (const char*)info->clear_value;
484
485 fprintf(f, "%s:\n", __func__+8);
486 DUMP_M(resource, info, res);
487 DUMP_M(uint, info, offset);
488 DUMP_M(uint, info, size);
489 DUMP_M(uint, info, clear_value_size);
490
491 fprintf(f, " clear_value:");
492 for (i = 0; i < info->clear_value_size; i++)
493 fprintf(f, " %02x", value[i]);
494 fprintf(f, "\n");
495 }
496
497 static void
498 dd_dump_clear_render_target(struct dd_context *dctx, FILE *f)
499 {
500 fprintf(f, "%s:\n", __func__+8);
501 /* TODO */
502 }
503
504 static void
505 dd_dump_clear_depth_stencil(struct dd_context *dctx, FILE *f)
506 {
507 fprintf(f, "%s:\n", __func__+8);
508 /* TODO */
509 }
510
511 static void
512 dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags)
513 {
514 if (dctx->pipe->dump_debug_state) {
515 fprintf(f,"\n\n**************************************************"
516 "***************************\n");
517 fprintf(f, "Driver-specific state:\n\n");
518 dctx->pipe->dump_debug_state(dctx->pipe, f, flags);
519 }
520 }
521
522 static void
523 dd_dump_call(struct dd_context *dctx, struct dd_call *call, unsigned flags,
524 bool dump_dmesg)
525 {
526 FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen),
527 dctx->apitrace_call_number);
528
529 if (!f)
530 return;
531
532 switch (call->type) {
533 case CALL_DRAW_VBO:
534 dd_dump_draw_vbo(dctx, &call->info.draw_vbo, f);
535 break;
536 case CALL_LAUNCH_GRID:
537 dd_dump_launch_grid(dctx, &call->info.launch_grid, f);
538 break;
539 case CALL_RESOURCE_COPY_REGION:
540 dd_dump_resource_copy_region(dctx, &call->info.resource_copy_region, f);
541 break;
542 case CALL_BLIT:
543 dd_dump_blit(dctx, &call->info.blit, f);
544 break;
545 case CALL_FLUSH_RESOURCE:
546 dd_dump_flush_resource(dctx, call->info.flush_resource, f);
547 break;
548 case CALL_CLEAR:
549 dd_dump_clear(dctx, &call->info.clear, f);
550 break;
551 case CALL_CLEAR_BUFFER:
552 dd_dump_clear_buffer(dctx, &call->info.clear_buffer, f);
553 break;
554 case CALL_CLEAR_RENDER_TARGET:
555 dd_dump_clear_render_target(dctx, f);
556 break;
557 case CALL_CLEAR_DEPTH_STENCIL:
558 dd_dump_clear_depth_stencil(dctx, f);
559 break;
560 case CALL_GENERATE_MIPMAP:
561 dd_dump_generate_mipmap(dctx, f);
562 break;
563 }
564
565 dd_dump_driver_state(dctx, f, flags);
566 if (dump_dmesg)
567 dd_dump_dmesg(f);
568 dd_close_file_stream(f);
569 }
570
571 static void
572 dd_kill_process(void)
573 {
574 sync();
575 fprintf(stderr, "dd: Aborting the process...\n");
576 fflush(stdout);
577 fflush(stderr);
578 exit(1);
579 }
580
581 static bool
582 dd_flush_and_check_hang(struct dd_context *dctx,
583 struct pipe_fence_handle **flush_fence,
584 unsigned flush_flags)
585 {
586 struct pipe_fence_handle *fence = NULL;
587 struct pipe_context *pipe = dctx->pipe;
588 struct pipe_screen *screen = pipe->screen;
589 uint64_t timeout_ms = dd_screen(dctx->base.screen)->timeout_ms;
590 bool idle;
591
592 assert(timeout_ms > 0);
593
594 pipe->flush(pipe, &fence, flush_flags);
595 if (flush_fence)
596 screen->fence_reference(screen, flush_fence, fence);
597 if (!fence)
598 return false;
599
600 idle = screen->fence_finish(screen, fence, timeout_ms * 1000000);
601 screen->fence_reference(screen, &fence, NULL);
602 if (!idle)
603 fprintf(stderr, "dd: GPU hang detected!\n");
604 return !idle;
605 }
606
607 static void
608 dd_flush_and_handle_hang(struct dd_context *dctx,
609 struct pipe_fence_handle **fence, unsigned flags,
610 const char *cause)
611 {
612 if (dd_flush_and_check_hang(dctx, fence, flags)) {
613 FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen),
614 dctx->apitrace_call_number);
615
616 if (f) {
617 fprintf(f, "dd: %s.\n", cause);
618 dd_dump_driver_state(dctx, f,
619 PIPE_DUMP_DEVICE_STATUS_REGISTERS |
620 PIPE_DUMP_CURRENT_STATES |
621 PIPE_DUMP_CURRENT_SHADERS |
622 PIPE_DUMP_LAST_COMMAND_BUFFER);
623 dd_dump_dmesg(f);
624 dd_close_file_stream(f);
625 }
626
627 /* Terminate the process to prevent future hangs. */
628 dd_kill_process();
629 }
630 }
631
632 static void
633 dd_context_flush(struct pipe_context *_pipe,
634 struct pipe_fence_handle **fence, unsigned flags)
635 {
636 struct dd_context *dctx = dd_context(_pipe);
637 struct pipe_context *pipe = dctx->pipe;
638
639 switch (dd_screen(dctx->base.screen)->mode) {
640 case DD_DETECT_HANGS:
641 dd_flush_and_handle_hang(dctx, fence, flags,
642 "GPU hang detected in pipe->flush()");
643 break;
644 case DD_DUMP_ALL_CALLS:
645 case DD_DUMP_APITRACE_CALL:
646 pipe->flush(pipe, fence, flags);
647 break;
648 default:
649 assert(0);
650 }
651 }
652
653 static void
654 dd_before_draw(struct dd_context *dctx)
655 {
656 struct dd_screen *dscreen = dd_screen(dctx->base.screen);
657
658 if (dscreen->mode == DD_DETECT_HANGS &&
659 !dscreen->no_flush &&
660 dctx->num_draw_calls >= dscreen->skip_count)
661 dd_flush_and_handle_hang(dctx, NULL, 0,
662 "GPU hang most likely caused by internal "
663 "driver commands");
664 }
665
666 static void
667 dd_after_draw(struct dd_context *dctx, struct dd_call *call)
668 {
669 struct dd_screen *dscreen = dd_screen(dctx->base.screen);
670 struct pipe_context *pipe = dctx->pipe;
671
672 if (dctx->num_draw_calls >= dscreen->skip_count) {
673 switch (dscreen->mode) {
674 case DD_DETECT_HANGS:
675 if (!dscreen->no_flush &&
676 dd_flush_and_check_hang(dctx, NULL, 0)) {
677 dd_dump_call(dctx, call,
678 PIPE_DUMP_DEVICE_STATUS_REGISTERS |
679 PIPE_DUMP_CURRENT_STATES |
680 PIPE_DUMP_CURRENT_SHADERS |
681 PIPE_DUMP_LAST_COMMAND_BUFFER,
682 true);
683
684 /* Terminate the process to prevent future hangs. */
685 dd_kill_process();
686 }
687 break;
688 case DD_DUMP_ALL_CALLS:
689 if (!dscreen->no_flush)
690 pipe->flush(pipe, NULL, 0);
691 dd_dump_call(dctx, call, 0, false);
692 break;
693 case DD_DUMP_APITRACE_CALL:
694 if (dscreen->apitrace_dump_call == dctx->apitrace_call_number) {
695 dd_dump_call(dctx, call, 0, false);
696 /* No need to continue. */
697 exit(0);
698 }
699 break;
700 default:
701 assert(0);
702 }
703 }
704
705 ++dctx->num_draw_calls;
706 if (dscreen->skip_count && dctx->num_draw_calls % 10000 == 0)
707 fprintf(stderr, "Gallium debugger reached %u draw calls.\n",
708 dctx->num_draw_calls);
709 }
710
711 static void
712 dd_context_draw_vbo(struct pipe_context *_pipe,
713 const struct pipe_draw_info *info)
714 {
715 struct dd_context *dctx = dd_context(_pipe);
716 struct pipe_context *pipe = dctx->pipe;
717 struct dd_call call;
718
719 call.type = CALL_DRAW_VBO;
720 call.info.draw_vbo = *info;
721
722 dd_before_draw(dctx);
723 pipe->draw_vbo(pipe, info);
724 dd_after_draw(dctx, &call);
725 }
726
727 static void
728 dd_context_launch_grid(struct pipe_context *_pipe,
729 const struct pipe_grid_info *info)
730 {
731 struct dd_context *dctx = dd_context(_pipe);
732 struct pipe_context *pipe = dctx->pipe;
733 struct dd_call call;
734
735 call.type = CALL_LAUNCH_GRID;
736 call.info.launch_grid = *info;
737
738 dd_before_draw(dctx);
739 pipe->launch_grid(pipe, info);
740 dd_after_draw(dctx, &call);
741 }
742
743 static void
744 dd_context_resource_copy_region(struct pipe_context *_pipe,
745 struct pipe_resource *dst, unsigned dst_level,
746 unsigned dstx, unsigned dsty, unsigned dstz,
747 struct pipe_resource *src, unsigned src_level,
748 const struct pipe_box *src_box)
749 {
750 struct dd_context *dctx = dd_context(_pipe);
751 struct pipe_context *pipe = dctx->pipe;
752 struct dd_call call;
753
754 call.type = CALL_RESOURCE_COPY_REGION;
755 call.info.resource_copy_region.dst = dst;
756 call.info.resource_copy_region.dst_level = dst_level;
757 call.info.resource_copy_region.dstx = dstx;
758 call.info.resource_copy_region.dsty = dsty;
759 call.info.resource_copy_region.dstz = dstz;
760 call.info.resource_copy_region.src = src;
761 call.info.resource_copy_region.src_level = src_level;
762 call.info.resource_copy_region.src_box = src_box;
763
764 dd_before_draw(dctx);
765 pipe->resource_copy_region(pipe,
766 dst, dst_level, dstx, dsty, dstz,
767 src, src_level, src_box);
768 dd_after_draw(dctx, &call);
769 }
770
771 static void
772 dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
773 {
774 struct dd_context *dctx = dd_context(_pipe);
775 struct pipe_context *pipe = dctx->pipe;
776 struct dd_call call;
777
778 call.type = CALL_BLIT;
779 call.info.blit = *info;
780
781 dd_before_draw(dctx);
782 pipe->blit(pipe, info);
783 dd_after_draw(dctx, &call);
784 }
785
786 static boolean
787 dd_context_generate_mipmap(struct pipe_context *_pipe,
788 struct pipe_resource *res,
789 enum pipe_format format,
790 unsigned base_level,
791 unsigned last_level,
792 unsigned first_layer,
793 unsigned last_layer)
794 {
795 struct dd_context *dctx = dd_context(_pipe);
796 struct pipe_context *pipe = dctx->pipe;
797 struct dd_call call;
798 boolean result;
799
800 call.type = CALL_GENERATE_MIPMAP;
801 call.info.generate_mipmap.res = res;
802 call.info.generate_mipmap.format = format;
803 call.info.generate_mipmap.base_level = base_level;
804 call.info.generate_mipmap.last_level = last_level;
805 call.info.generate_mipmap.first_layer = first_layer;
806 call.info.generate_mipmap.last_layer = last_layer;
807
808 dd_before_draw(dctx);
809 result = pipe->generate_mipmap(pipe, res, format, base_level, last_level,
810 first_layer, last_layer);
811 dd_after_draw(dctx, &call);
812 return result;
813 }
814
815 static void
816 dd_context_flush_resource(struct pipe_context *_pipe,
817 struct pipe_resource *resource)
818 {
819 struct dd_context *dctx = dd_context(_pipe);
820 struct pipe_context *pipe = dctx->pipe;
821 struct dd_call call;
822
823 call.type = CALL_FLUSH_RESOURCE;
824 call.info.flush_resource = resource;
825
826 dd_before_draw(dctx);
827 pipe->flush_resource(pipe, resource);
828 dd_after_draw(dctx, &call);
829 }
830
831 static void
832 dd_context_clear(struct pipe_context *_pipe, unsigned buffers,
833 const union pipe_color_union *color, double depth,
834 unsigned stencil)
835 {
836 struct dd_context *dctx = dd_context(_pipe);
837 struct pipe_context *pipe = dctx->pipe;
838 struct dd_call call;
839
840 call.type = CALL_CLEAR;
841 call.info.clear.buffers = buffers;
842 call.info.clear.color = color;
843 call.info.clear.depth = depth;
844 call.info.clear.stencil = stencil;
845
846 dd_before_draw(dctx);
847 pipe->clear(pipe, buffers, color, depth, stencil);
848 dd_after_draw(dctx, &call);
849 }
850
851 static void
852 dd_context_clear_render_target(struct pipe_context *_pipe,
853 struct pipe_surface *dst,
854 const union pipe_color_union *color,
855 unsigned dstx, unsigned dsty,
856 unsigned width, unsigned height)
857 {
858 struct dd_context *dctx = dd_context(_pipe);
859 struct pipe_context *pipe = dctx->pipe;
860 struct dd_call call;
861
862 call.type = CALL_CLEAR_RENDER_TARGET;
863
864 dd_before_draw(dctx);
865 pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height);
866 dd_after_draw(dctx, &call);
867 }
868
869 static void
870 dd_context_clear_depth_stencil(struct pipe_context *_pipe,
871 struct pipe_surface *dst, unsigned clear_flags,
872 double depth, unsigned stencil, unsigned dstx,
873 unsigned dsty, unsigned width, unsigned height)
874 {
875 struct dd_context *dctx = dd_context(_pipe);
876 struct pipe_context *pipe = dctx->pipe;
877 struct dd_call call;
878
879 call.type = CALL_CLEAR_DEPTH_STENCIL;
880
881 dd_before_draw(dctx);
882 pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
883 dstx, dsty, width, height);
884 dd_after_draw(dctx, &call);
885 }
886
887 static void
888 dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res,
889 unsigned offset, unsigned size,
890 const void *clear_value, int clear_value_size)
891 {
892 struct dd_context *dctx = dd_context(_pipe);
893 struct pipe_context *pipe = dctx->pipe;
894 struct dd_call call;
895
896 call.type = CALL_CLEAR_BUFFER;
897 call.info.clear_buffer.res = res;
898 call.info.clear_buffer.offset = offset;
899 call.info.clear_buffer.size = size;
900 call.info.clear_buffer.clear_value = clear_value;
901 call.info.clear_buffer.clear_value_size = clear_value_size;
902
903 dd_before_draw(dctx);
904 pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size);
905 dd_after_draw(dctx, &call);
906 }
907
908 void
909 dd_init_draw_functions(struct dd_context *dctx)
910 {
911 CTX_INIT(flush);
912 CTX_INIT(draw_vbo);
913 CTX_INIT(launch_grid);
914 CTX_INIT(resource_copy_region);
915 CTX_INIT(blit);
916 CTX_INIT(clear);
917 CTX_INIT(clear_render_target);
918 CTX_INIT(clear_depth_stencil);
919 CTX_INIT(clear_buffer);
920 CTX_INIT(flush_resource);
921 CTX_INIT(generate_mipmap);
922 }