1 /**************************************************************************
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
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:
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
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.
26 **************************************************************************/
30 #include "util/u_dump.h"
31 #include "util/u_format.h"
32 #include "util/u_framebuffer.h"
33 #include "util/u_helpers.h"
34 #include "util/u_inlines.h"
35 #include "util/u_memory.h"
36 #include "util/u_process.h"
37 #include "tgsi/tgsi_parse.h"
38 #include "tgsi/tgsi_scan.h"
39 #include "util/os_time.h"
41 #include "pipe/p_config.h"
44 dd_get_debug_filename_and_mkdir(char *buf
, size_t buflen
, bool verbose
)
46 static unsigned index
;
47 char proc_name
[128], dir
[256];
49 if (!os_get_process_name(proc_name
, sizeof(proc_name
))) {
50 fprintf(stderr
, "dd: can't get the process name\n");
51 strcpy(proc_name
, "unknown");
54 snprintf(dir
, sizeof(dir
), "%s/"DD_DIR
, debug_get_option("HOME", "."));
56 if (mkdir(dir
, 0774) && errno
!= EEXIST
)
57 fprintf(stderr
, "dd: can't create a directory (%i)\n", errno
);
59 snprintf(buf
, buflen
, "%s/%s_%u_%08u", dir
, proc_name
, getpid(),
60 p_atomic_inc_return(&index
) - 1);
63 fprintf(stderr
, "dd: dumping to file %s\n", buf
);
67 dd_get_debug_file(bool verbose
)
72 dd_get_debug_filename_and_mkdir(name
, sizeof(name
), verbose
);
75 fprintf(stderr
, "dd: can't open file %s\n", name
);
83 dd_parse_apitrace_marker(const char *string
, int len
, unsigned *call_number
)
91 /* Make it zero-terminated. */
93 memcpy(s
, string
, len
);
96 /* Parse the number. */
98 num
= strtol(s
, NULL
, 10);
106 dd_write_header(FILE *f
, struct pipe_screen
*screen
, unsigned apitrace_call_number
)
109 if (os_get_command_line(cmd_line
, sizeof(cmd_line
)))
110 fprintf(f
, "Command: %s\n", cmd_line
);
111 fprintf(f
, "Driver vendor: %s\n", screen
->get_vendor(screen
));
112 fprintf(f
, "Device vendor: %s\n", screen
->get_device_vendor(screen
));
113 fprintf(f
, "Device name: %s\n\n", screen
->get_name(screen
));
115 if (apitrace_call_number
)
116 fprintf(f
, "Last apitrace call: %u\n\n", apitrace_call_number
);
120 dd_get_file_stream(struct dd_screen
*dscreen
, unsigned apitrace_call_number
)
122 struct pipe_screen
*screen
= dscreen
->screen
;
124 FILE *f
= dd_get_debug_file(dscreen
->verbose
);
128 dd_write_header(f
, screen
, apitrace_call_number
);
133 dd_dump_dmesg(FILE *f
)
137 FILE *p
= popen("dmesg | tail -n60", "r");
142 fprintf(f
, "\nLast 60 lines of dmesg:\n\n");
143 while (fgets(line
, sizeof(line
), p
))
151 dd_num_active_viewports(struct dd_draw_state
*dstate
)
153 struct tgsi_shader_info info
;
154 const struct tgsi_token
*tokens
;
156 if (dstate
->shaders
[PIPE_SHADER_GEOMETRY
])
157 tokens
= dstate
->shaders
[PIPE_SHADER_GEOMETRY
]->state
.shader
.tokens
;
158 else if (dstate
->shaders
[PIPE_SHADER_TESS_EVAL
])
159 tokens
= dstate
->shaders
[PIPE_SHADER_TESS_EVAL
]->state
.shader
.tokens
;
160 else if (dstate
->shaders
[PIPE_SHADER_VERTEX
])
161 tokens
= dstate
->shaders
[PIPE_SHADER_VERTEX
]->state
.shader
.tokens
;
166 tgsi_scan_shader(tokens
, &info
);
167 if (info
.writes_viewport_index
)
168 return PIPE_MAX_VIEWPORTS
;
174 #define COLOR_RESET "\033[0m"
175 #define COLOR_SHADER "\033[1;32m"
176 #define COLOR_STATE "\033[1;33m"
178 #define DUMP(name, var) do { \
179 fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \
180 util_dump_##name(f, var); \
184 #define DUMP_I(name, var, i) do { \
185 fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \
186 util_dump_##name(f, var); \
190 #define DUMP_M(name, var, member) do { \
191 fprintf(f, " " #member ": "); \
192 util_dump_##name(f, (var)->member); \
196 #define DUMP_M_ADDR(name, var, member) do { \
197 fprintf(f, " " #member ": "); \
198 util_dump_##name(f, &(var)->member); \
202 #define PRINT_NAMED(type, name, value) \
204 fprintf(f, COLOR_STATE "%s" COLOR_RESET " = ", name); \
205 util_dump_##type(f, value); \
210 util_dump_uint(FILE *f
, unsigned i
)
216 util_dump_int(FILE *f
, int i
)
222 util_dump_hex(FILE *f
, unsigned i
)
224 fprintf(f
, "0x%x", i
);
228 util_dump_double(FILE *f
, double d
)
234 util_dump_format(FILE *f
, enum pipe_format format
)
236 fprintf(f
, "%s", util_format_name(format
));
240 util_dump_color_union(FILE *f
, const union pipe_color_union
*color
)
242 fprintf(f
, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}",
243 color
->f
[0], color
->f
[1], color
->f
[2], color
->f
[3],
244 color
->ui
[0], color
->ui
[1], color
->ui
[2], color
->ui
[3]);
248 dd_dump_render_condition(struct dd_draw_state
*dstate
, FILE *f
)
250 if (dstate
->render_cond
.query
) {
251 fprintf(f
, "render condition:\n");
252 DUMP_M(query_type
, &dstate
->render_cond
, query
->type
);
253 DUMP_M(uint
, &dstate
->render_cond
, condition
);
254 DUMP_M(uint
, &dstate
->render_cond
, mode
);
260 dd_dump_shader(struct dd_draw_state
*dstate
, enum pipe_shader_type sh
, FILE *f
)
263 const char *shader_str
[PIPE_SHADER_TYPES
];
265 shader_str
[PIPE_SHADER_VERTEX
] = "VERTEX";
266 shader_str
[PIPE_SHADER_TESS_CTRL
] = "TESS_CTRL";
267 shader_str
[PIPE_SHADER_TESS_EVAL
] = "TESS_EVAL";
268 shader_str
[PIPE_SHADER_GEOMETRY
] = "GEOMETRY";
269 shader_str
[PIPE_SHADER_FRAGMENT
] = "FRAGMENT";
270 shader_str
[PIPE_SHADER_COMPUTE
] = "COMPUTE";
272 if (sh
== PIPE_SHADER_TESS_CTRL
&&
273 !dstate
->shaders
[PIPE_SHADER_TESS_CTRL
] &&
274 dstate
->shaders
[PIPE_SHADER_TESS_EVAL
])
275 fprintf(f
, "tess_state: {default_outer_level = {%f, %f, %f, %f}, "
276 "default_inner_level = {%f, %f}}\n",
277 dstate
->tess_default_levels
[0],
278 dstate
->tess_default_levels
[1],
279 dstate
->tess_default_levels
[2],
280 dstate
->tess_default_levels
[3],
281 dstate
->tess_default_levels
[4],
282 dstate
->tess_default_levels
[5]);
284 if (sh
== PIPE_SHADER_FRAGMENT
)
286 unsigned num_viewports
= dd_num_active_viewports(dstate
);
288 if (dstate
->rs
->state
.rs
.clip_plane_enable
)
289 DUMP(clip_state
, &dstate
->clip_state
);
291 for (i
= 0; i
< num_viewports
; i
++)
292 DUMP_I(viewport_state
, &dstate
->viewports
[i
], i
);
294 if (dstate
->rs
->state
.rs
.scissor
)
295 for (i
= 0; i
< num_viewports
; i
++)
296 DUMP_I(scissor_state
, &dstate
->scissors
[i
], i
);
298 DUMP(rasterizer_state
, &dstate
->rs
->state
.rs
);
300 if (dstate
->rs
->state
.rs
.poly_stipple_enable
)
301 DUMP(poly_stipple
, &dstate
->polygon_stipple
);
305 if (!dstate
->shaders
[sh
])
308 fprintf(f
, COLOR_SHADER
"begin shader: %s" COLOR_RESET
"\n", shader_str
[sh
]);
309 DUMP(shader_state
, &dstate
->shaders
[sh
]->state
.shader
);
311 for (i
= 0; i
< PIPE_MAX_CONSTANT_BUFFERS
; i
++)
312 if (dstate
->constant_buffers
[sh
][i
].buffer
||
313 dstate
->constant_buffers
[sh
][i
].user_buffer
) {
314 DUMP_I(constant_buffer
, &dstate
->constant_buffers
[sh
][i
], i
);
315 if (dstate
->constant_buffers
[sh
][i
].buffer
)
316 DUMP_M(resource
, &dstate
->constant_buffers
[sh
][i
], buffer
);
319 for (i
= 0; i
< PIPE_MAX_SAMPLERS
; i
++)
320 if (dstate
->sampler_states
[sh
][i
])
321 DUMP_I(sampler_state
, &dstate
->sampler_states
[sh
][i
]->state
.sampler
, i
);
323 for (i
= 0; i
< PIPE_MAX_SAMPLERS
; i
++)
324 if (dstate
->sampler_views
[sh
][i
]) {
325 DUMP_I(sampler_view
, dstate
->sampler_views
[sh
][i
], i
);
326 DUMP_M(resource
, dstate
->sampler_views
[sh
][i
], texture
);
329 for (i
= 0; i
< PIPE_MAX_SHADER_IMAGES
; i
++)
330 if (dstate
->shader_images
[sh
][i
].resource
) {
331 DUMP_I(image_view
, &dstate
->shader_images
[sh
][i
], i
);
332 if (dstate
->shader_images
[sh
][i
].resource
)
333 DUMP_M(resource
, &dstate
->shader_images
[sh
][i
], resource
);
336 for (i
= 0; i
< PIPE_MAX_SHADER_BUFFERS
; i
++)
337 if (dstate
->shader_buffers
[sh
][i
].buffer
) {
338 DUMP_I(shader_buffer
, &dstate
->shader_buffers
[sh
][i
], i
);
339 if (dstate
->shader_buffers
[sh
][i
].buffer
)
340 DUMP_M(resource
, &dstate
->shader_buffers
[sh
][i
], buffer
);
343 fprintf(f
, COLOR_SHADER
"end shader: %s" COLOR_RESET
"\n\n", shader_str
[sh
]);
347 dd_dump_flush(struct dd_draw_state
*dstate
, struct call_flush
*info
, FILE *f
)
349 fprintf(f
, "%s:\n", __func__
+8);
350 DUMP_M(hex
, info
, flags
);
354 dd_dump_draw_vbo(struct dd_draw_state
*dstate
, struct pipe_draw_info
*info
, FILE *f
)
358 DUMP(draw_info
, info
);
359 if (info
->count_from_stream_output
)
360 DUMP_M(stream_output_target
, info
,
361 count_from_stream_output
);
362 if (info
->indirect
) {
363 DUMP_M(resource
, info
, indirect
->buffer
);
364 if (info
->indirect
->indirect_draw_count
)
365 DUMP_M(resource
, info
, indirect
->indirect_draw_count
);
370 /* TODO: dump active queries */
372 dd_dump_render_condition(dstate
, f
);
374 for (i
= 0; i
< PIPE_MAX_ATTRIBS
; i
++)
375 if (dstate
->vertex_buffers
[i
].buffer
.resource
) {
376 DUMP_I(vertex_buffer
, &dstate
->vertex_buffers
[i
], i
);
377 if (!dstate
->vertex_buffers
[i
].is_user_buffer
)
378 DUMP_M(resource
, &dstate
->vertex_buffers
[i
], buffer
.resource
);
381 if (dstate
->velems
) {
382 PRINT_NAMED(uint
, "num vertex elements",
383 dstate
->velems
->state
.velems
.count
);
384 for (i
= 0; i
< dstate
->velems
->state
.velems
.count
; i
++) {
386 DUMP_I(vertex_element
, &dstate
->velems
->state
.velems
.velems
[i
], i
);
390 PRINT_NAMED(uint
, "num stream output targets", dstate
->num_so_targets
);
391 for (i
= 0; i
< dstate
->num_so_targets
; i
++)
392 if (dstate
->so_targets
[i
]) {
393 DUMP_I(stream_output_target
, dstate
->so_targets
[i
], i
);
394 DUMP_M(resource
, dstate
->so_targets
[i
], buffer
);
395 fprintf(f
, " offset = %i\n", dstate
->so_offsets
[i
]);
399 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
400 if (sh
== PIPE_SHADER_COMPUTE
)
403 dd_dump_shader(dstate
, sh
, f
);
407 DUMP(depth_stencil_alpha_state
, &dstate
->dsa
->state
.dsa
);
408 DUMP(stencil_ref
, &dstate
->stencil_ref
);
411 DUMP(blend_state
, &dstate
->blend
->state
.blend
);
412 DUMP(blend_color
, &dstate
->blend_color
);
414 PRINT_NAMED(uint
, "min_samples", dstate
->min_samples
);
415 PRINT_NAMED(hex
, "sample_mask", dstate
->sample_mask
);
418 DUMP(framebuffer_state
, &dstate
->framebuffer_state
);
419 for (i
= 0; i
< dstate
->framebuffer_state
.nr_cbufs
; i
++)
420 if (dstate
->framebuffer_state
.cbufs
[i
]) {
421 fprintf(f
, " " COLOR_STATE
"cbufs[%i]:" COLOR_RESET
"\n ", i
);
422 DUMP(surface
, dstate
->framebuffer_state
.cbufs
[i
]);
424 DUMP(resource
, dstate
->framebuffer_state
.cbufs
[i
]->texture
);
426 if (dstate
->framebuffer_state
.zsbuf
) {
427 fprintf(f
, " " COLOR_STATE
"zsbuf:" COLOR_RESET
"\n ");
428 DUMP(surface
, dstate
->framebuffer_state
.zsbuf
);
430 DUMP(resource
, dstate
->framebuffer_state
.zsbuf
->texture
);
436 dd_dump_launch_grid(struct dd_draw_state
*dstate
, struct pipe_grid_info
*info
, FILE *f
)
438 fprintf(f
, "%s:\n", __func__
+8);
439 DUMP(grid_info
, info
);
442 dd_dump_shader(dstate
, PIPE_SHADER_COMPUTE
, f
);
447 dd_dump_resource_copy_region(struct dd_draw_state
*dstate
,
448 struct call_resource_copy_region
*info
,
451 fprintf(f
, "%s:\n", __func__
+8);
452 DUMP_M(resource
, info
, dst
);
453 DUMP_M(uint
, info
, dst_level
);
454 DUMP_M(uint
, info
, dstx
);
455 DUMP_M(uint
, info
, dsty
);
456 DUMP_M(uint
, info
, dstz
);
457 DUMP_M(resource
, info
, src
);
458 DUMP_M(uint
, info
, src_level
);
459 DUMP_M_ADDR(box
, info
, src_box
);
463 dd_dump_blit(struct dd_draw_state
*dstate
, struct pipe_blit_info
*info
, FILE *f
)
465 fprintf(f
, "%s:\n", __func__
+8);
466 DUMP_M(resource
, info
, dst
.resource
);
467 DUMP_M(uint
, info
, dst
.level
);
468 DUMP_M_ADDR(box
, info
, dst
.box
);
469 DUMP_M(format
, info
, dst
.format
);
471 DUMP_M(resource
, info
, src
.resource
);
472 DUMP_M(uint
, info
, src
.level
);
473 DUMP_M_ADDR(box
, info
, src
.box
);
474 DUMP_M(format
, info
, src
.format
);
476 DUMP_M(hex
, info
, mask
);
477 DUMP_M(uint
, info
, filter
);
478 DUMP_M(uint
, info
, scissor_enable
);
479 DUMP_M_ADDR(scissor_state
, info
, scissor
);
480 DUMP_M(uint
, info
, render_condition_enable
);
482 if (info
->render_condition_enable
)
483 dd_dump_render_condition(dstate
, f
);
487 dd_dump_generate_mipmap(struct dd_draw_state
*dstate
, FILE *f
)
489 fprintf(f
, "%s:\n", __func__
+8);
494 dd_dump_get_query_result_resource(struct call_get_query_result_resource
*info
, FILE *f
)
496 fprintf(f
, "%s:\n", __func__
+ 8);
497 DUMP_M(query_type
, info
, query_type
);
498 DUMP_M(uint
, info
, wait
);
499 DUMP_M(query_value_type
, info
, result_type
);
500 DUMP_M(int, info
, index
);
501 DUMP_M(resource
, info
, resource
);
502 DUMP_M(uint
, info
, offset
);
506 dd_dump_flush_resource(struct dd_draw_state
*dstate
, struct pipe_resource
*res
,
509 fprintf(f
, "%s:\n", __func__
+8);
514 dd_dump_clear(struct dd_draw_state
*dstate
, struct call_clear
*info
, FILE *f
)
516 fprintf(f
, "%s:\n", __func__
+8);
517 DUMP_M(uint
, info
, buffers
);
518 DUMP_M_ADDR(color_union
, info
, color
);
519 DUMP_M(double, info
, depth
);
520 DUMP_M(hex
, info
, stencil
);
524 dd_dump_clear_buffer(struct dd_draw_state
*dstate
, struct call_clear_buffer
*info
,
528 const char *value
= (const char*)info
->clear_value
;
530 fprintf(f
, "%s:\n", __func__
+8);
531 DUMP_M(resource
, info
, res
);
532 DUMP_M(uint
, info
, offset
);
533 DUMP_M(uint
, info
, size
);
534 DUMP_M(uint
, info
, clear_value_size
);
536 fprintf(f
, " clear_value:");
537 for (i
= 0; i
< info
->clear_value_size
; i
++)
538 fprintf(f
, " %02x", value
[i
]);
543 dd_dump_transfer_map(struct call_transfer_map
*info
, FILE *f
)
545 fprintf(f
, "%s:\n", __func__
+8);
546 DUMP_M_ADDR(transfer
, info
, transfer
);
547 DUMP_M(ptr
, info
, transfer_ptr
);
548 DUMP_M(ptr
, info
, ptr
);
552 dd_dump_transfer_flush_region(struct call_transfer_flush_region
*info
, FILE *f
)
554 fprintf(f
, "%s:\n", __func__
+8);
555 DUMP_M_ADDR(transfer
, info
, transfer
);
556 DUMP_M(ptr
, info
, transfer_ptr
);
557 DUMP_M_ADDR(box
, info
, box
);
561 dd_dump_transfer_unmap(struct call_transfer_unmap
*info
, FILE *f
)
563 fprintf(f
, "%s:\n", __func__
+8);
564 DUMP_M_ADDR(transfer
, info
, transfer
);
565 DUMP_M(ptr
, info
, transfer_ptr
);
569 dd_dump_buffer_subdata(struct call_buffer_subdata
*info
, FILE *f
)
571 fprintf(f
, "%s:\n", __func__
+8);
572 DUMP_M(resource
, info
, resource
);
573 DUMP_M(transfer_usage
, info
, usage
);
574 DUMP_M(uint
, info
, offset
);
575 DUMP_M(uint
, info
, size
);
576 DUMP_M(ptr
, info
, data
);
580 dd_dump_texture_subdata(struct call_texture_subdata
*info
, FILE *f
)
582 fprintf(f
, "%s:\n", __func__
+8);
583 DUMP_M(resource
, info
, resource
);
584 DUMP_M(uint
, info
, level
);
585 DUMP_M(transfer_usage
, info
, usage
);
586 DUMP_M_ADDR(box
, info
, box
);
587 DUMP_M(ptr
, info
, data
);
588 DUMP_M(uint
, info
, stride
);
589 DUMP_M(uint
, info
, layer_stride
);
593 dd_dump_clear_texture(struct dd_draw_state
*dstate
, FILE *f
)
595 fprintf(f
, "%s:\n", __func__
+8);
600 dd_dump_clear_render_target(struct dd_draw_state
*dstate
, FILE *f
)
602 fprintf(f
, "%s:\n", __func__
+8);
607 dd_dump_clear_depth_stencil(struct dd_draw_state
*dstate
, FILE *f
)
609 fprintf(f
, "%s:\n", __func__
+8);
614 dd_dump_driver_state(struct dd_context
*dctx
, FILE *f
, unsigned flags
)
616 if (dctx
->pipe
->dump_debug_state
) {
617 fprintf(f
,"\n\n**************************************************"
618 "***************************\n");
619 fprintf(f
, "Driver-specific state:\n\n");
620 dctx
->pipe
->dump_debug_state(dctx
->pipe
, f
, flags
);
625 dd_dump_call(FILE *f
, struct dd_draw_state
*state
, struct dd_call
*call
)
627 switch (call
->type
) {
629 dd_dump_flush(state
, &call
->info
.flush
, f
);
632 dd_dump_draw_vbo(state
, &call
->info
.draw_vbo
.draw
, f
);
634 case CALL_LAUNCH_GRID
:
635 dd_dump_launch_grid(state
, &call
->info
.launch_grid
, f
);
637 case CALL_RESOURCE_COPY_REGION
:
638 dd_dump_resource_copy_region(state
,
639 &call
->info
.resource_copy_region
, f
);
642 dd_dump_blit(state
, &call
->info
.blit
, f
);
644 case CALL_FLUSH_RESOURCE
:
645 dd_dump_flush_resource(state
, call
->info
.flush_resource
, f
);
648 dd_dump_clear(state
, &call
->info
.clear
, f
);
650 case CALL_CLEAR_BUFFER
:
651 dd_dump_clear_buffer(state
, &call
->info
.clear_buffer
, f
);
653 case CALL_CLEAR_TEXTURE
:
654 dd_dump_clear_texture(state
, f
);
656 case CALL_CLEAR_RENDER_TARGET
:
657 dd_dump_clear_render_target(state
, f
);
659 case CALL_CLEAR_DEPTH_STENCIL
:
660 dd_dump_clear_depth_stencil(state
, f
);
662 case CALL_GENERATE_MIPMAP
:
663 dd_dump_generate_mipmap(state
, f
);
665 case CALL_GET_QUERY_RESULT_RESOURCE
:
666 dd_dump_get_query_result_resource(&call
->info
.get_query_result_resource
, f
);
668 case CALL_TRANSFER_MAP
:
669 dd_dump_transfer_map(&call
->info
.transfer_map
, f
);
671 case CALL_TRANSFER_FLUSH_REGION
:
672 dd_dump_transfer_flush_region(&call
->info
.transfer_flush_region
, f
);
674 case CALL_TRANSFER_UNMAP
:
675 dd_dump_transfer_unmap(&call
->info
.transfer_unmap
, f
);
677 case CALL_BUFFER_SUBDATA
:
678 dd_dump_buffer_subdata(&call
->info
.buffer_subdata
, f
);
680 case CALL_TEXTURE_SUBDATA
:
681 dd_dump_texture_subdata(&call
->info
.texture_subdata
, f
);
687 dd_kill_process(void)
692 fprintf(stderr
, "dd: Aborting the process...\n");
699 dd_unreference_copy_of_call(struct dd_call
*dst
)
705 pipe_so_target_reference(&dst
->info
.draw_vbo
.draw
.count_from_stream_output
, NULL
);
706 pipe_resource_reference(&dst
->info
.draw_vbo
.indirect
.buffer
, NULL
);
707 pipe_resource_reference(&dst
->info
.draw_vbo
.indirect
.indirect_draw_count
, NULL
);
708 if (dst
->info
.draw_vbo
.draw
.index_size
&&
709 !dst
->info
.draw_vbo
.draw
.has_user_indices
)
710 pipe_resource_reference(&dst
->info
.draw_vbo
.draw
.index
.resource
, NULL
);
712 dst
->info
.draw_vbo
.draw
.index
.user
= NULL
;
714 case CALL_LAUNCH_GRID
:
715 pipe_resource_reference(&dst
->info
.launch_grid
.indirect
, NULL
);
717 case CALL_RESOURCE_COPY_REGION
:
718 pipe_resource_reference(&dst
->info
.resource_copy_region
.dst
, NULL
);
719 pipe_resource_reference(&dst
->info
.resource_copy_region
.src
, NULL
);
722 pipe_resource_reference(&dst
->info
.blit
.dst
.resource
, NULL
);
723 pipe_resource_reference(&dst
->info
.blit
.src
.resource
, NULL
);
725 case CALL_FLUSH_RESOURCE
:
726 pipe_resource_reference(&dst
->info
.flush_resource
, NULL
);
730 case CALL_CLEAR_BUFFER
:
731 pipe_resource_reference(&dst
->info
.clear_buffer
.res
, NULL
);
733 case CALL_CLEAR_TEXTURE
:
735 case CALL_CLEAR_RENDER_TARGET
:
737 case CALL_CLEAR_DEPTH_STENCIL
:
739 case CALL_GENERATE_MIPMAP
:
740 pipe_resource_reference(&dst
->info
.generate_mipmap
.res
, NULL
);
742 case CALL_GET_QUERY_RESULT_RESOURCE
:
743 pipe_resource_reference(&dst
->info
.get_query_result_resource
.resource
, NULL
);
745 case CALL_TRANSFER_MAP
:
746 pipe_resource_reference(&dst
->info
.transfer_map
.transfer
.resource
, NULL
);
748 case CALL_TRANSFER_FLUSH_REGION
:
749 pipe_resource_reference(&dst
->info
.transfer_flush_region
.transfer
.resource
, NULL
);
751 case CALL_TRANSFER_UNMAP
:
752 pipe_resource_reference(&dst
->info
.transfer_unmap
.transfer
.resource
, NULL
);
754 case CALL_BUFFER_SUBDATA
:
755 pipe_resource_reference(&dst
->info
.buffer_subdata
.resource
, NULL
);
757 case CALL_TEXTURE_SUBDATA
:
758 pipe_resource_reference(&dst
->info
.texture_subdata
.resource
, NULL
);
764 dd_init_copy_of_draw_state(struct dd_draw_state_copy
*state
)
768 /* Just clear pointers to gallium objects. Don't clear the whole structure,
769 * because it would kill performance with its size of 130 KB.
771 memset(state
->base
.vertex_buffers
, 0,
772 sizeof(state
->base
.vertex_buffers
));
773 memset(state
->base
.so_targets
, 0,
774 sizeof(state
->base
.so_targets
));
775 memset(state
->base
.constant_buffers
, 0,
776 sizeof(state
->base
.constant_buffers
));
777 memset(state
->base
.sampler_views
, 0,
778 sizeof(state
->base
.sampler_views
));
779 memset(state
->base
.shader_images
, 0,
780 sizeof(state
->base
.shader_images
));
781 memset(state
->base
.shader_buffers
, 0,
782 sizeof(state
->base
.shader_buffers
));
783 memset(&state
->base
.framebuffer_state
, 0,
784 sizeof(state
->base
.framebuffer_state
));
786 memset(state
->shaders
, 0, sizeof(state
->shaders
));
788 state
->base
.render_cond
.query
= &state
->render_cond
;
790 for (i
= 0; i
< PIPE_SHADER_TYPES
; i
++) {
791 state
->base
.shaders
[i
] = &state
->shaders
[i
];
792 for (j
= 0; j
< PIPE_MAX_SAMPLERS
; j
++)
793 state
->base
.sampler_states
[i
][j
] = &state
->sampler_states
[i
][j
];
796 state
->base
.velems
= &state
->velems
;
797 state
->base
.rs
= &state
->rs
;
798 state
->base
.dsa
= &state
->dsa
;
799 state
->base
.blend
= &state
->blend
;
803 dd_unreference_copy_of_draw_state(struct dd_draw_state_copy
*state
)
805 struct dd_draw_state
*dst
= &state
->base
;
808 for (i
= 0; i
< ARRAY_SIZE(dst
->vertex_buffers
); i
++)
809 pipe_vertex_buffer_unreference(&dst
->vertex_buffers
[i
]);
810 for (i
= 0; i
< ARRAY_SIZE(dst
->so_targets
); i
++)
811 pipe_so_target_reference(&dst
->so_targets
[i
], NULL
);
813 for (i
= 0; i
< PIPE_SHADER_TYPES
; i
++) {
815 tgsi_free_tokens(dst
->shaders
[i
]->state
.shader
.tokens
);
817 for (j
= 0; j
< PIPE_MAX_CONSTANT_BUFFERS
; j
++)
818 pipe_resource_reference(&dst
->constant_buffers
[i
][j
].buffer
, NULL
);
819 for (j
= 0; j
< PIPE_MAX_SAMPLERS
; j
++)
820 pipe_sampler_view_reference(&dst
->sampler_views
[i
][j
], NULL
);
821 for (j
= 0; j
< PIPE_MAX_SHADER_IMAGES
; j
++)
822 pipe_resource_reference(&dst
->shader_images
[i
][j
].resource
, NULL
);
823 for (j
= 0; j
< PIPE_MAX_SHADER_BUFFERS
; j
++)
824 pipe_resource_reference(&dst
->shader_buffers
[i
][j
].buffer
, NULL
);
827 util_unreference_framebuffer_state(&dst
->framebuffer_state
);
831 dd_copy_draw_state(struct dd_draw_state
*dst
, struct dd_draw_state
*src
)
835 if (src
->render_cond
.query
) {
836 *dst
->render_cond
.query
= *src
->render_cond
.query
;
837 dst
->render_cond
.condition
= src
->render_cond
.condition
;
838 dst
->render_cond
.mode
= src
->render_cond
.mode
;
840 dst
->render_cond
.query
= NULL
;
843 for (i
= 0; i
< ARRAY_SIZE(src
->vertex_buffers
); i
++) {
844 pipe_vertex_buffer_reference(&dst
->vertex_buffers
[i
],
845 &src
->vertex_buffers
[i
]);
848 dst
->num_so_targets
= src
->num_so_targets
;
849 for (i
= 0; i
< src
->num_so_targets
; i
++)
850 pipe_so_target_reference(&dst
->so_targets
[i
], src
->so_targets
[i
]);
851 memcpy(dst
->so_offsets
, src
->so_offsets
, sizeof(src
->so_offsets
));
853 for (i
= 0; i
< PIPE_SHADER_TYPES
; i
++) {
854 if (!src
->shaders
[i
]) {
855 dst
->shaders
[i
] = NULL
;
859 if (src
->shaders
[i
]) {
860 dst
->shaders
[i
]->state
.shader
= src
->shaders
[i
]->state
.shader
;
861 if (src
->shaders
[i
]->state
.shader
.tokens
) {
862 dst
->shaders
[i
]->state
.shader
.tokens
=
863 tgsi_dup_tokens(src
->shaders
[i
]->state
.shader
.tokens
);
865 dst
->shaders
[i
]->state
.shader
.ir
.nir
= NULL
;
868 dst
->shaders
[i
] = NULL
;
871 for (j
= 0; j
< PIPE_MAX_CONSTANT_BUFFERS
; j
++) {
872 pipe_resource_reference(&dst
->constant_buffers
[i
][j
].buffer
,
873 src
->constant_buffers
[i
][j
].buffer
);
874 memcpy(&dst
->constant_buffers
[i
][j
], &src
->constant_buffers
[i
][j
],
875 sizeof(src
->constant_buffers
[i
][j
]));
878 for (j
= 0; j
< PIPE_MAX_SAMPLERS
; j
++) {
879 pipe_sampler_view_reference(&dst
->sampler_views
[i
][j
],
880 src
->sampler_views
[i
][j
]);
881 if (src
->sampler_states
[i
][j
])
882 dst
->sampler_states
[i
][j
]->state
.sampler
=
883 src
->sampler_states
[i
][j
]->state
.sampler
;
885 dst
->sampler_states
[i
][j
] = NULL
;
888 for (j
= 0; j
< PIPE_MAX_SHADER_IMAGES
; j
++) {
889 pipe_resource_reference(&dst
->shader_images
[i
][j
].resource
,
890 src
->shader_images
[i
][j
].resource
);
891 memcpy(&dst
->shader_images
[i
][j
], &src
->shader_images
[i
][j
],
892 sizeof(src
->shader_images
[i
][j
]));
895 for (j
= 0; j
< PIPE_MAX_SHADER_BUFFERS
; j
++) {
896 pipe_resource_reference(&dst
->shader_buffers
[i
][j
].buffer
,
897 src
->shader_buffers
[i
][j
].buffer
);
898 memcpy(&dst
->shader_buffers
[i
][j
], &src
->shader_buffers
[i
][j
],
899 sizeof(src
->shader_buffers
[i
][j
]));
904 dst
->velems
->state
.velems
= src
->velems
->state
.velems
;
909 dst
->rs
->state
.rs
= src
->rs
->state
.rs
;
914 dst
->dsa
->state
.dsa
= src
->dsa
->state
.dsa
;
919 dst
->blend
->state
.blend
= src
->blend
->state
.blend
;
923 dst
->blend_color
= src
->blend_color
;
924 dst
->stencil_ref
= src
->stencil_ref
;
925 dst
->sample_mask
= src
->sample_mask
;
926 dst
->min_samples
= src
->min_samples
;
927 dst
->clip_state
= src
->clip_state
;
928 util_copy_framebuffer_state(&dst
->framebuffer_state
, &src
->framebuffer_state
);
929 memcpy(dst
->scissors
, src
->scissors
, sizeof(src
->scissors
));
930 memcpy(dst
->viewports
, src
->viewports
, sizeof(src
->viewports
));
931 memcpy(dst
->tess_default_levels
, src
->tess_default_levels
,
932 sizeof(src
->tess_default_levels
));
933 dst
->apitrace_call_number
= src
->apitrace_call_number
;
937 dd_free_record(struct pipe_screen
*screen
, struct dd_draw_record
*record
)
939 u_log_page_destroy(record
->log_page
);
940 dd_unreference_copy_of_call(&record
->call
);
941 dd_unreference_copy_of_draw_state(&record
->draw_state
);
942 screen
->fence_reference(screen
, &record
->prev_bottom_of_pipe
, NULL
);
943 screen
->fence_reference(screen
, &record
->top_of_pipe
, NULL
);
944 screen
->fence_reference(screen
, &record
->bottom_of_pipe
, NULL
);
945 util_queue_fence_destroy(&record
->driver_finished
);
950 dd_write_record(FILE *f
, struct dd_draw_record
*record
)
952 PRINT_NAMED(ptr
, "pipe", record
->dctx
->pipe
);
953 PRINT_NAMED(ns
, "time before (API call)", record
->time_before
);
954 PRINT_NAMED(ns
, "time after (driver done)", record
->time_after
);
957 dd_dump_call(f
, &record
->draw_state
.base
, &record
->call
);
959 if (record
->log_page
) {
960 fprintf(f
,"\n\n**************************************************"
961 "***************************\n");
962 fprintf(f
, "Context Log:\n\n");
963 u_log_page_print(record
->log_page
, f
);
968 dd_maybe_dump_record(struct dd_screen
*dscreen
, struct dd_draw_record
*record
)
970 if (dscreen
->dump_mode
== DD_DUMP_ONLY_HANGS
||
971 (dscreen
->dump_mode
== DD_DUMP_APITRACE_CALL
&&
972 dscreen
->apitrace_dump_call
!= record
->draw_state
.base
.apitrace_call_number
))
976 dd_get_debug_filename_and_mkdir(name
, sizeof(name
), dscreen
->verbose
);
977 FILE *f
= fopen(name
, "w");
979 fprintf(stderr
, "dd: failed to open %s\n", name
);
983 dd_write_header(f
, dscreen
->screen
, record
->draw_state
.base
.apitrace_call_number
);
984 dd_write_record(f
, record
);
990 dd_fence_state(struct pipe_screen
*screen
, struct pipe_fence_handle
*fence
,
996 bool ok
= screen
->fence_finish(screen
, NULL
, fence
, 0);
998 if (not_reached
&& !ok
)
1001 return ok
? "YES" : "NO ";
1005 dd_report_hang(struct dd_context
*dctx
)
1007 struct dd_screen
*dscreen
= dd_screen(dctx
->base
.screen
);
1008 struct pipe_screen
*screen
= dscreen
->screen
;
1009 bool encountered_hang
= false;
1010 bool stop_output
= false;
1011 unsigned num_later
= 0;
1013 fprintf(stderr
, "GPU hang detected, collecting information...\n\n");
1015 fprintf(stderr
, "Draw # driver prev BOP TOP BOP dump file\n"
1016 "-------------------------------------------------------------\n");
1018 list_for_each_entry(struct dd_draw_record
, record
, &dctx
->records
, list
) {
1019 if (!encountered_hang
&&
1020 screen
->fence_finish(screen
, NULL
, record
->bottom_of_pipe
, 0)) {
1021 dd_maybe_dump_record(dscreen
, record
);
1026 dd_maybe_dump_record(dscreen
, record
);
1031 bool driver
= util_queue_fence_is_signalled(&record
->driver_finished
);
1032 bool top_not_reached
= false;
1033 const char *prev_bop
= dd_fence_state(screen
, record
->prev_bottom_of_pipe
, NULL
);
1034 const char *top
= dd_fence_state(screen
, record
->top_of_pipe
, &top_not_reached
);
1035 const char *bop
= dd_fence_state(screen
, record
->bottom_of_pipe
, NULL
);
1037 fprintf(stderr
, "%-9u %s %s %s %s ",
1038 record
->draw_call
, driver
? "YES" : "NO ", prev_bop
, top
, bop
);
1041 dd_get_debug_filename_and_mkdir(name
, sizeof(name
), false);
1043 FILE *f
= fopen(name
, "w");
1045 fprintf(stderr
, "fopen failed\n");
1047 fprintf(stderr
, "%s\n", name
);
1049 dd_write_header(f
, dscreen
->screen
, record
->draw_state
.base
.apitrace_call_number
);
1050 dd_write_record(f
, record
);
1055 if (top_not_reached
)
1057 encountered_hang
= true;
1061 fprintf(stderr
, "... and %u additional draws.\n", num_later
);
1064 dd_get_debug_filename_and_mkdir(name
, sizeof(name
), false);
1065 FILE *f
= fopen(name
, "w");
1067 fprintf(stderr
, "fopen failed\n");
1069 dd_write_header(f
, dscreen
->screen
, 0);
1070 dd_dump_driver_state(dctx
, f
, PIPE_DUMP_DEVICE_STATUS_REGISTERS
);
1075 fprintf(stderr
, "\nDone.\n");
1080 dd_thread_main(void *input
)
1082 struct dd_context
*dctx
= (struct dd_context
*)input
;
1083 struct dd_screen
*dscreen
= dd_screen(dctx
->base
.screen
);
1084 struct pipe_screen
*screen
= dscreen
->screen
;
1086 const char *process_name
= util_get_process_name();
1088 char threadname
[16];
1089 snprintf(threadname
, sizeof(threadname
), "%.*s:ddbg",
1090 (int)MIN2(strlen(process_name
), sizeof(threadname
) - 6),
1092 u_thread_setname(threadname
);
1095 mtx_lock(&dctx
->mutex
);
1098 struct list_head records
;
1099 list_replace(&dctx
->records
, &records
);
1100 list_inithead(&dctx
->records
);
1101 dctx
->num_records
= 0;
1103 if (dctx
->api_stalled
)
1104 cnd_signal(&dctx
->cond
);
1106 if (list_empty(&records
)) {
1107 if (dctx
->kill_thread
)
1110 cnd_wait(&dctx
->cond
, &dctx
->mutex
);
1114 mtx_unlock(&dctx
->mutex
);
1116 /* Wait for the youngest draw. This means hangs can take a bit longer
1117 * to detect, but it's more efficient this way. */
1118 struct dd_draw_record
*youngest
=
1119 list_last_entry(&records
, struct dd_draw_record
, list
);
1121 if (dscreen
->timeout_ms
> 0) {
1122 uint64_t abs_timeout
= os_time_get_absolute_timeout(
1123 (uint64_t)dscreen
->timeout_ms
* 1000*1000);
1125 if (!util_queue_fence_wait_timeout(&youngest
->driver_finished
, abs_timeout
) ||
1126 !screen
->fence_finish(screen
, NULL
, youngest
->bottom_of_pipe
,
1127 (uint64_t)dscreen
->timeout_ms
* 1000*1000)) {
1128 mtx_lock(&dctx
->mutex
);
1129 list_splice(&records
, &dctx
->records
);
1130 dd_report_hang(dctx
);
1131 /* we won't actually get here */
1132 mtx_unlock(&dctx
->mutex
);
1135 util_queue_fence_wait(&youngest
->driver_finished
);
1138 list_for_each_entry_safe(struct dd_draw_record
, record
, &records
, list
) {
1139 dd_maybe_dump_record(dscreen
, record
);
1140 list_del(&record
->list
);
1141 dd_free_record(screen
, record
);
1144 mtx_lock(&dctx
->mutex
);
1146 mtx_unlock(&dctx
->mutex
);
1150 static struct dd_draw_record
*
1151 dd_create_record(struct dd_context
*dctx
)
1153 struct dd_draw_record
*record
;
1155 record
= MALLOC_STRUCT(dd_draw_record
);
1159 record
->dctx
= dctx
;
1160 record
->draw_call
= dctx
->num_draw_calls
;
1162 record
->prev_bottom_of_pipe
= NULL
;
1163 record
->top_of_pipe
= NULL
;
1164 record
->bottom_of_pipe
= NULL
;
1165 record
->log_page
= NULL
;
1166 util_queue_fence_init(&record
->driver_finished
);
1167 util_queue_fence_reset(&record
->driver_finished
);
1169 dd_init_copy_of_draw_state(&record
->draw_state
);
1170 dd_copy_draw_state(&record
->draw_state
.base
, &dctx
->draw_state
);
1176 dd_add_record(struct dd_context
*dctx
, struct dd_draw_record
*record
)
1178 mtx_lock(&dctx
->mutex
);
1179 if (unlikely(dctx
->num_records
> 10000)) {
1180 dctx
->api_stalled
= true;
1181 /* Since this is only a heuristic to prevent the API thread from getting
1182 * too far ahead, we don't need a loop here. */
1183 cnd_wait(&dctx
->cond
, &dctx
->mutex
);
1184 dctx
->api_stalled
= false;
1187 if (list_empty(&dctx
->records
))
1188 cnd_signal(&dctx
->cond
);
1190 list_addtail(&record
->list
, &dctx
->records
);
1191 dctx
->num_records
++;
1192 mtx_unlock(&dctx
->mutex
);
1196 dd_before_draw(struct dd_context
*dctx
, struct dd_draw_record
*record
)
1198 struct dd_screen
*dscreen
= dd_screen(dctx
->base
.screen
);
1199 struct pipe_context
*pipe
= dctx
->pipe
;
1200 struct pipe_screen
*screen
= dscreen
->screen
;
1202 record
->time_before
= os_time_get_nano();
1204 if (dscreen
->timeout_ms
> 0) {
1205 if (dscreen
->flush_always
&& dctx
->num_draw_calls
>= dscreen
->skip_count
) {
1206 pipe
->flush(pipe
, &record
->prev_bottom_of_pipe
, 0);
1207 screen
->fence_reference(screen
, &record
->top_of_pipe
, record
->prev_bottom_of_pipe
);
1209 pipe
->flush(pipe
, &record
->prev_bottom_of_pipe
,
1210 PIPE_FLUSH_DEFERRED
| PIPE_FLUSH_BOTTOM_OF_PIPE
);
1211 pipe
->flush(pipe
, &record
->top_of_pipe
,
1212 PIPE_FLUSH_DEFERRED
| PIPE_FLUSH_TOP_OF_PIPE
);
1214 } else if (dscreen
->flush_always
&& dctx
->num_draw_calls
>= dscreen
->skip_count
) {
1215 pipe
->flush(pipe
, NULL
, 0);
1218 dd_add_record(dctx
, record
);
1222 dd_after_draw_async(void *data
)
1224 struct dd_draw_record
*record
= (struct dd_draw_record
*)data
;
1225 struct dd_context
*dctx
= record
->dctx
;
1226 struct dd_screen
*dscreen
= dd_screen(dctx
->base
.screen
);
1228 record
->log_page
= u_log_new_page(&dctx
->log
);
1229 record
->time_after
= os_time_get_nano();
1231 util_queue_fence_signal(&record
->driver_finished
);
1233 if (dscreen
->dump_mode
== DD_DUMP_APITRACE_CALL
&&
1234 dscreen
->apitrace_dump_call
> dctx
->draw_state
.apitrace_call_number
) {
1235 dd_thread_join(dctx
);
1236 /* No need to continue. */
1242 dd_after_draw(struct dd_context
*dctx
, struct dd_draw_record
*record
)
1244 struct dd_screen
*dscreen
= dd_screen(dctx
->base
.screen
);
1245 struct pipe_context
*pipe
= dctx
->pipe
;
1247 if (dscreen
->timeout_ms
> 0) {
1248 unsigned flush_flags
;
1249 if (dscreen
->flush_always
&& dctx
->num_draw_calls
>= dscreen
->skip_count
)
1252 flush_flags
= PIPE_FLUSH_DEFERRED
| PIPE_FLUSH_BOTTOM_OF_PIPE
;
1253 pipe
->flush(pipe
, &record
->bottom_of_pipe
, flush_flags
);
1256 if (pipe
->callback
) {
1257 pipe
->callback(pipe
, dd_after_draw_async
, record
, true);
1259 dd_after_draw_async(record
);
1262 ++dctx
->num_draw_calls
;
1263 if (dscreen
->skip_count
&& dctx
->num_draw_calls
% 10000 == 0)
1264 fprintf(stderr
, "Gallium debugger reached %u draw calls.\n",
1265 dctx
->num_draw_calls
);
1269 dd_context_flush(struct pipe_context
*_pipe
,
1270 struct pipe_fence_handle
**fence
, unsigned flags
)
1272 struct dd_context
*dctx
= dd_context(_pipe
);
1273 struct pipe_context
*pipe
= dctx
->pipe
;
1274 struct pipe_screen
*screen
= pipe
->screen
;
1275 struct dd_draw_record
*record
= dd_create_record(dctx
);
1277 record
->call
.type
= CALL_FLUSH
;
1278 record
->call
.info
.flush
.flags
= flags
;
1280 record
->time_before
= os_time_get_nano();
1282 dd_add_record(dctx
, record
);
1284 pipe
->flush(pipe
, &record
->bottom_of_pipe
, flags
);
1286 screen
->fence_reference(screen
, fence
, record
->bottom_of_pipe
);
1288 if (pipe
->callback
) {
1289 pipe
->callback(pipe
, dd_after_draw_async
, record
, true);
1291 dd_after_draw_async(record
);
1296 dd_context_draw_vbo(struct pipe_context
*_pipe
,
1297 const struct pipe_draw_info
*info
)
1299 struct dd_context
*dctx
= dd_context(_pipe
);
1300 struct pipe_context
*pipe
= dctx
->pipe
;
1301 struct dd_draw_record
*record
= dd_create_record(dctx
);
1303 record
->call
.type
= CALL_DRAW_VBO
;
1304 record
->call
.info
.draw_vbo
.draw
= *info
;
1305 record
->call
.info
.draw_vbo
.draw
.count_from_stream_output
= NULL
;
1306 pipe_so_target_reference(&record
->call
.info
.draw_vbo
.draw
.count_from_stream_output
,
1307 info
->count_from_stream_output
);
1308 if (info
->index_size
&& !info
->has_user_indices
) {
1309 record
->call
.info
.draw_vbo
.draw
.index
.resource
= NULL
;
1310 pipe_resource_reference(&record
->call
.info
.draw_vbo
.draw
.index
.resource
,
1311 info
->index
.resource
);
1314 if (info
->indirect
) {
1315 record
->call
.info
.draw_vbo
.indirect
= *info
->indirect
;
1316 record
->call
.info
.draw_vbo
.draw
.indirect
= &record
->call
.info
.draw_vbo
.indirect
;
1318 record
->call
.info
.draw_vbo
.indirect
.buffer
= NULL
;
1319 pipe_resource_reference(&record
->call
.info
.draw_vbo
.indirect
.buffer
,
1320 info
->indirect
->buffer
);
1321 record
->call
.info
.draw_vbo
.indirect
.indirect_draw_count
= NULL
;
1322 pipe_resource_reference(&record
->call
.info
.draw_vbo
.indirect
.indirect_draw_count
,
1323 info
->indirect
->indirect_draw_count
);
1325 memset(&record
->call
.info
.draw_vbo
.indirect
, 0, sizeof(*info
->indirect
));
1328 dd_before_draw(dctx
, record
);
1329 pipe
->draw_vbo(pipe
, info
);
1330 dd_after_draw(dctx
, record
);
1334 dd_context_launch_grid(struct pipe_context
*_pipe
,
1335 const struct pipe_grid_info
*info
)
1337 struct dd_context
*dctx
= dd_context(_pipe
);
1338 struct pipe_context
*pipe
= dctx
->pipe
;
1339 struct dd_draw_record
*record
= dd_create_record(dctx
);
1341 record
->call
.type
= CALL_LAUNCH_GRID
;
1342 record
->call
.info
.launch_grid
= *info
;
1343 record
->call
.info
.launch_grid
.indirect
= NULL
;
1344 pipe_resource_reference(&record
->call
.info
.launch_grid
.indirect
, info
->indirect
);
1346 dd_before_draw(dctx
, record
);
1347 pipe
->launch_grid(pipe
, info
);
1348 dd_after_draw(dctx
, record
);
1352 dd_context_resource_copy_region(struct pipe_context
*_pipe
,
1353 struct pipe_resource
*dst
, unsigned dst_level
,
1354 unsigned dstx
, unsigned dsty
, unsigned dstz
,
1355 struct pipe_resource
*src
, unsigned src_level
,
1356 const struct pipe_box
*src_box
)
1358 struct dd_context
*dctx
= dd_context(_pipe
);
1359 struct pipe_context
*pipe
= dctx
->pipe
;
1360 struct dd_draw_record
*record
= dd_create_record(dctx
);
1362 record
->call
.type
= CALL_RESOURCE_COPY_REGION
;
1363 record
->call
.info
.resource_copy_region
.dst
= NULL
;
1364 pipe_resource_reference(&record
->call
.info
.resource_copy_region
.dst
, dst
);
1365 record
->call
.info
.resource_copy_region
.dst_level
= dst_level
;
1366 record
->call
.info
.resource_copy_region
.dstx
= dstx
;
1367 record
->call
.info
.resource_copy_region
.dsty
= dsty
;
1368 record
->call
.info
.resource_copy_region
.dstz
= dstz
;
1369 record
->call
.info
.resource_copy_region
.src
= NULL
;
1370 pipe_resource_reference(&record
->call
.info
.resource_copy_region
.src
, src
);
1371 record
->call
.info
.resource_copy_region
.src_level
= src_level
;
1372 record
->call
.info
.resource_copy_region
.src_box
= *src_box
;
1374 dd_before_draw(dctx
, record
);
1375 pipe
->resource_copy_region(pipe
,
1376 dst
, dst_level
, dstx
, dsty
, dstz
,
1377 src
, src_level
, src_box
);
1378 dd_after_draw(dctx
, record
);
1382 dd_context_blit(struct pipe_context
*_pipe
, const struct pipe_blit_info
*info
)
1384 struct dd_context
*dctx
= dd_context(_pipe
);
1385 struct pipe_context
*pipe
= dctx
->pipe
;
1386 struct dd_draw_record
*record
= dd_create_record(dctx
);
1388 record
->call
.type
= CALL_BLIT
;
1389 record
->call
.info
.blit
= *info
;
1390 record
->call
.info
.blit
.dst
.resource
= NULL
;
1391 pipe_resource_reference(&record
->call
.info
.blit
.dst
.resource
, info
->dst
.resource
);
1392 record
->call
.info
.blit
.src
.resource
= NULL
;
1393 pipe_resource_reference(&record
->call
.info
.blit
.src
.resource
, info
->src
.resource
);
1395 dd_before_draw(dctx
, record
);
1396 pipe
->blit(pipe
, info
);
1397 dd_after_draw(dctx
, record
);
1401 dd_context_generate_mipmap(struct pipe_context
*_pipe
,
1402 struct pipe_resource
*res
,
1403 enum pipe_format format
,
1404 unsigned base_level
,
1405 unsigned last_level
,
1406 unsigned first_layer
,
1407 unsigned last_layer
)
1409 struct dd_context
*dctx
= dd_context(_pipe
);
1410 struct pipe_context
*pipe
= dctx
->pipe
;
1411 struct dd_draw_record
*record
= dd_create_record(dctx
);
1414 record
->call
.type
= CALL_GENERATE_MIPMAP
;
1415 record
->call
.info
.generate_mipmap
.res
= NULL
;
1416 pipe_resource_reference(&record
->call
.info
.generate_mipmap
.res
, res
);
1417 record
->call
.info
.generate_mipmap
.format
= format
;
1418 record
->call
.info
.generate_mipmap
.base_level
= base_level
;
1419 record
->call
.info
.generate_mipmap
.last_level
= last_level
;
1420 record
->call
.info
.generate_mipmap
.first_layer
= first_layer
;
1421 record
->call
.info
.generate_mipmap
.last_layer
= last_layer
;
1423 dd_before_draw(dctx
, record
);
1424 result
= pipe
->generate_mipmap(pipe
, res
, format
, base_level
, last_level
,
1425 first_layer
, last_layer
);
1426 dd_after_draw(dctx
, record
);
1431 dd_context_get_query_result_resource(struct pipe_context
*_pipe
,
1432 struct pipe_query
*query
,
1434 enum pipe_query_value_type result_type
,
1436 struct pipe_resource
*resource
,
1439 struct dd_context
*dctx
= dd_context(_pipe
);
1440 struct dd_query
*dquery
= dd_query(query
);
1441 struct pipe_context
*pipe
= dctx
->pipe
;
1442 struct dd_draw_record
*record
= dd_create_record(dctx
);
1444 record
->call
.type
= CALL_GET_QUERY_RESULT_RESOURCE
;
1445 record
->call
.info
.get_query_result_resource
.query
= query
;
1446 record
->call
.info
.get_query_result_resource
.wait
= wait
;
1447 record
->call
.info
.get_query_result_resource
.result_type
= result_type
;
1448 record
->call
.info
.get_query_result_resource
.index
= index
;
1449 record
->call
.info
.get_query_result_resource
.resource
= NULL
;
1450 pipe_resource_reference(&record
->call
.info
.get_query_result_resource
.resource
,
1452 record
->call
.info
.get_query_result_resource
.offset
= offset
;
1454 /* The query may be deleted by the time we need to print it. */
1455 record
->call
.info
.get_query_result_resource
.query_type
= dquery
->type
;
1457 dd_before_draw(dctx
, record
);
1458 pipe
->get_query_result_resource(pipe
, dquery
->query
, wait
,
1459 result_type
, index
, resource
, offset
);
1460 dd_after_draw(dctx
, record
);
1464 dd_context_flush_resource(struct pipe_context
*_pipe
,
1465 struct pipe_resource
*resource
)
1467 struct dd_context
*dctx
= dd_context(_pipe
);
1468 struct pipe_context
*pipe
= dctx
->pipe
;
1469 struct dd_draw_record
*record
= dd_create_record(dctx
);
1471 record
->call
.type
= CALL_FLUSH_RESOURCE
;
1472 record
->call
.info
.flush_resource
= NULL
;
1473 pipe_resource_reference(&record
->call
.info
.flush_resource
, resource
);
1475 dd_before_draw(dctx
, record
);
1476 pipe
->flush_resource(pipe
, resource
);
1477 dd_after_draw(dctx
, record
);
1481 dd_context_clear(struct pipe_context
*_pipe
, unsigned buffers
,
1482 const union pipe_color_union
*color
, double depth
,
1485 struct dd_context
*dctx
= dd_context(_pipe
);
1486 struct pipe_context
*pipe
= dctx
->pipe
;
1487 struct dd_draw_record
*record
= dd_create_record(dctx
);
1489 record
->call
.type
= CALL_CLEAR
;
1490 record
->call
.info
.clear
.buffers
= buffers
;
1491 record
->call
.info
.clear
.color
= *color
;
1492 record
->call
.info
.clear
.depth
= depth
;
1493 record
->call
.info
.clear
.stencil
= stencil
;
1495 dd_before_draw(dctx
, record
);
1496 pipe
->clear(pipe
, buffers
, color
, depth
, stencil
);
1497 dd_after_draw(dctx
, record
);
1501 dd_context_clear_render_target(struct pipe_context
*_pipe
,
1502 struct pipe_surface
*dst
,
1503 const union pipe_color_union
*color
,
1504 unsigned dstx
, unsigned dsty
,
1505 unsigned width
, unsigned height
,
1506 bool render_condition_enabled
)
1508 struct dd_context
*dctx
= dd_context(_pipe
);
1509 struct pipe_context
*pipe
= dctx
->pipe
;
1510 struct dd_draw_record
*record
= dd_create_record(dctx
);
1512 record
->call
.type
= CALL_CLEAR_RENDER_TARGET
;
1514 dd_before_draw(dctx
, record
);
1515 pipe
->clear_render_target(pipe
, dst
, color
, dstx
, dsty
, width
, height
,
1516 render_condition_enabled
);
1517 dd_after_draw(dctx
, record
);
1521 dd_context_clear_depth_stencil(struct pipe_context
*_pipe
,
1522 struct pipe_surface
*dst
, unsigned clear_flags
,
1523 double depth
, unsigned stencil
, unsigned dstx
,
1524 unsigned dsty
, unsigned width
, unsigned height
,
1525 bool render_condition_enabled
)
1527 struct dd_context
*dctx
= dd_context(_pipe
);
1528 struct pipe_context
*pipe
= dctx
->pipe
;
1529 struct dd_draw_record
*record
= dd_create_record(dctx
);
1531 record
->call
.type
= CALL_CLEAR_DEPTH_STENCIL
;
1533 dd_before_draw(dctx
, record
);
1534 pipe
->clear_depth_stencil(pipe
, dst
, clear_flags
, depth
, stencil
,
1535 dstx
, dsty
, width
, height
,
1536 render_condition_enabled
);
1537 dd_after_draw(dctx
, record
);
1541 dd_context_clear_buffer(struct pipe_context
*_pipe
, struct pipe_resource
*res
,
1542 unsigned offset
, unsigned size
,
1543 const void *clear_value
, int clear_value_size
)
1545 struct dd_context
*dctx
= dd_context(_pipe
);
1546 struct pipe_context
*pipe
= dctx
->pipe
;
1547 struct dd_draw_record
*record
= dd_create_record(dctx
);
1549 record
->call
.type
= CALL_CLEAR_BUFFER
;
1550 record
->call
.info
.clear_buffer
.res
= NULL
;
1551 pipe_resource_reference(&record
->call
.info
.clear_buffer
.res
, res
);
1552 record
->call
.info
.clear_buffer
.offset
= offset
;
1553 record
->call
.info
.clear_buffer
.size
= size
;
1554 record
->call
.info
.clear_buffer
.clear_value
= clear_value
;
1555 record
->call
.info
.clear_buffer
.clear_value_size
= clear_value_size
;
1557 dd_before_draw(dctx
, record
);
1558 pipe
->clear_buffer(pipe
, res
, offset
, size
, clear_value
, clear_value_size
);
1559 dd_after_draw(dctx
, record
);
1563 dd_context_clear_texture(struct pipe_context
*_pipe
,
1564 struct pipe_resource
*res
,
1566 const struct pipe_box
*box
,
1569 struct dd_context
*dctx
= dd_context(_pipe
);
1570 struct pipe_context
*pipe
= dctx
->pipe
;
1571 struct dd_draw_record
*record
= dd_create_record(dctx
);
1573 record
->call
.type
= CALL_CLEAR_TEXTURE
;
1575 dd_before_draw(dctx
, record
);
1576 pipe
->clear_texture(pipe
, res
, level
, box
, data
);
1577 dd_after_draw(dctx
, record
);
1580 /********************************************************************
1585 dd_context_transfer_map(struct pipe_context
*_pipe
,
1586 struct pipe_resource
*resource
, unsigned level
,
1587 unsigned usage
, const struct pipe_box
*box
,
1588 struct pipe_transfer
**transfer
)
1590 struct dd_context
*dctx
= dd_context(_pipe
);
1591 struct pipe_context
*pipe
= dctx
->pipe
;
1592 struct dd_draw_record
*record
=
1593 dd_screen(dctx
->base
.screen
)->transfers
? dd_create_record(dctx
) : NULL
;
1596 record
->call
.type
= CALL_TRANSFER_MAP
;
1598 dd_before_draw(dctx
, record
);
1600 void *ptr
= pipe
->transfer_map(pipe
, resource
, level
, usage
, box
, transfer
);
1602 record
->call
.info
.transfer_map
.transfer_ptr
= *transfer
;
1603 record
->call
.info
.transfer_map
.ptr
= ptr
;
1605 record
->call
.info
.transfer_map
.transfer
= **transfer
;
1606 record
->call
.info
.transfer_map
.transfer
.resource
= NULL
;
1607 pipe_resource_reference(&record
->call
.info
.transfer_map
.transfer
.resource
,
1608 (*transfer
)->resource
);
1610 memset(&record
->call
.info
.transfer_map
.transfer
, 0, sizeof(struct pipe_transfer
));
1613 dd_after_draw(dctx
, record
);
1619 dd_context_transfer_flush_region(struct pipe_context
*_pipe
,
1620 struct pipe_transfer
*transfer
,
1621 const struct pipe_box
*box
)
1623 struct dd_context
*dctx
= dd_context(_pipe
);
1624 struct pipe_context
*pipe
= dctx
->pipe
;
1625 struct dd_draw_record
*record
=
1626 dd_screen(dctx
->base
.screen
)->transfers
? dd_create_record(dctx
) : NULL
;
1629 record
->call
.type
= CALL_TRANSFER_FLUSH_REGION
;
1630 record
->call
.info
.transfer_flush_region
.transfer_ptr
= transfer
;
1631 record
->call
.info
.transfer_flush_region
.box
= *box
;
1632 record
->call
.info
.transfer_flush_region
.transfer
= *transfer
;
1633 record
->call
.info
.transfer_flush_region
.transfer
.resource
= NULL
;
1634 pipe_resource_reference(
1635 &record
->call
.info
.transfer_flush_region
.transfer
.resource
,
1636 transfer
->resource
);
1638 dd_before_draw(dctx
, record
);
1640 pipe
->transfer_flush_region(pipe
, transfer
, box
);
1642 dd_after_draw(dctx
, record
);
1646 dd_context_transfer_unmap(struct pipe_context
*_pipe
,
1647 struct pipe_transfer
*transfer
)
1649 struct dd_context
*dctx
= dd_context(_pipe
);
1650 struct pipe_context
*pipe
= dctx
->pipe
;
1651 struct dd_draw_record
*record
=
1652 dd_screen(dctx
->base
.screen
)->transfers
? dd_create_record(dctx
) : NULL
;
1655 record
->call
.type
= CALL_TRANSFER_UNMAP
;
1656 record
->call
.info
.transfer_unmap
.transfer_ptr
= transfer
;
1657 record
->call
.info
.transfer_unmap
.transfer
= *transfer
;
1658 record
->call
.info
.transfer_unmap
.transfer
.resource
= NULL
;
1659 pipe_resource_reference(
1660 &record
->call
.info
.transfer_unmap
.transfer
.resource
,
1661 transfer
->resource
);
1663 dd_before_draw(dctx
, record
);
1665 pipe
->transfer_unmap(pipe
, transfer
);
1667 dd_after_draw(dctx
, record
);
1671 dd_context_buffer_subdata(struct pipe_context
*_pipe
,
1672 struct pipe_resource
*resource
,
1673 unsigned usage
, unsigned offset
,
1674 unsigned size
, const void *data
)
1676 struct dd_context
*dctx
= dd_context(_pipe
);
1677 struct pipe_context
*pipe
= dctx
->pipe
;
1678 struct dd_draw_record
*record
=
1679 dd_screen(dctx
->base
.screen
)->transfers
? dd_create_record(dctx
) : NULL
;
1682 record
->call
.type
= CALL_BUFFER_SUBDATA
;
1683 record
->call
.info
.buffer_subdata
.resource
= NULL
;
1684 pipe_resource_reference(&record
->call
.info
.buffer_subdata
.resource
, resource
);
1685 record
->call
.info
.buffer_subdata
.usage
= usage
;
1686 record
->call
.info
.buffer_subdata
.offset
= offset
;
1687 record
->call
.info
.buffer_subdata
.size
= size
;
1688 record
->call
.info
.buffer_subdata
.data
= data
;
1690 dd_before_draw(dctx
, record
);
1692 pipe
->buffer_subdata(pipe
, resource
, usage
, offset
, size
, data
);
1694 dd_after_draw(dctx
, record
);
1698 dd_context_texture_subdata(struct pipe_context
*_pipe
,
1699 struct pipe_resource
*resource
,
1700 unsigned level
, unsigned usage
,
1701 const struct pipe_box
*box
,
1702 const void *data
, unsigned stride
,
1703 unsigned layer_stride
)
1705 struct dd_context
*dctx
= dd_context(_pipe
);
1706 struct pipe_context
*pipe
= dctx
->pipe
;
1707 struct dd_draw_record
*record
=
1708 dd_screen(dctx
->base
.screen
)->transfers
? dd_create_record(dctx
) : NULL
;
1711 record
->call
.type
= CALL_TEXTURE_SUBDATA
;
1712 record
->call
.info
.texture_subdata
.resource
= NULL
;
1713 pipe_resource_reference(&record
->call
.info
.texture_subdata
.resource
, resource
);
1714 record
->call
.info
.texture_subdata
.level
= level
;
1715 record
->call
.info
.texture_subdata
.usage
= usage
;
1716 record
->call
.info
.texture_subdata
.box
= *box
;
1717 record
->call
.info
.texture_subdata
.data
= data
;
1718 record
->call
.info
.texture_subdata
.stride
= stride
;
1719 record
->call
.info
.texture_subdata
.layer_stride
= layer_stride
;
1721 dd_before_draw(dctx
, record
);
1723 pipe
->texture_subdata(pipe
, resource
, level
, usage
, box
, data
,
1724 stride
, layer_stride
);
1726 dd_after_draw(dctx
, record
);
1730 dd_init_draw_functions(struct dd_context
*dctx
)
1734 CTX_INIT(launch_grid
);
1735 CTX_INIT(resource_copy_region
);
1738 CTX_INIT(clear_render_target
);
1739 CTX_INIT(clear_depth_stencil
);
1740 CTX_INIT(clear_buffer
);
1741 CTX_INIT(clear_texture
);
1742 CTX_INIT(flush_resource
);
1743 CTX_INIT(generate_mipmap
);
1744 CTX_INIT(get_query_result_resource
);
1745 CTX_INIT(transfer_map
);
1746 CTX_INIT(transfer_flush_region
);
1747 CTX_INIT(transfer_unmap
);
1748 CTX_INIT(buffer_subdata
);
1749 CTX_INIT(texture_subdata
);