• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "util/u_framebuffer.h"
33 #include "util/u_helpers.h"
34 #include "util/u_inlines.h"
35 #include "util/u_memory.h"
36 #include "tgsi/tgsi_parse.h"
37 #include "tgsi/tgsi_scan.h"
38 #include "util/os_time.h"
39 #include <inttypes.h>
40 
41 
42 static void
dd_write_header(FILE * f,struct pipe_screen * screen,unsigned apitrace_call_number)43 dd_write_header(FILE *f, struct pipe_screen *screen, unsigned apitrace_call_number)
44 {
45    char cmd_line[4096];
46    if (os_get_command_line(cmd_line, sizeof(cmd_line)))
47       fprintf(f, "Command: %s\n", cmd_line);
48    fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
49    fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
50    fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
51 
52    if (apitrace_call_number)
53       fprintf(f, "Last apitrace call: %u\n\n", apitrace_call_number);
54 }
55 
56 FILE *
dd_get_file_stream(struct dd_screen * dscreen,unsigned apitrace_call_number)57 dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number)
58 {
59    struct pipe_screen *screen = dscreen->screen;
60 
61    FILE *f = dd_get_debug_file(dscreen->verbose);
62    if (!f)
63       return NULL;
64 
65    dd_write_header(f, screen, apitrace_call_number);
66    return f;
67 }
68 
69 static void
dd_dump_dmesg(FILE * f)70 dd_dump_dmesg(FILE *f)
71 {
72    char line[2000];
73    FILE *p = popen("dmesg | tail -n60", "r");
74 
75    if (!p)
76       return;
77 
78    fprintf(f, "\nLast 60 lines of dmesg:\n\n");
79    while (fgets(line, sizeof(line), p))
80       fputs(line, f);
81 
82    pclose(p);
83 }
84 
85 static unsigned
dd_num_active_viewports(struct dd_draw_state * dstate)86 dd_num_active_viewports(struct dd_draw_state *dstate)
87 {
88    struct tgsi_shader_info info;
89    const struct tgsi_token *tokens;
90 
91    if (dstate->shaders[PIPE_SHADER_GEOMETRY])
92       tokens = dstate->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens;
93    else if (dstate->shaders[PIPE_SHADER_TESS_EVAL])
94       tokens = dstate->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens;
95    else if (dstate->shaders[PIPE_SHADER_VERTEX])
96       tokens = dstate->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens;
97    else
98       return 1;
99 
100    if (tokens) {
101       tgsi_scan_shader(tokens, &info);
102       if (info.writes_viewport_index)
103          return PIPE_MAX_VIEWPORTS;
104    }
105 
106    return 1;
107 }
108 
109 #define COLOR_RESET	"\033[0m"
110 #define COLOR_SHADER	"\033[1;32m"
111 #define COLOR_STATE	"\033[1;33m"
112 
113 #define DUMP(name, var) do { \
114    fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \
115    util_dump_##name(f, var); \
116    fprintf(f, "\n"); \
117 } while(0)
118 
119 #define DUMP_I(name, var, i) do { \
120    fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \
121    util_dump_##name(f, var); \
122    fprintf(f, "\n"); \
123 } while(0)
124 
125 #define DUMP_M(name, var, member) do { \
126    fprintf(f, "  " #member ": "); \
127    util_dump_##name(f, (var)->member); \
128    fprintf(f, "\n"); \
129 } while(0)
130 
131 #define DUMP_M_ADDR(name, var, member) do { \
132    fprintf(f, "  " #member ": "); \
133    util_dump_##name(f, &(var)->member); \
134    fprintf(f, "\n"); \
135 } while(0)
136 
137 #define PRINT_NAMED(type, name, value) \
138 do { \
139    fprintf(f, COLOR_STATE "%s" COLOR_RESET " = ", name); \
140    util_dump_##type(f, value); \
141    fprintf(f, "\n"); \
142 } while (0)
143 
144 static void
util_dump_uint(FILE * f,unsigned i)145 util_dump_uint(FILE *f, unsigned i)
146 {
147    fprintf(f, "%u", i);
148 }
149 
150 static void
util_dump_int(FILE * f,int i)151 util_dump_int(FILE *f, int i)
152 {
153    fprintf(f, "%d", i);
154 }
155 
156 static void
util_dump_hex(FILE * f,unsigned i)157 util_dump_hex(FILE *f, unsigned i)
158 {
159    fprintf(f, "0x%x", i);
160 }
161 
162 static void
util_dump_double(FILE * f,double d)163 util_dump_double(FILE *f, double d)
164 {
165    fprintf(f, "%f", d);
166 }
167 
168 static void
util_dump_format(FILE * f,enum pipe_format format)169 util_dump_format(FILE *f, enum pipe_format format)
170 {
171    fprintf(f, "%s", util_format_name(format));
172 }
173 
174 static void
util_dump_color_union(FILE * f,const union pipe_color_union * color)175 util_dump_color_union(FILE *f, const union pipe_color_union *color)
176 {
177    fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}",
178            color->f[0], color->f[1], color->f[2], color->f[3],
179            color->ui[0], color->ui[1], color->ui[2], color->ui[3]);
180 }
181 
182 static void
dd_dump_render_condition(struct dd_draw_state * dstate,FILE * f)183 dd_dump_render_condition(struct dd_draw_state *dstate, FILE *f)
184 {
185    if (dstate->render_cond.query) {
186       fprintf(f, "render condition:\n");
187       DUMP_M(query_type, &dstate->render_cond, query->type);
188       DUMP_M(uint, &dstate->render_cond, condition);
189       DUMP_M(uint, &dstate->render_cond, mode);
190       fprintf(f, "\n");
191    }
192 }
193 
194 static void
dd_dump_shader(struct dd_draw_state * dstate,enum pipe_shader_type sh,FILE * f)195 dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f)
196 {
197    int i;
198    const char *shader_str[PIPE_SHADER_TYPES];
199 
200    shader_str[PIPE_SHADER_VERTEX] = "VERTEX";
201    shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL";
202    shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL";
203    shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY";
204    shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT";
205    shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE";
206 
207    if (sh == PIPE_SHADER_TESS_CTRL &&
208        !dstate->shaders[PIPE_SHADER_TESS_CTRL] &&
209        dstate->shaders[PIPE_SHADER_TESS_EVAL])
210       fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, "
211               "default_inner_level = {%f, %f}}\n",
212               dstate->tess_default_levels[0],
213               dstate->tess_default_levels[1],
214               dstate->tess_default_levels[2],
215               dstate->tess_default_levels[3],
216               dstate->tess_default_levels[4],
217               dstate->tess_default_levels[5]);
218 
219    if (sh == PIPE_SHADER_FRAGMENT)
220       if (dstate->rs) {
221          unsigned num_viewports = dd_num_active_viewports(dstate);
222 
223          if (dstate->rs->state.rs.clip_plane_enable)
224             DUMP(clip_state, &dstate->clip_state);
225 
226          for (i = 0; i < num_viewports; i++)
227             DUMP_I(viewport_state, &dstate->viewports[i], i);
228 
229          if (dstate->rs->state.rs.scissor)
230             for (i = 0; i < num_viewports; i++)
231                DUMP_I(scissor_state, &dstate->scissors[i], i);
232 
233          DUMP(rasterizer_state, &dstate->rs->state.rs);
234 
235          if (dstate->rs->state.rs.poly_stipple_enable)
236             DUMP(poly_stipple, &dstate->polygon_stipple);
237          fprintf(f, "\n");
238       }
239 
240    if (!dstate->shaders[sh])
241       return;
242 
243    fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]);
244    DUMP(shader_state, &dstate->shaders[sh]->state.shader);
245 
246    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++)
247       if (dstate->constant_buffers[sh][i].buffer ||
248             dstate->constant_buffers[sh][i].user_buffer) {
249          DUMP_I(constant_buffer, &dstate->constant_buffers[sh][i], i);
250          if (dstate->constant_buffers[sh][i].buffer)
251             DUMP_M(resource, &dstate->constant_buffers[sh][i], buffer);
252       }
253 
254    for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
255       if (dstate->sampler_states[sh][i])
256          DUMP_I(sampler_state, &dstate->sampler_states[sh][i]->state.sampler, i);
257 
258    for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
259       if (dstate->sampler_views[sh][i]) {
260          DUMP_I(sampler_view, dstate->sampler_views[sh][i], i);
261          DUMP_M(resource, dstate->sampler_views[sh][i], texture);
262       }
263 
264    for (i = 0; i < PIPE_MAX_SHADER_IMAGES; i++)
265       if (dstate->shader_images[sh][i].resource) {
266          DUMP_I(image_view, &dstate->shader_images[sh][i], i);
267          if (dstate->shader_images[sh][i].resource)
268             DUMP_M(resource, &dstate->shader_images[sh][i], resource);
269       }
270 
271    for (i = 0; i < PIPE_MAX_SHADER_BUFFERS; i++)
272       if (dstate->shader_buffers[sh][i].buffer) {
273          DUMP_I(shader_buffer, &dstate->shader_buffers[sh][i], i);
274          if (dstate->shader_buffers[sh][i].buffer)
275             DUMP_M(resource, &dstate->shader_buffers[sh][i], buffer);
276       }
277 
278    fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]);
279 }
280 
281 static void
dd_dump_draw_vbo(struct dd_draw_state * dstate,struct pipe_draw_info * info,FILE * f)282 dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f)
283 {
284    int sh, i;
285 
286    DUMP(draw_info, info);
287    if (info->count_from_stream_output)
288       DUMP_M(stream_output_target, info,
289              count_from_stream_output);
290    if (info->indirect) {
291       DUMP_M(resource, info, indirect->buffer);
292       if (info->indirect->indirect_draw_count)
293          DUMP_M(resource, info, indirect->indirect_draw_count);
294    }
295 
296    fprintf(f, "\n");
297 
298    /* TODO: dump active queries */
299 
300    dd_dump_render_condition(dstate, f);
301 
302    for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
303       if (dstate->vertex_buffers[i].buffer.resource) {
304          DUMP_I(vertex_buffer, &dstate->vertex_buffers[i], i);
305          if (!dstate->vertex_buffers[i].is_user_buffer)
306             DUMP_M(resource, &dstate->vertex_buffers[i], buffer.resource);
307       }
308 
309    if (dstate->velems) {
310       PRINT_NAMED(uint, "num vertex elements",
311                         dstate->velems->state.velems.count);
312       for (i = 0; i < dstate->velems->state.velems.count; i++) {
313          fprintf(f, "  ");
314          DUMP_I(vertex_element, &dstate->velems->state.velems.velems[i], i);
315       }
316    }
317 
318    PRINT_NAMED(uint, "num stream output targets", dstate->num_so_targets);
319    for (i = 0; i < dstate->num_so_targets; i++)
320       if (dstate->so_targets[i]) {
321          DUMP_I(stream_output_target, dstate->so_targets[i], i);
322          DUMP_M(resource, dstate->so_targets[i], buffer);
323          fprintf(f, "  offset = %i\n", dstate->so_offsets[i]);
324       }
325 
326    fprintf(f, "\n");
327    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
328       if (sh == PIPE_SHADER_COMPUTE)
329          continue;
330 
331       dd_dump_shader(dstate, sh, f);
332    }
333 
334    if (dstate->dsa)
335       DUMP(depth_stencil_alpha_state, &dstate->dsa->state.dsa);
336    DUMP(stencil_ref, &dstate->stencil_ref);
337 
338    if (dstate->blend)
339       DUMP(blend_state, &dstate->blend->state.blend);
340    DUMP(blend_color, &dstate->blend_color);
341 
342    PRINT_NAMED(uint, "min_samples", dstate->min_samples);
343    PRINT_NAMED(hex, "sample_mask", dstate->sample_mask);
344    fprintf(f, "\n");
345 
346    DUMP(framebuffer_state, &dstate->framebuffer_state);
347    for (i = 0; i < dstate->framebuffer_state.nr_cbufs; i++)
348       if (dstate->framebuffer_state.cbufs[i]) {
349          fprintf(f, "  " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n    ", i);
350          DUMP(surface, dstate->framebuffer_state.cbufs[i]);
351          fprintf(f, "    ");
352          DUMP(resource, dstate->framebuffer_state.cbufs[i]->texture);
353       }
354    if (dstate->framebuffer_state.zsbuf) {
355       fprintf(f, "  " COLOR_STATE "zsbuf:" COLOR_RESET "\n    ");
356       DUMP(surface, dstate->framebuffer_state.zsbuf);
357       fprintf(f, "    ");
358       DUMP(resource, dstate->framebuffer_state.zsbuf->texture);
359    }
360    fprintf(f, "\n");
361 }
362 
363 static void
dd_dump_launch_grid(struct dd_draw_state * dstate,struct pipe_grid_info * info,FILE * f)364 dd_dump_launch_grid(struct dd_draw_state *dstate, struct pipe_grid_info *info, FILE *f)
365 {
366    fprintf(f, "%s:\n", __func__+8);
367    DUMP(grid_info, info);
368    fprintf(f, "\n");
369 
370    dd_dump_shader(dstate, PIPE_SHADER_COMPUTE, f);
371    fprintf(f, "\n");
372 }
373 
374 static void
dd_dump_resource_copy_region(struct dd_draw_state * dstate,struct call_resource_copy_region * info,FILE * f)375 dd_dump_resource_copy_region(struct dd_draw_state *dstate,
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_ADDR(box, info, src_box);
388 }
389 
390 static void
dd_dump_blit(struct dd_draw_state * dstate,struct pipe_blit_info * info,FILE * f)391 dd_dump_blit(struct dd_draw_state *dstate, 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(dstate, f);
412 }
413 
414 static void
dd_dump_generate_mipmap(struct dd_draw_state * dstate,FILE * f)415 dd_dump_generate_mipmap(struct dd_draw_state *dstate, FILE *f)
416 {
417    fprintf(f, "%s:\n", __func__+8);
418    /* TODO */
419 }
420 
421 static void
dd_dump_get_query_result_resource(struct call_get_query_result_resource * info,FILE * f)422 dd_dump_get_query_result_resource(struct call_get_query_result_resource *info, FILE *f)
423 {
424    fprintf(f, "%s:\n", __func__ + 8);
425    DUMP_M(query_type, info, query_type);
426    DUMP_M(uint, info, wait);
427    DUMP_M(query_value_type, info, result_type);
428    DUMP_M(int, info, index);
429    DUMP_M(resource, info, resource);
430    DUMP_M(uint, info, offset);
431 }
432 
433 static void
dd_dump_flush_resource(struct dd_draw_state * dstate,struct pipe_resource * res,FILE * f)434 dd_dump_flush_resource(struct dd_draw_state *dstate, struct pipe_resource *res,
435                        FILE *f)
436 {
437    fprintf(f, "%s:\n", __func__+8);
438    DUMP(resource, res);
439 }
440 
441 static void
dd_dump_clear(struct dd_draw_state * dstate,struct call_clear * info,FILE * f)442 dd_dump_clear(struct dd_draw_state *dstate, struct call_clear *info, FILE *f)
443 {
444    fprintf(f, "%s:\n", __func__+8);
445    DUMP_M(uint, info, buffers);
446    DUMP_M_ADDR(color_union, info, color);
447    DUMP_M(double, info, depth);
448    DUMP_M(hex, info, stencil);
449 }
450 
451 static void
dd_dump_clear_buffer(struct dd_draw_state * dstate,struct call_clear_buffer * info,FILE * f)452 dd_dump_clear_buffer(struct dd_draw_state *dstate, struct call_clear_buffer *info,
453                      FILE *f)
454 {
455    int i;
456    const char *value = (const char*)info->clear_value;
457 
458    fprintf(f, "%s:\n", __func__+8);
459    DUMP_M(resource, info, res);
460    DUMP_M(uint, info, offset);
461    DUMP_M(uint, info, size);
462    DUMP_M(uint, info, clear_value_size);
463 
464    fprintf(f, "  clear_value:");
465    for (i = 0; i < info->clear_value_size; i++)
466       fprintf(f, " %02x", value[i]);
467    fprintf(f, "\n");
468 }
469 
470 static void
dd_dump_transfer_map(struct call_transfer_map * info,FILE * f)471 dd_dump_transfer_map(struct call_transfer_map *info, FILE *f)
472 {
473    fprintf(f, "%s:\n", __func__+8);
474    DUMP_M_ADDR(transfer, info, transfer);
475    DUMP_M(ptr, info, transfer_ptr);
476    DUMP_M(ptr, info, ptr);
477 }
478 
479 static void
dd_dump_transfer_flush_region(struct call_transfer_flush_region * info,FILE * f)480 dd_dump_transfer_flush_region(struct call_transfer_flush_region *info, FILE *f)
481 {
482    fprintf(f, "%s:\n", __func__+8);
483    DUMP_M_ADDR(transfer, info, transfer);
484    DUMP_M(ptr, info, transfer_ptr);
485    DUMP_M_ADDR(box, info, box);
486 }
487 
488 static void
dd_dump_transfer_unmap(struct call_transfer_unmap * info,FILE * f)489 dd_dump_transfer_unmap(struct call_transfer_unmap *info, FILE *f)
490 {
491    fprintf(f, "%s:\n", __func__+8);
492    DUMP_M_ADDR(transfer, info, transfer);
493    DUMP_M(ptr, info, transfer_ptr);
494 }
495 
496 static void
dd_dump_buffer_subdata(struct call_buffer_subdata * info,FILE * f)497 dd_dump_buffer_subdata(struct call_buffer_subdata *info, FILE *f)
498 {
499    fprintf(f, "%s:\n", __func__+8);
500    DUMP_M(resource, info, resource);
501    DUMP_M(transfer_usage, info, usage);
502    DUMP_M(uint, info, offset);
503    DUMP_M(uint, info, size);
504    DUMP_M(ptr, info, data);
505 }
506 
507 static void
dd_dump_texture_subdata(struct call_texture_subdata * info,FILE * f)508 dd_dump_texture_subdata(struct call_texture_subdata *info, FILE *f)
509 {
510    fprintf(f, "%s:\n", __func__+8);
511    DUMP_M(resource, info, resource);
512    DUMP_M(uint, info, level);
513    DUMP_M(transfer_usage, info, usage);
514    DUMP_M_ADDR(box, info, box);
515    DUMP_M(ptr, info, data);
516    DUMP_M(uint, info, stride);
517    DUMP_M(uint, info, layer_stride);
518 }
519 
520 static void
dd_dump_clear_texture(struct dd_draw_state * dstate,FILE * f)521 dd_dump_clear_texture(struct dd_draw_state *dstate, FILE *f)
522 {
523    fprintf(f, "%s:\n", __func__+8);
524    /* TODO */
525 }
526 
527 static void
dd_dump_clear_render_target(struct dd_draw_state * dstate,FILE * f)528 dd_dump_clear_render_target(struct dd_draw_state *dstate, FILE *f)
529 {
530    fprintf(f, "%s:\n", __func__+8);
531    /* TODO */
532 }
533 
534 static void
dd_dump_clear_depth_stencil(struct dd_draw_state * dstate,FILE * f)535 dd_dump_clear_depth_stencil(struct dd_draw_state *dstate, FILE *f)
536 {
537    fprintf(f, "%s:\n", __func__+8);
538    /* TODO */
539 }
540 
541 static void
dd_dump_driver_state(struct dd_context * dctx,FILE * f,unsigned flags)542 dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags)
543 {
544    if (dctx->pipe->dump_debug_state) {
545 	   fprintf(f,"\n\n**************************************************"
546 		     "***************************\n");
547 	   fprintf(f, "Driver-specific state:\n\n");
548 	   dctx->pipe->dump_debug_state(dctx->pipe, f, flags);
549    }
550 }
551 
552 static void
dd_dump_call(FILE * f,struct dd_draw_state * state,struct dd_call * call)553 dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call)
554 {
555    switch (call->type) {
556    case CALL_DRAW_VBO:
557       dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f);
558       break;
559    case CALL_LAUNCH_GRID:
560       dd_dump_launch_grid(state, &call->info.launch_grid, f);
561       break;
562    case CALL_RESOURCE_COPY_REGION:
563       dd_dump_resource_copy_region(state,
564                                    &call->info.resource_copy_region, f);
565       break;
566    case CALL_BLIT:
567       dd_dump_blit(state, &call->info.blit, f);
568       break;
569    case CALL_FLUSH_RESOURCE:
570       dd_dump_flush_resource(state, call->info.flush_resource, f);
571       break;
572    case CALL_CLEAR:
573       dd_dump_clear(state, &call->info.clear, f);
574       break;
575    case CALL_CLEAR_BUFFER:
576       dd_dump_clear_buffer(state, &call->info.clear_buffer, f);
577       break;
578    case CALL_CLEAR_TEXTURE:
579       dd_dump_clear_texture(state, f);
580       break;
581    case CALL_CLEAR_RENDER_TARGET:
582       dd_dump_clear_render_target(state, f);
583       break;
584    case CALL_CLEAR_DEPTH_STENCIL:
585       dd_dump_clear_depth_stencil(state, f);
586       break;
587    case CALL_GENERATE_MIPMAP:
588       dd_dump_generate_mipmap(state, f);
589       break;
590    case CALL_GET_QUERY_RESULT_RESOURCE:
591       dd_dump_get_query_result_resource(&call->info.get_query_result_resource, f);
592       break;
593    case CALL_TRANSFER_MAP:
594       dd_dump_transfer_map(&call->info.transfer_map, f);
595       break;
596    case CALL_TRANSFER_FLUSH_REGION:
597       dd_dump_transfer_flush_region(&call->info.transfer_flush_region, f);
598       break;
599    case CALL_TRANSFER_UNMAP:
600       dd_dump_transfer_unmap(&call->info.transfer_unmap, f);
601       break;
602    case CALL_BUFFER_SUBDATA:
603       dd_dump_buffer_subdata(&call->info.buffer_subdata, f);
604       break;
605    case CALL_TEXTURE_SUBDATA:
606       dd_dump_texture_subdata(&call->info.texture_subdata, f);
607       break;
608    }
609 }
610 
611 static void
dd_kill_process(void)612 dd_kill_process(void)
613 {
614    sync();
615    fprintf(stderr, "dd: Aborting the process...\n");
616    fflush(stdout);
617    fflush(stderr);
618    exit(1);
619 }
620 
621 static void
dd_unreference_copy_of_call(struct dd_call * dst)622 dd_unreference_copy_of_call(struct dd_call *dst)
623 {
624    switch (dst->type) {
625    case CALL_DRAW_VBO:
626       pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL);
627       pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
628       pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL);
629       if (dst->info.draw_vbo.draw.index_size &&
630           !dst->info.draw_vbo.draw.has_user_indices)
631          pipe_resource_reference(&dst->info.draw_vbo.draw.index.resource, NULL);
632       else
633          dst->info.draw_vbo.draw.index.user = NULL;
634       break;
635    case CALL_LAUNCH_GRID:
636       pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
637       break;
638    case CALL_RESOURCE_COPY_REGION:
639       pipe_resource_reference(&dst->info.resource_copy_region.dst, NULL);
640       pipe_resource_reference(&dst->info.resource_copy_region.src, NULL);
641       break;
642    case CALL_BLIT:
643       pipe_resource_reference(&dst->info.blit.dst.resource, NULL);
644       pipe_resource_reference(&dst->info.blit.src.resource, NULL);
645       break;
646    case CALL_FLUSH_RESOURCE:
647       pipe_resource_reference(&dst->info.flush_resource, NULL);
648       break;
649    case CALL_CLEAR:
650       break;
651    case CALL_CLEAR_BUFFER:
652       pipe_resource_reference(&dst->info.clear_buffer.res, NULL);
653       break;
654    case CALL_CLEAR_TEXTURE:
655       break;
656    case CALL_CLEAR_RENDER_TARGET:
657       break;
658    case CALL_CLEAR_DEPTH_STENCIL:
659       break;
660    case CALL_GENERATE_MIPMAP:
661       pipe_resource_reference(&dst->info.generate_mipmap.res, NULL);
662       break;
663    case CALL_GET_QUERY_RESULT_RESOURCE:
664       pipe_resource_reference(&dst->info.get_query_result_resource.resource, NULL);
665       break;
666    case CALL_TRANSFER_MAP:
667       pipe_resource_reference(&dst->info.transfer_map.transfer.resource, NULL);
668       break;
669    case CALL_TRANSFER_FLUSH_REGION:
670       pipe_resource_reference(&dst->info.transfer_flush_region.transfer.resource, NULL);
671       break;
672    case CALL_TRANSFER_UNMAP:
673       pipe_resource_reference(&dst->info.transfer_unmap.transfer.resource, NULL);
674       break;
675    case CALL_BUFFER_SUBDATA:
676       pipe_resource_reference(&dst->info.buffer_subdata.resource, NULL);
677       break;
678    case CALL_TEXTURE_SUBDATA:
679       pipe_resource_reference(&dst->info.texture_subdata.resource, NULL);
680       break;
681    }
682 }
683 
684 static void
dd_init_copy_of_draw_state(struct dd_draw_state_copy * state)685 dd_init_copy_of_draw_state(struct dd_draw_state_copy *state)
686 {
687    unsigned i,j;
688 
689    /* Just clear pointers to gallium objects. Don't clear the whole structure,
690     * because it would kill performance with its size of 130 KB.
691     */
692    memset(state->base.vertex_buffers, 0,
693           sizeof(state->base.vertex_buffers));
694    memset(state->base.so_targets, 0,
695           sizeof(state->base.so_targets));
696    memset(state->base.constant_buffers, 0,
697           sizeof(state->base.constant_buffers));
698    memset(state->base.sampler_views, 0,
699           sizeof(state->base.sampler_views));
700    memset(state->base.shader_images, 0,
701           sizeof(state->base.shader_images));
702    memset(state->base.shader_buffers, 0,
703           sizeof(state->base.shader_buffers));
704    memset(&state->base.framebuffer_state, 0,
705           sizeof(state->base.framebuffer_state));
706 
707    memset(state->shaders, 0, sizeof(state->shaders));
708 
709    state->base.render_cond.query = &state->render_cond;
710 
711    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
712       state->base.shaders[i] = &state->shaders[i];
713       for (j = 0; j < PIPE_MAX_SAMPLERS; j++)
714          state->base.sampler_states[i][j] = &state->sampler_states[i][j];
715    }
716 
717    state->base.velems = &state->velems;
718    state->base.rs = &state->rs;
719    state->base.dsa = &state->dsa;
720    state->base.blend = &state->blend;
721 }
722 
723 static void
dd_unreference_copy_of_draw_state(struct dd_draw_state_copy * state)724 dd_unreference_copy_of_draw_state(struct dd_draw_state_copy *state)
725 {
726    struct dd_draw_state *dst = &state->base;
727    unsigned i,j;
728 
729    for (i = 0; i < ARRAY_SIZE(dst->vertex_buffers); i++)
730       pipe_vertex_buffer_unreference(&dst->vertex_buffers[i]);
731    for (i = 0; i < ARRAY_SIZE(dst->so_targets); i++)
732       pipe_so_target_reference(&dst->so_targets[i], NULL);
733 
734    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
735       if (dst->shaders[i])
736          tgsi_free_tokens(dst->shaders[i]->state.shader.tokens);
737 
738       for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++)
739          pipe_resource_reference(&dst->constant_buffers[i][j].buffer, NULL);
740       for (j = 0; j < PIPE_MAX_SAMPLERS; j++)
741          pipe_sampler_view_reference(&dst->sampler_views[i][j], NULL);
742       for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++)
743          pipe_resource_reference(&dst->shader_images[i][j].resource, NULL);
744       for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++)
745          pipe_resource_reference(&dst->shader_buffers[i][j].buffer, NULL);
746    }
747 
748    util_unreference_framebuffer_state(&dst->framebuffer_state);
749 }
750 
751 static void
dd_copy_draw_state(struct dd_draw_state * dst,struct dd_draw_state * src)752 dd_copy_draw_state(struct dd_draw_state *dst, struct dd_draw_state *src)
753 {
754    unsigned i,j;
755 
756    if (src->render_cond.query) {
757       *dst->render_cond.query = *src->render_cond.query;
758       dst->render_cond.condition = src->render_cond.condition;
759       dst->render_cond.mode = src->render_cond.mode;
760    } else {
761       dst->render_cond.query = NULL;
762    }
763 
764    for (i = 0; i < ARRAY_SIZE(src->vertex_buffers); i++) {
765       pipe_vertex_buffer_reference(&dst->vertex_buffers[i],
766                                    &src->vertex_buffers[i]);
767    }
768 
769    dst->num_so_targets = src->num_so_targets;
770    for (i = 0; i < src->num_so_targets; i++)
771       pipe_so_target_reference(&dst->so_targets[i], src->so_targets[i]);
772    memcpy(dst->so_offsets, src->so_offsets, sizeof(src->so_offsets));
773 
774    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
775       if (!src->shaders[i]) {
776          dst->shaders[i] = NULL;
777          continue;
778       }
779 
780       if (src->shaders[i]) {
781          dst->shaders[i]->state.shader = src->shaders[i]->state.shader;
782          if (src->shaders[i]->state.shader.tokens) {
783             dst->shaders[i]->state.shader.tokens =
784                tgsi_dup_tokens(src->shaders[i]->state.shader.tokens);
785          } else {
786             dst->shaders[i]->state.shader.ir.nir = NULL;
787          }
788       } else {
789          dst->shaders[i] = NULL;
790       }
791 
792       for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
793          pipe_resource_reference(&dst->constant_buffers[i][j].buffer,
794                                  src->constant_buffers[i][j].buffer);
795          memcpy(&dst->constant_buffers[i][j], &src->constant_buffers[i][j],
796                 sizeof(src->constant_buffers[i][j]));
797       }
798 
799       for (j = 0; j < PIPE_MAX_SAMPLERS; j++) {
800          pipe_sampler_view_reference(&dst->sampler_views[i][j],
801                                      src->sampler_views[i][j]);
802          if (src->sampler_states[i][j])
803             dst->sampler_states[i][j]->state.sampler =
804                src->sampler_states[i][j]->state.sampler;
805          else
806             dst->sampler_states[i][j] = NULL;
807       }
808 
809       for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) {
810          pipe_resource_reference(&dst->shader_images[i][j].resource,
811                                  src->shader_images[i][j].resource);
812          memcpy(&dst->shader_images[i][j], &src->shader_images[i][j],
813                 sizeof(src->shader_images[i][j]));
814       }
815 
816       for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) {
817          pipe_resource_reference(&dst->shader_buffers[i][j].buffer,
818                                  src->shader_buffers[i][j].buffer);
819          memcpy(&dst->shader_buffers[i][j], &src->shader_buffers[i][j],
820                 sizeof(src->shader_buffers[i][j]));
821       }
822    }
823 
824    if (src->velems)
825       dst->velems->state.velems = src->velems->state.velems;
826    else
827       dst->velems = NULL;
828 
829    if (src->rs)
830       dst->rs->state.rs = src->rs->state.rs;
831    else
832       dst->rs = NULL;
833 
834    if (src->dsa)
835       dst->dsa->state.dsa = src->dsa->state.dsa;
836    else
837       dst->dsa = NULL;
838 
839    if (src->blend)
840       dst->blend->state.blend = src->blend->state.blend;
841    else
842       dst->blend = NULL;
843 
844    dst->blend_color = src->blend_color;
845    dst->stencil_ref = src->stencil_ref;
846    dst->sample_mask = src->sample_mask;
847    dst->min_samples = src->min_samples;
848    dst->clip_state = src->clip_state;
849    util_copy_framebuffer_state(&dst->framebuffer_state, &src->framebuffer_state);
850    memcpy(dst->scissors, src->scissors, sizeof(src->scissors));
851    memcpy(dst->viewports, src->viewports, sizeof(src->viewports));
852    memcpy(dst->tess_default_levels, src->tess_default_levels,
853           sizeof(src->tess_default_levels));
854    dst->apitrace_call_number = src->apitrace_call_number;
855 }
856 
857 static void
dd_free_record(struct pipe_screen * screen,struct dd_draw_record * record)858 dd_free_record(struct pipe_screen *screen, struct dd_draw_record *record)
859 {
860    u_log_page_destroy(record->log_page);
861    dd_unreference_copy_of_call(&record->call);
862    dd_unreference_copy_of_draw_state(&record->draw_state);
863    screen->fence_reference(screen, &record->prev_bottom_of_pipe, NULL);
864    screen->fence_reference(screen, &record->top_of_pipe, NULL);
865    screen->fence_reference(screen, &record->bottom_of_pipe, NULL);
866    util_queue_fence_destroy(&record->driver_finished);
867    FREE(record);
868 }
869 
870 static void
dd_write_record(FILE * f,struct dd_draw_record * record)871 dd_write_record(FILE *f, struct dd_draw_record *record)
872 {
873    PRINT_NAMED(ptr, "pipe", record->dctx->pipe);
874    PRINT_NAMED(ns, "time before (API call)", record->time_before);
875    PRINT_NAMED(ns, "time after (driver done)", record->time_after);
876    fprintf(f, "\n");
877 
878    dd_dump_call(f, &record->draw_state.base, &record->call);
879 
880    if (record->log_page) {
881       fprintf(f,"\n\n**************************************************"
882                 "***************************\n");
883       fprintf(f, "Context Log:\n\n");
884       u_log_page_print(record->log_page, f);
885    }
886 }
887 
888 static void
dd_maybe_dump_record(struct dd_screen * dscreen,struct dd_draw_record * record)889 dd_maybe_dump_record(struct dd_screen *dscreen, struct dd_draw_record *record)
890 {
891    if (dscreen->dump_mode == DD_DUMP_ONLY_HANGS ||
892        (dscreen->dump_mode == DD_DUMP_APITRACE_CALL &&
893         dscreen->apitrace_dump_call != record->draw_state.base.apitrace_call_number))
894       return;
895 
896    char name[512];
897    dd_get_debug_filename_and_mkdir(name, sizeof(name), dscreen->verbose);
898    FILE *f = fopen(name, "w");
899    if (!f) {
900       fprintf(stderr, "dd: failed to open %s\n", name);
901       return;
902    }
903 
904    dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number);
905    dd_write_record(f, record);
906 
907    fclose(f);
908 }
909 
910 static const char *
dd_fence_state(struct pipe_screen * screen,struct pipe_fence_handle * fence,bool * not_reached)911 dd_fence_state(struct pipe_screen *screen, struct pipe_fence_handle *fence,
912                bool *not_reached)
913 {
914    if (!fence)
915       return "---";
916 
917    bool ok = screen->fence_finish(screen, NULL, fence, 0);
918 
919    if (not_reached && !ok)
920       *not_reached = true;
921 
922    return ok ? "YES" : "NO ";
923 }
924 
925 static void
dd_report_hang(struct dd_context * dctx)926 dd_report_hang(struct dd_context *dctx)
927 {
928    struct dd_screen *dscreen = dd_screen(dctx->base.screen);
929    struct pipe_screen *screen = dscreen->screen;
930    bool encountered_hang = false;
931    bool stop_output = false;
932    unsigned num_later = 0;
933 
934    fprintf(stderr, "GPU hang detected, collecting information...\n\n");
935 
936    fprintf(stderr, "Draw #   driver  prev BOP  TOP  BOP  dump file\n"
937                    "-------------------------------------------------------------\n");
938 
939    list_for_each_entry(struct dd_draw_record, record, &dctx->records, list) {
940       if (!encountered_hang &&
941           screen->fence_finish(screen, NULL, record->bottom_of_pipe, 0)) {
942          dd_maybe_dump_record(dscreen, record);
943          continue;
944       }
945 
946       if (stop_output) {
947          dd_maybe_dump_record(dscreen, record);
948          num_later++;
949          continue;
950       }
951 
952       bool driver = util_queue_fence_is_signalled(&record->driver_finished);
953       bool top_not_reached = false;
954       const char *prev_bop = dd_fence_state(screen, record->prev_bottom_of_pipe, NULL);
955       const char *top = dd_fence_state(screen, record->top_of_pipe, &top_not_reached);
956       const char *bop = dd_fence_state(screen, record->bottom_of_pipe, NULL);
957 
958       fprintf(stderr, "%-9u %s      %s     %s  %s  ",
959               record->draw_call, driver ? "YES" : "NO ", prev_bop, top, bop);
960 
961       char name[512];
962       dd_get_debug_filename_and_mkdir(name, sizeof(name), false);
963 
964       FILE *f = fopen(name, "w");
965       if (!f) {
966          fprintf(stderr, "fopen failed\n");
967       } else {
968          fprintf(stderr, "%s\n", name);
969 
970          dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number);
971          dd_write_record(f, record);
972 
973          if (!encountered_hang) {
974             dd_dump_driver_state(dctx, f, PIPE_DUMP_DEVICE_STATUS_REGISTERS);
975             dd_dump_dmesg(f);
976          }
977 
978          fclose(f);
979       }
980 
981       if (top_not_reached)
982          stop_output = true;
983       encountered_hang = true;
984    }
985 
986    if (num_later || dctx->record_pending) {
987       fprintf(stderr, "... and %u%s additional draws.\n", num_later,
988               dctx->record_pending ? "+1 (pending)" : "");
989    }
990 
991    fprintf(stderr, "\nDone.\n");
992    dd_kill_process();
993 }
994 
995 int
dd_thread_main(void * input)996 dd_thread_main(void *input)
997 {
998    struct dd_context *dctx = (struct dd_context *)input;
999    struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1000    struct pipe_screen *screen = dscreen->screen;
1001 
1002    mtx_lock(&dctx->mutex);
1003 
1004    for (;;) {
1005       struct list_head records;
1006       struct pipe_fence_handle *fence;
1007       struct pipe_fence_handle *fence2 = NULL;
1008 
1009       list_replace(&dctx->records, &records);
1010       list_inithead(&dctx->records);
1011       dctx->num_records = 0;
1012 
1013       if (dctx->api_stalled)
1014          cnd_signal(&dctx->cond);
1015 
1016       if (!list_empty(&records)) {
1017          /* Wait for the youngest draw. This means hangs can take a bit longer
1018           * to detect, but it's more efficient this way. */
1019          struct dd_draw_record *youngest =
1020             LIST_ENTRY(struct dd_draw_record, records.prev, list);
1021          fence = youngest->bottom_of_pipe;
1022       } else if (dctx->record_pending) {
1023          /* Wait for pending fences, in case the driver ends up hanging internally. */
1024          fence = dctx->record_pending->prev_bottom_of_pipe;
1025          fence2 = dctx->record_pending->top_of_pipe;
1026       } else if (dctx->kill_thread) {
1027          break;
1028       } else {
1029          cnd_wait(&dctx->cond, &dctx->mutex);
1030          continue;
1031       }
1032       mtx_unlock(&dctx->mutex);
1033 
1034       /* Fences can be NULL legitimately when timeout detection is disabled. */
1035       if ((fence &&
1036            !screen->fence_finish(screen, NULL, fence,
1037                                  (uint64_t)dscreen->timeout_ms * 1000*1000)) ||
1038           (fence2 &&
1039            !screen->fence_finish(screen, NULL, fence2,
1040                                  (uint64_t)dscreen->timeout_ms * 1000*1000))) {
1041          mtx_lock(&dctx->mutex);
1042          list_splice(&records, &dctx->records);
1043          dd_report_hang(dctx);
1044          /* we won't actually get here */
1045          mtx_unlock(&dctx->mutex);
1046       }
1047 
1048       list_for_each_entry_safe(struct dd_draw_record, record, &records, list) {
1049          dd_maybe_dump_record(dscreen, record);
1050          list_del(&record->list);
1051          dd_free_record(screen, record);
1052       }
1053 
1054       mtx_lock(&dctx->mutex);
1055    }
1056    mtx_unlock(&dctx->mutex);
1057    return 0;
1058 }
1059 
1060 static struct dd_draw_record *
dd_create_record(struct dd_context * dctx)1061 dd_create_record(struct dd_context *dctx)
1062 {
1063    struct dd_draw_record *record;
1064 
1065    record = MALLOC_STRUCT(dd_draw_record);
1066    if (!record)
1067       return NULL;
1068 
1069    record->dctx = dctx;
1070    record->draw_call = dctx->num_draw_calls;
1071 
1072    record->prev_bottom_of_pipe = NULL;
1073    record->top_of_pipe = NULL;
1074    record->bottom_of_pipe = NULL;
1075    record->log_page = NULL;
1076    util_queue_fence_init(&record->driver_finished);
1077 
1078    dd_init_copy_of_draw_state(&record->draw_state);
1079    dd_copy_draw_state(&record->draw_state.base, &dctx->draw_state);
1080 
1081    return record;
1082 }
1083 
1084 static void
dd_context_flush(struct pipe_context * _pipe,struct pipe_fence_handle ** fence,unsigned flags)1085 dd_context_flush(struct pipe_context *_pipe,
1086                  struct pipe_fence_handle **fence, unsigned flags)
1087 {
1088    struct dd_context *dctx = dd_context(_pipe);
1089    struct pipe_context *pipe = dctx->pipe;
1090 
1091    pipe->flush(pipe, fence, flags);
1092 }
1093 
1094 static void
dd_before_draw(struct dd_context * dctx,struct dd_draw_record * record)1095 dd_before_draw(struct dd_context *dctx, struct dd_draw_record *record)
1096 {
1097    struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1098    struct pipe_context *pipe = dctx->pipe;
1099    struct pipe_screen *screen = dscreen->screen;
1100 
1101    record->time_before = os_time_get_nano();
1102 
1103    if (dscreen->timeout_ms > 0) {
1104       if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count) {
1105          pipe->flush(pipe, &record->prev_bottom_of_pipe, 0);
1106          screen->fence_reference(screen, &record->top_of_pipe, record->prev_bottom_of_pipe);
1107       } else {
1108          pipe->flush(pipe, &record->prev_bottom_of_pipe,
1109                      PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE);
1110          pipe->flush(pipe, &record->top_of_pipe,
1111                      PIPE_FLUSH_DEFERRED | PIPE_FLUSH_TOP_OF_PIPE);
1112       }
1113 
1114       mtx_lock(&dctx->mutex);
1115       dctx->record_pending = record;
1116       if (list_empty(&dctx->records))
1117          cnd_signal(&dctx->cond);
1118       mtx_unlock(&dctx->mutex);
1119    }
1120 }
1121 
1122 static void
dd_after_draw_async(void * data)1123 dd_after_draw_async(void *data)
1124 {
1125    struct dd_draw_record *record = (struct dd_draw_record *)data;
1126    struct dd_context *dctx = record->dctx;
1127    struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1128 
1129    record->log_page = u_log_new_page(&dctx->log);
1130    record->time_after = os_time_get_nano();
1131 
1132    if (!util_queue_fence_is_signalled(&record->driver_finished))
1133       util_queue_fence_signal(&record->driver_finished);
1134 
1135    if (dscreen->dump_mode == DD_DUMP_APITRACE_CALL &&
1136        dscreen->apitrace_dump_call > dctx->draw_state.apitrace_call_number) {
1137       dd_thread_join(dctx);
1138       /* No need to continue. */
1139       exit(0);
1140    }
1141 }
1142 
1143 static void
dd_after_draw(struct dd_context * dctx,struct dd_draw_record * record)1144 dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record)
1145 {
1146    struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1147    struct pipe_context *pipe = dctx->pipe;
1148 
1149    if (dscreen->timeout_ms > 0) {
1150       unsigned flush_flags;
1151       if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count)
1152          flush_flags = 0;
1153       else
1154          flush_flags = PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE;
1155       pipe->flush(pipe, &record->bottom_of_pipe, flush_flags);
1156 
1157       assert(record == dctx->record_pending);
1158    }
1159 
1160    if (pipe->callback) {
1161       util_queue_fence_reset(&record->driver_finished);
1162       pipe->callback(pipe, dd_after_draw_async, record, true);
1163    } else {
1164       dd_after_draw_async(record);
1165    }
1166 
1167    mtx_lock(&dctx->mutex);
1168    if (unlikely(dctx->num_records > 10000)) {
1169       dctx->api_stalled = true;
1170       /* Since this is only a heuristic to prevent the API thread from getting
1171        * too far ahead, we don't need a loop here. */
1172       cnd_wait(&dctx->cond, &dctx->mutex);
1173       dctx->api_stalled = false;
1174    }
1175 
1176    if (list_empty(&dctx->records))
1177       cnd_signal(&dctx->cond);
1178 
1179    list_addtail(&record->list, &dctx->records);
1180    dctx->record_pending = NULL;
1181    dctx->num_records++;
1182    mtx_unlock(&dctx->mutex);
1183 
1184    ++dctx->num_draw_calls;
1185    if (dscreen->skip_count && dctx->num_draw_calls % 10000 == 0)
1186       fprintf(stderr, "Gallium debugger reached %u draw calls.\n",
1187               dctx->num_draw_calls);
1188 }
1189 
1190 static void
dd_context_draw_vbo(struct pipe_context * _pipe,const struct pipe_draw_info * info)1191 dd_context_draw_vbo(struct pipe_context *_pipe,
1192                     const struct pipe_draw_info *info)
1193 {
1194    struct dd_context *dctx = dd_context(_pipe);
1195    struct pipe_context *pipe = dctx->pipe;
1196    struct dd_draw_record *record = dd_create_record(dctx);
1197 
1198    record->call.type = CALL_DRAW_VBO;
1199    record->call.info.draw_vbo.draw = *info;
1200    record->call.info.draw_vbo.draw.count_from_stream_output = NULL;
1201    pipe_so_target_reference(&record->call.info.draw_vbo.draw.count_from_stream_output,
1202                             info->count_from_stream_output);
1203    if (info->index_size && !info->has_user_indices) {
1204       record->call.info.draw_vbo.draw.index.resource = NULL;
1205       pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource,
1206                               info->index.resource);
1207    }
1208 
1209    if (info->indirect) {
1210       record->call.info.draw_vbo.indirect = *info->indirect;
1211       record->call.info.draw_vbo.draw.indirect = &record->call.info.draw_vbo.indirect;
1212 
1213       record->call.info.draw_vbo.indirect.buffer = NULL;
1214       pipe_resource_reference(&record->call.info.draw_vbo.indirect.buffer,
1215                               info->indirect->buffer);
1216       record->call.info.draw_vbo.indirect.indirect_draw_count = NULL;
1217       pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count,
1218                               info->indirect->indirect_draw_count);
1219    } else {
1220       memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect));
1221    }
1222 
1223    dd_before_draw(dctx, record);
1224    pipe->draw_vbo(pipe, info);
1225    dd_after_draw(dctx, record);
1226 }
1227 
1228 static void
dd_context_launch_grid(struct pipe_context * _pipe,const struct pipe_grid_info * info)1229 dd_context_launch_grid(struct pipe_context *_pipe,
1230                        const struct pipe_grid_info *info)
1231 {
1232    struct dd_context *dctx = dd_context(_pipe);
1233    struct pipe_context *pipe = dctx->pipe;
1234    struct dd_draw_record *record = dd_create_record(dctx);
1235 
1236    record->call.type = CALL_LAUNCH_GRID;
1237    record->call.info.launch_grid = *info;
1238    record->call.info.launch_grid.indirect = NULL;
1239    pipe_resource_reference(&record->call.info.launch_grid.indirect, info->indirect);
1240 
1241    dd_before_draw(dctx, record);
1242    pipe->launch_grid(pipe, info);
1243    dd_after_draw(dctx, record);
1244 }
1245 
1246 static void
dd_context_resource_copy_region(struct pipe_context * _pipe,struct pipe_resource * dst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * src,unsigned src_level,const struct pipe_box * src_box)1247 dd_context_resource_copy_region(struct pipe_context *_pipe,
1248                                 struct pipe_resource *dst, unsigned dst_level,
1249                                 unsigned dstx, unsigned dsty, unsigned dstz,
1250                                 struct pipe_resource *src, unsigned src_level,
1251                                 const struct pipe_box *src_box)
1252 {
1253    struct dd_context *dctx = dd_context(_pipe);
1254    struct pipe_context *pipe = dctx->pipe;
1255    struct dd_draw_record *record = dd_create_record(dctx);
1256 
1257    record->call.type = CALL_RESOURCE_COPY_REGION;
1258    record->call.info.resource_copy_region.dst = NULL;
1259    pipe_resource_reference(&record->call.info.resource_copy_region.dst, dst);
1260    record->call.info.resource_copy_region.dst_level = dst_level;
1261    record->call.info.resource_copy_region.dstx = dstx;
1262    record->call.info.resource_copy_region.dsty = dsty;
1263    record->call.info.resource_copy_region.dstz = dstz;
1264    record->call.info.resource_copy_region.src = NULL;
1265    pipe_resource_reference(&record->call.info.resource_copy_region.src, src);
1266    record->call.info.resource_copy_region.src_level = src_level;
1267    record->call.info.resource_copy_region.src_box = *src_box;
1268 
1269    dd_before_draw(dctx, record);
1270    pipe->resource_copy_region(pipe,
1271                               dst, dst_level, dstx, dsty, dstz,
1272                               src, src_level, src_box);
1273    dd_after_draw(dctx, record);
1274 }
1275 
1276 static void
dd_context_blit(struct pipe_context * _pipe,const struct pipe_blit_info * info)1277 dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
1278 {
1279    struct dd_context *dctx = dd_context(_pipe);
1280    struct pipe_context *pipe = dctx->pipe;
1281    struct dd_draw_record *record = dd_create_record(dctx);
1282 
1283    record->call.type = CALL_BLIT;
1284    record->call.info.blit = *info;
1285    record->call.info.blit.dst.resource = NULL;
1286    pipe_resource_reference(&record->call.info.blit.dst.resource, info->dst.resource);
1287    record->call.info.blit.src.resource = NULL;
1288    pipe_resource_reference(&record->call.info.blit.src.resource, info->src.resource);
1289 
1290    dd_before_draw(dctx, record);
1291    pipe->blit(pipe, info);
1292    dd_after_draw(dctx, record);
1293 }
1294 
1295 static boolean
dd_context_generate_mipmap(struct pipe_context * _pipe,struct pipe_resource * res,enum pipe_format format,unsigned base_level,unsigned last_level,unsigned first_layer,unsigned last_layer)1296 dd_context_generate_mipmap(struct pipe_context *_pipe,
1297                            struct pipe_resource *res,
1298                            enum pipe_format format,
1299                            unsigned base_level,
1300                            unsigned last_level,
1301                            unsigned first_layer,
1302                            unsigned last_layer)
1303 {
1304    struct dd_context *dctx = dd_context(_pipe);
1305    struct pipe_context *pipe = dctx->pipe;
1306    struct dd_draw_record *record = dd_create_record(dctx);
1307    boolean result;
1308 
1309    record->call.type = CALL_GENERATE_MIPMAP;
1310    record->call.info.generate_mipmap.res = NULL;
1311    pipe_resource_reference(&record->call.info.generate_mipmap.res, res);
1312    record->call.info.generate_mipmap.format = format;
1313    record->call.info.generate_mipmap.base_level = base_level;
1314    record->call.info.generate_mipmap.last_level = last_level;
1315    record->call.info.generate_mipmap.first_layer = first_layer;
1316    record->call.info.generate_mipmap.last_layer = last_layer;
1317 
1318    dd_before_draw(dctx, record);
1319    result = pipe->generate_mipmap(pipe, res, format, base_level, last_level,
1320                                   first_layer, last_layer);
1321    dd_after_draw(dctx, record);
1322    return result;
1323 }
1324 
1325 static void
dd_context_get_query_result_resource(struct pipe_context * _pipe,struct pipe_query * query,boolean wait,enum pipe_query_value_type result_type,int index,struct pipe_resource * resource,unsigned offset)1326 dd_context_get_query_result_resource(struct pipe_context *_pipe,
1327                                      struct pipe_query *query,
1328                                      boolean wait,
1329                                      enum pipe_query_value_type result_type,
1330                                      int index,
1331                                      struct pipe_resource *resource,
1332                                      unsigned offset)
1333 {
1334    struct dd_context *dctx = dd_context(_pipe);
1335    struct dd_query *dquery = dd_query(query);
1336    struct pipe_context *pipe = dctx->pipe;
1337    struct dd_draw_record *record = dd_create_record(dctx);
1338 
1339    record->call.type = CALL_GET_QUERY_RESULT_RESOURCE;
1340    record->call.info.get_query_result_resource.query = query;
1341    record->call.info.get_query_result_resource.wait = wait;
1342    record->call.info.get_query_result_resource.result_type = result_type;
1343    record->call.info.get_query_result_resource.index = index;
1344    record->call.info.get_query_result_resource.resource = NULL;
1345    pipe_resource_reference(&record->call.info.get_query_result_resource.resource,
1346                            resource);
1347    record->call.info.get_query_result_resource.offset = offset;
1348 
1349    /* The query may be deleted by the time we need to print it. */
1350    record->call.info.get_query_result_resource.query_type = dquery->type;
1351 
1352    dd_before_draw(dctx, record);
1353    pipe->get_query_result_resource(pipe, dquery->query, wait,
1354                                    result_type, index, resource, offset);
1355    dd_after_draw(dctx, record);
1356 }
1357 
1358 static void
dd_context_flush_resource(struct pipe_context * _pipe,struct pipe_resource * resource)1359 dd_context_flush_resource(struct pipe_context *_pipe,
1360                           struct pipe_resource *resource)
1361 {
1362    struct dd_context *dctx = dd_context(_pipe);
1363    struct pipe_context *pipe = dctx->pipe;
1364    struct dd_draw_record *record = dd_create_record(dctx);
1365 
1366    record->call.type = CALL_FLUSH_RESOURCE;
1367    record->call.info.flush_resource = NULL;
1368    pipe_resource_reference(&record->call.info.flush_resource, resource);
1369 
1370    dd_before_draw(dctx, record);
1371    pipe->flush_resource(pipe, resource);
1372    dd_after_draw(dctx, record);
1373 }
1374 
1375 static void
dd_context_clear(struct pipe_context * _pipe,unsigned buffers,const union pipe_color_union * color,double depth,unsigned stencil)1376 dd_context_clear(struct pipe_context *_pipe, unsigned buffers,
1377                  const union pipe_color_union *color, double depth,
1378                  unsigned stencil)
1379 {
1380    struct dd_context *dctx = dd_context(_pipe);
1381    struct pipe_context *pipe = dctx->pipe;
1382    struct dd_draw_record *record = dd_create_record(dctx);
1383 
1384    record->call.type = CALL_CLEAR;
1385    record->call.info.clear.buffers = buffers;
1386    record->call.info.clear.color = *color;
1387    record->call.info.clear.depth = depth;
1388    record->call.info.clear.stencil = stencil;
1389 
1390    dd_before_draw(dctx, record);
1391    pipe->clear(pipe, buffers, color, depth, stencil);
1392    dd_after_draw(dctx, record);
1393 }
1394 
1395 static void
dd_context_clear_render_target(struct pipe_context * _pipe,struct pipe_surface * dst,const union pipe_color_union * color,unsigned dstx,unsigned dsty,unsigned width,unsigned height,bool render_condition_enabled)1396 dd_context_clear_render_target(struct pipe_context *_pipe,
1397                                struct pipe_surface *dst,
1398                                const union pipe_color_union *color,
1399                                unsigned dstx, unsigned dsty,
1400                                unsigned width, unsigned height,
1401                                bool render_condition_enabled)
1402 {
1403    struct dd_context *dctx = dd_context(_pipe);
1404    struct pipe_context *pipe = dctx->pipe;
1405    struct dd_draw_record *record = dd_create_record(dctx);
1406 
1407    record->call.type = CALL_CLEAR_RENDER_TARGET;
1408 
1409    dd_before_draw(dctx, record);
1410    pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height,
1411                              render_condition_enabled);
1412    dd_after_draw(dctx, record);
1413 }
1414 
1415 static void
dd_context_clear_depth_stencil(struct pipe_context * _pipe,struct pipe_surface * dst,unsigned clear_flags,double depth,unsigned stencil,unsigned dstx,unsigned dsty,unsigned width,unsigned height,bool render_condition_enabled)1416 dd_context_clear_depth_stencil(struct pipe_context *_pipe,
1417                                struct pipe_surface *dst, unsigned clear_flags,
1418                                double depth, unsigned stencil, unsigned dstx,
1419                                unsigned dsty, unsigned width, unsigned height,
1420                                bool render_condition_enabled)
1421 {
1422    struct dd_context *dctx = dd_context(_pipe);
1423    struct pipe_context *pipe = dctx->pipe;
1424    struct dd_draw_record *record = dd_create_record(dctx);
1425 
1426    record->call.type = CALL_CLEAR_DEPTH_STENCIL;
1427 
1428    dd_before_draw(dctx, record);
1429    pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
1430                              dstx, dsty, width, height,
1431                              render_condition_enabled);
1432    dd_after_draw(dctx, record);
1433 }
1434 
1435 static void
dd_context_clear_buffer(struct pipe_context * _pipe,struct pipe_resource * res,unsigned offset,unsigned size,const void * clear_value,int clear_value_size)1436 dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res,
1437                         unsigned offset, unsigned size,
1438                         const void *clear_value, int clear_value_size)
1439 {
1440    struct dd_context *dctx = dd_context(_pipe);
1441    struct pipe_context *pipe = dctx->pipe;
1442    struct dd_draw_record *record = dd_create_record(dctx);
1443 
1444    record->call.type = CALL_CLEAR_BUFFER;
1445    record->call.info.clear_buffer.res = NULL;
1446    pipe_resource_reference(&record->call.info.clear_buffer.res, res);
1447    record->call.info.clear_buffer.offset = offset;
1448    record->call.info.clear_buffer.size = size;
1449    record->call.info.clear_buffer.clear_value = clear_value;
1450    record->call.info.clear_buffer.clear_value_size = clear_value_size;
1451 
1452    dd_before_draw(dctx, record);
1453    pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size);
1454    dd_after_draw(dctx, record);
1455 }
1456 
1457 static void
dd_context_clear_texture(struct pipe_context * _pipe,struct pipe_resource * res,unsigned level,const struct pipe_box * box,const void * data)1458 dd_context_clear_texture(struct pipe_context *_pipe,
1459                          struct pipe_resource *res,
1460                          unsigned level,
1461                          const struct pipe_box *box,
1462                          const void *data)
1463 {
1464    struct dd_context *dctx = dd_context(_pipe);
1465    struct pipe_context *pipe = dctx->pipe;
1466    struct dd_draw_record *record = dd_create_record(dctx);
1467 
1468    record->call.type = CALL_CLEAR_TEXTURE;
1469 
1470    dd_before_draw(dctx, record);
1471    pipe->clear_texture(pipe, res, level, box, data);
1472    dd_after_draw(dctx, record);
1473 }
1474 
1475 /********************************************************************
1476  * transfer
1477  */
1478 
1479 static void *
dd_context_transfer_map(struct pipe_context * _pipe,struct pipe_resource * resource,unsigned level,unsigned usage,const struct pipe_box * box,struct pipe_transfer ** transfer)1480 dd_context_transfer_map(struct pipe_context *_pipe,
1481                         struct pipe_resource *resource, unsigned level,
1482                         unsigned usage, const struct pipe_box *box,
1483                         struct pipe_transfer **transfer)
1484 {
1485    struct dd_context *dctx = dd_context(_pipe);
1486    struct pipe_context *pipe = dctx->pipe;
1487    struct dd_draw_record *record =
1488       dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1489 
1490    if (record) {
1491       record->call.type = CALL_TRANSFER_MAP;
1492 
1493       dd_before_draw(dctx, record);
1494    }
1495    void *ptr = pipe->transfer_map(pipe, resource, level, usage, box, transfer);
1496    if (record) {
1497       record->call.info.transfer_map.transfer_ptr = *transfer;
1498       record->call.info.transfer_map.ptr = ptr;
1499       if (*transfer) {
1500          record->call.info.transfer_map.transfer = **transfer;
1501          record->call.info.transfer_map.transfer.resource = NULL;
1502          pipe_resource_reference(&record->call.info.transfer_map.transfer.resource,
1503                                  (*transfer)->resource);
1504       } else {
1505          memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer));
1506       }
1507 
1508       dd_after_draw(dctx, record);
1509    }
1510    return ptr;
1511 }
1512 
1513 static void
dd_context_transfer_flush_region(struct pipe_context * _pipe,struct pipe_transfer * transfer,const struct pipe_box * box)1514 dd_context_transfer_flush_region(struct pipe_context *_pipe,
1515                                  struct pipe_transfer *transfer,
1516                                  const struct pipe_box *box)
1517 {
1518    struct dd_context *dctx = dd_context(_pipe);
1519    struct pipe_context *pipe = dctx->pipe;
1520    struct dd_draw_record *record =
1521       dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1522 
1523    if (record) {
1524       record->call.type = CALL_TRANSFER_FLUSH_REGION;
1525       record->call.info.transfer_flush_region.transfer_ptr = transfer;
1526       record->call.info.transfer_flush_region.box = *box;
1527       record->call.info.transfer_flush_region.transfer = *transfer;
1528       record->call.info.transfer_flush_region.transfer.resource = NULL;
1529       pipe_resource_reference(
1530             &record->call.info.transfer_flush_region.transfer.resource,
1531             transfer->resource);
1532 
1533       dd_before_draw(dctx, record);
1534    }
1535    pipe->transfer_flush_region(pipe, transfer, box);
1536    if (record)
1537       dd_after_draw(dctx, record);
1538 }
1539 
1540 static void
dd_context_transfer_unmap(struct pipe_context * _pipe,struct pipe_transfer * transfer)1541 dd_context_transfer_unmap(struct pipe_context *_pipe,
1542                           struct pipe_transfer *transfer)
1543 {
1544    struct dd_context *dctx = dd_context(_pipe);
1545    struct pipe_context *pipe = dctx->pipe;
1546    struct dd_draw_record *record =
1547       dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1548 
1549    if (record) {
1550       record->call.type = CALL_TRANSFER_UNMAP;
1551       record->call.info.transfer_unmap.transfer_ptr = transfer;
1552       record->call.info.transfer_unmap.transfer = *transfer;
1553       record->call.info.transfer_unmap.transfer.resource = NULL;
1554       pipe_resource_reference(
1555             &record->call.info.transfer_unmap.transfer.resource,
1556             transfer->resource);
1557 
1558       dd_before_draw(dctx, record);
1559    }
1560    pipe->transfer_unmap(pipe, transfer);
1561    if (record)
1562       dd_after_draw(dctx, record);
1563 }
1564 
1565 static void
dd_context_buffer_subdata(struct pipe_context * _pipe,struct pipe_resource * resource,unsigned usage,unsigned offset,unsigned size,const void * data)1566 dd_context_buffer_subdata(struct pipe_context *_pipe,
1567                           struct pipe_resource *resource,
1568                           unsigned usage, unsigned offset,
1569                           unsigned size, const void *data)
1570 {
1571    struct dd_context *dctx = dd_context(_pipe);
1572    struct pipe_context *pipe = dctx->pipe;
1573    struct dd_draw_record *record =
1574       dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1575 
1576    if (record) {
1577       record->call.type = CALL_BUFFER_SUBDATA;
1578       record->call.info.buffer_subdata.resource = NULL;
1579       pipe_resource_reference(&record->call.info.buffer_subdata.resource, resource);
1580       record->call.info.buffer_subdata.usage = usage;
1581       record->call.info.buffer_subdata.offset = offset;
1582       record->call.info.buffer_subdata.size = size;
1583       record->call.info.buffer_subdata.data = data;
1584 
1585       dd_before_draw(dctx, record);
1586    }
1587    pipe->buffer_subdata(pipe, resource, usage, offset, size, data);
1588    if (record)
1589       dd_after_draw(dctx, record);
1590 }
1591 
1592 static void
dd_context_texture_subdata(struct pipe_context * _pipe,struct pipe_resource * resource,unsigned level,unsigned usage,const struct pipe_box * box,const void * data,unsigned stride,unsigned layer_stride)1593 dd_context_texture_subdata(struct pipe_context *_pipe,
1594                            struct pipe_resource *resource,
1595                            unsigned level, unsigned usage,
1596                            const struct pipe_box *box,
1597                            const void *data, unsigned stride,
1598                            unsigned layer_stride)
1599 {
1600    struct dd_context *dctx = dd_context(_pipe);
1601    struct pipe_context *pipe = dctx->pipe;
1602    struct dd_draw_record *record =
1603       dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1604 
1605    if (record) {
1606       record->call.type = CALL_TEXTURE_SUBDATA;
1607       record->call.info.texture_subdata.resource = NULL;
1608       pipe_resource_reference(&record->call.info.texture_subdata.resource, resource);
1609       record->call.info.texture_subdata.level = level;
1610       record->call.info.texture_subdata.usage = usage;
1611       record->call.info.texture_subdata.box = *box;
1612       record->call.info.texture_subdata.data = data;
1613       record->call.info.texture_subdata.stride = stride;
1614       record->call.info.texture_subdata.layer_stride = layer_stride;
1615 
1616       dd_before_draw(dctx, record);
1617    }
1618    pipe->texture_subdata(pipe, resource, level, usage, box, data,
1619                          stride, layer_stride);
1620    if (record)
1621       dd_after_draw(dctx, record);
1622 }
1623 
1624 void
dd_init_draw_functions(struct dd_context * dctx)1625 dd_init_draw_functions(struct dd_context *dctx)
1626 {
1627    CTX_INIT(flush);
1628    CTX_INIT(draw_vbo);
1629    CTX_INIT(launch_grid);
1630    CTX_INIT(resource_copy_region);
1631    CTX_INIT(blit);
1632    CTX_INIT(clear);
1633    CTX_INIT(clear_render_target);
1634    CTX_INIT(clear_depth_stencil);
1635    CTX_INIT(clear_buffer);
1636    CTX_INIT(clear_texture);
1637    CTX_INIT(flush_resource);
1638    CTX_INIT(generate_mipmap);
1639    CTX_INIT(get_query_result_resource);
1640    CTX_INIT(transfer_map);
1641    CTX_INIT(transfer_flush_region);
1642    CTX_INIT(transfer_unmap);
1643    CTX_INIT(buffer_subdata);
1644    CTX_INIT(texture_subdata);
1645 }
1646