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