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