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