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(query_flags, info, flags);
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_draw_vertex_state(struct pipe_context *_pipe,
1350                             struct pipe_vertex_state *state,
1351                             uint32_t partial_velem_mask,
1352                             struct pipe_draw_vertex_state_info info,
1353                             const struct pipe_draw_start_count_bias *draws,
1354                             unsigned num_draws)
1355{
1356   struct dd_context *dctx = dd_context(_pipe);
1357   struct pipe_context *pipe = dctx->pipe;
1358   struct dd_draw_record *record = dd_create_record(dctx);
1359
1360   record->call.type = CALL_DRAW_VBO;
1361   memset(&record->call.info.draw_vbo.info, 0,
1362          sizeof(record->call.info.draw_vbo.info));
1363   record->call.info.draw_vbo.info.mode = info.mode;
1364   record->call.info.draw_vbo.info.index_size = 4;
1365   record->call.info.draw_vbo.info.instance_count = 1;
1366   record->call.info.draw_vbo.drawid_offset = 0;
1367   record->call.info.draw_vbo.draw = draws[0];
1368   record->call.info.draw_vbo.info.index.resource = NULL;
1369   pipe_resource_reference(&record->call.info.draw_vbo.info.index.resource,
1370                           state->input.indexbuf);
1371   memset(&record->call.info.draw_vbo.indirect, 0,
1372          sizeof(record->call.info.draw_vbo.indirect));
1373
1374   dd_before_draw(dctx, record);
1375   pipe->draw_vertex_state(pipe, state, partial_velem_mask, info, draws, num_draws);
1376   dd_after_draw(dctx, record);
1377}
1378
1379static void
1380dd_context_launch_grid(struct pipe_context *_pipe,
1381                       const struct pipe_grid_info *info)
1382{
1383   struct dd_context *dctx = dd_context(_pipe);
1384   struct pipe_context *pipe = dctx->pipe;
1385   struct dd_draw_record *record = dd_create_record(dctx);
1386
1387   record->call.type = CALL_LAUNCH_GRID;
1388   record->call.info.launch_grid = *info;
1389   record->call.info.launch_grid.indirect = NULL;
1390   pipe_resource_reference(&record->call.info.launch_grid.indirect, info->indirect);
1391
1392   dd_before_draw(dctx, record);
1393   pipe->launch_grid(pipe, info);
1394   dd_after_draw(dctx, record);
1395}
1396
1397static void
1398dd_context_resource_copy_region(struct pipe_context *_pipe,
1399                                struct pipe_resource *dst, unsigned dst_level,
1400                                unsigned dstx, unsigned dsty, unsigned dstz,
1401                                struct pipe_resource *src, unsigned src_level,
1402                                const struct pipe_box *src_box)
1403{
1404   struct dd_context *dctx = dd_context(_pipe);
1405   struct pipe_context *pipe = dctx->pipe;
1406   struct dd_draw_record *record = dd_create_record(dctx);
1407
1408   record->call.type = CALL_RESOURCE_COPY_REGION;
1409   record->call.info.resource_copy_region.dst = NULL;
1410   pipe_resource_reference(&record->call.info.resource_copy_region.dst, dst);
1411   record->call.info.resource_copy_region.dst_level = dst_level;
1412   record->call.info.resource_copy_region.dstx = dstx;
1413   record->call.info.resource_copy_region.dsty = dsty;
1414   record->call.info.resource_copy_region.dstz = dstz;
1415   record->call.info.resource_copy_region.src = NULL;
1416   pipe_resource_reference(&record->call.info.resource_copy_region.src, src);
1417   record->call.info.resource_copy_region.src_level = src_level;
1418   record->call.info.resource_copy_region.src_box = *src_box;
1419
1420   dd_before_draw(dctx, record);
1421   pipe->resource_copy_region(pipe,
1422                              dst, dst_level, dstx, dsty, dstz,
1423                              src, src_level, src_box);
1424   dd_after_draw(dctx, record);
1425}
1426
1427static void
1428dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
1429{
1430   struct dd_context *dctx = dd_context(_pipe);
1431   struct pipe_context *pipe = dctx->pipe;
1432   struct dd_draw_record *record = dd_create_record(dctx);
1433
1434   record->call.type = CALL_BLIT;
1435   record->call.info.blit = *info;
1436   record->call.info.blit.dst.resource = NULL;
1437   pipe_resource_reference(&record->call.info.blit.dst.resource, info->dst.resource);
1438   record->call.info.blit.src.resource = NULL;
1439   pipe_resource_reference(&record->call.info.blit.src.resource, info->src.resource);
1440
1441   dd_before_draw(dctx, record);
1442   pipe->blit(pipe, info);
1443   dd_after_draw(dctx, record);
1444}
1445
1446static bool
1447dd_context_generate_mipmap(struct pipe_context *_pipe,
1448                           struct pipe_resource *res,
1449                           enum pipe_format format,
1450                           unsigned base_level,
1451                           unsigned last_level,
1452                           unsigned first_layer,
1453                           unsigned last_layer)
1454{
1455   struct dd_context *dctx = dd_context(_pipe);
1456   struct pipe_context *pipe = dctx->pipe;
1457   struct dd_draw_record *record = dd_create_record(dctx);
1458   bool result;
1459
1460   record->call.type = CALL_GENERATE_MIPMAP;
1461   record->call.info.generate_mipmap.res = NULL;
1462   pipe_resource_reference(&record->call.info.generate_mipmap.res, res);
1463   record->call.info.generate_mipmap.format = format;
1464   record->call.info.generate_mipmap.base_level = base_level;
1465   record->call.info.generate_mipmap.last_level = last_level;
1466   record->call.info.generate_mipmap.first_layer = first_layer;
1467   record->call.info.generate_mipmap.last_layer = last_layer;
1468
1469   dd_before_draw(dctx, record);
1470   result = pipe->generate_mipmap(pipe, res, format, base_level, last_level,
1471                                  first_layer, last_layer);
1472   dd_after_draw(dctx, record);
1473   return result;
1474}
1475
1476static void
1477dd_context_get_query_result_resource(struct pipe_context *_pipe,
1478                                     struct pipe_query *query,
1479                                     enum pipe_query_flags flags,
1480                                     enum pipe_query_value_type result_type,
1481                                     int index,
1482                                     struct pipe_resource *resource,
1483                                     unsigned offset)
1484{
1485   struct dd_context *dctx = dd_context(_pipe);
1486   struct dd_query *dquery = dd_query(query);
1487   struct pipe_context *pipe = dctx->pipe;
1488   struct dd_draw_record *record = dd_create_record(dctx);
1489
1490   record->call.type = CALL_GET_QUERY_RESULT_RESOURCE;
1491   record->call.info.get_query_result_resource.query = query;
1492   record->call.info.get_query_result_resource.flags = flags;
1493   record->call.info.get_query_result_resource.result_type = result_type;
1494   record->call.info.get_query_result_resource.index = index;
1495   record->call.info.get_query_result_resource.resource = NULL;
1496   pipe_resource_reference(&record->call.info.get_query_result_resource.resource,
1497                           resource);
1498   record->call.info.get_query_result_resource.offset = offset;
1499
1500   /* The query may be deleted by the time we need to print it. */
1501   record->call.info.get_query_result_resource.query_type = dquery->type;
1502
1503   dd_before_draw(dctx, record);
1504   pipe->get_query_result_resource(pipe, dquery->query, flags,
1505                                   result_type, index, resource, offset);
1506   dd_after_draw(dctx, record);
1507}
1508
1509static void
1510dd_context_flush_resource(struct pipe_context *_pipe,
1511                          struct pipe_resource *resource)
1512{
1513   struct dd_context *dctx = dd_context(_pipe);
1514   struct pipe_context *pipe = dctx->pipe;
1515   struct dd_draw_record *record = dd_create_record(dctx);
1516
1517   record->call.type = CALL_FLUSH_RESOURCE;
1518   record->call.info.flush_resource = NULL;
1519   pipe_resource_reference(&record->call.info.flush_resource, resource);
1520
1521   dd_before_draw(dctx, record);
1522   pipe->flush_resource(pipe, resource);
1523   dd_after_draw(dctx, record);
1524}
1525
1526static void
1527dd_context_clear(struct pipe_context *_pipe, unsigned buffers, const struct pipe_scissor_state *scissor_state,
1528                 const union pipe_color_union *color, double depth,
1529                 unsigned stencil)
1530{
1531   struct dd_context *dctx = dd_context(_pipe);
1532   struct pipe_context *pipe = dctx->pipe;
1533   struct dd_draw_record *record = dd_create_record(dctx);
1534
1535   record->call.type = CALL_CLEAR;
1536   record->call.info.clear.buffers = buffers;
1537   if (scissor_state)
1538      record->call.info.clear.scissor_state = *scissor_state;
1539   record->call.info.clear.color = *color;
1540   record->call.info.clear.depth = depth;
1541   record->call.info.clear.stencil = stencil;
1542
1543   dd_before_draw(dctx, record);
1544   pipe->clear(pipe, buffers, scissor_state, color, depth, stencil);
1545   dd_after_draw(dctx, record);
1546}
1547
1548static void
1549dd_context_clear_render_target(struct pipe_context *_pipe,
1550                               struct pipe_surface *dst,
1551                               const union pipe_color_union *color,
1552                               unsigned dstx, unsigned dsty,
1553                               unsigned width, unsigned height,
1554                               bool render_condition_enabled)
1555{
1556   struct dd_context *dctx = dd_context(_pipe);
1557   struct pipe_context *pipe = dctx->pipe;
1558   struct dd_draw_record *record = dd_create_record(dctx);
1559
1560   record->call.type = CALL_CLEAR_RENDER_TARGET;
1561
1562   dd_before_draw(dctx, record);
1563   pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height,
1564                             render_condition_enabled);
1565   dd_after_draw(dctx, record);
1566}
1567
1568static void
1569dd_context_clear_depth_stencil(struct pipe_context *_pipe,
1570                               struct pipe_surface *dst, unsigned clear_flags,
1571                               double depth, unsigned stencil, unsigned dstx,
1572                               unsigned dsty, unsigned width, unsigned height,
1573                               bool render_condition_enabled)
1574{
1575   struct dd_context *dctx = dd_context(_pipe);
1576   struct pipe_context *pipe = dctx->pipe;
1577   struct dd_draw_record *record = dd_create_record(dctx);
1578
1579   record->call.type = CALL_CLEAR_DEPTH_STENCIL;
1580
1581   dd_before_draw(dctx, record);
1582   pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
1583                             dstx, dsty, width, height,
1584                             render_condition_enabled);
1585   dd_after_draw(dctx, record);
1586}
1587
1588static void
1589dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res,
1590                        unsigned offset, unsigned size,
1591                        const void *clear_value, int clear_value_size)
1592{
1593   struct dd_context *dctx = dd_context(_pipe);
1594   struct pipe_context *pipe = dctx->pipe;
1595   struct dd_draw_record *record = dd_create_record(dctx);
1596
1597   record->call.type = CALL_CLEAR_BUFFER;
1598   record->call.info.clear_buffer.res = NULL;
1599   pipe_resource_reference(&record->call.info.clear_buffer.res, res);
1600   record->call.info.clear_buffer.offset = offset;
1601   record->call.info.clear_buffer.size = size;
1602   record->call.info.clear_buffer.clear_value = clear_value;
1603   record->call.info.clear_buffer.clear_value_size = clear_value_size;
1604
1605   dd_before_draw(dctx, record);
1606   pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size);
1607   dd_after_draw(dctx, record);
1608}
1609
1610static void
1611dd_context_clear_texture(struct pipe_context *_pipe,
1612                         struct pipe_resource *res,
1613                         unsigned level,
1614                         const struct pipe_box *box,
1615                         const void *data)
1616{
1617   struct dd_context *dctx = dd_context(_pipe);
1618   struct pipe_context *pipe = dctx->pipe;
1619   struct dd_draw_record *record = dd_create_record(dctx);
1620
1621   record->call.type = CALL_CLEAR_TEXTURE;
1622
1623   dd_before_draw(dctx, record);
1624   pipe->clear_texture(pipe, res, level, box, data);
1625   dd_after_draw(dctx, record);
1626}
1627
1628/********************************************************************
1629 * transfer
1630 */
1631
1632static void *
1633dd_context_buffer_map(struct pipe_context *_pipe,
1634                      struct pipe_resource *resource, unsigned level,
1635                      unsigned usage, const struct pipe_box *box,
1636                      struct pipe_transfer **transfer)
1637{
1638   struct dd_context *dctx = dd_context(_pipe);
1639   struct pipe_context *pipe = dctx->pipe;
1640   struct dd_draw_record *record =
1641      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1642
1643   if (record) {
1644      record->call.type = CALL_TRANSFER_MAP;
1645
1646      dd_before_draw(dctx, record);
1647   }
1648   void *ptr = pipe->buffer_map(pipe, resource, level, usage, box, transfer);
1649   if (record) {
1650      record->call.info.transfer_map.transfer_ptr = *transfer;
1651      record->call.info.transfer_map.ptr = ptr;
1652      if (*transfer) {
1653         record->call.info.transfer_map.transfer = **transfer;
1654         record->call.info.transfer_map.transfer.resource = NULL;
1655         pipe_resource_reference(&record->call.info.transfer_map.transfer.resource,
1656                                 (*transfer)->resource);
1657      } else {
1658         memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer));
1659      }
1660
1661      dd_after_draw(dctx, record);
1662   }
1663   return ptr;
1664}
1665
1666static void *
1667dd_context_texture_map(struct pipe_context *_pipe,
1668                       struct pipe_resource *resource, unsigned level,
1669                       unsigned usage, const struct pipe_box *box,
1670                       struct pipe_transfer **transfer)
1671{
1672   struct dd_context *dctx = dd_context(_pipe);
1673   struct pipe_context *pipe = dctx->pipe;
1674   struct dd_draw_record *record =
1675      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1676
1677   if (record) {
1678      record->call.type = CALL_TRANSFER_MAP;
1679
1680      dd_before_draw(dctx, record);
1681   }
1682   void *ptr = pipe->texture_map(pipe, resource, level, usage, box, transfer);
1683   if (record) {
1684      record->call.info.transfer_map.transfer_ptr = *transfer;
1685      record->call.info.transfer_map.ptr = ptr;
1686      if (*transfer) {
1687         record->call.info.transfer_map.transfer = **transfer;
1688         record->call.info.transfer_map.transfer.resource = NULL;
1689         pipe_resource_reference(&record->call.info.transfer_map.transfer.resource,
1690                                 (*transfer)->resource);
1691      } else {
1692         memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer));
1693      }
1694
1695      dd_after_draw(dctx, record);
1696   }
1697   return ptr;
1698}
1699
1700static void
1701dd_context_transfer_flush_region(struct pipe_context *_pipe,
1702                                 struct pipe_transfer *transfer,
1703                                 const struct pipe_box *box)
1704{
1705   struct dd_context *dctx = dd_context(_pipe);
1706   struct pipe_context *pipe = dctx->pipe;
1707   struct dd_draw_record *record =
1708      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1709
1710   if (record) {
1711      record->call.type = CALL_TRANSFER_FLUSH_REGION;
1712      record->call.info.transfer_flush_region.transfer_ptr = transfer;
1713      record->call.info.transfer_flush_region.box = *box;
1714      record->call.info.transfer_flush_region.transfer = *transfer;
1715      record->call.info.transfer_flush_region.transfer.resource = NULL;
1716      pipe_resource_reference(
1717            &record->call.info.transfer_flush_region.transfer.resource,
1718            transfer->resource);
1719
1720      dd_before_draw(dctx, record);
1721   }
1722   pipe->transfer_flush_region(pipe, transfer, box);
1723   if (record)
1724      dd_after_draw(dctx, record);
1725}
1726
1727static void
1728dd_context_buffer_unmap(struct pipe_context *_pipe,
1729                          struct pipe_transfer *transfer)
1730{
1731   struct dd_context *dctx = dd_context(_pipe);
1732   struct pipe_context *pipe = dctx->pipe;
1733   struct dd_draw_record *record =
1734      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1735
1736   if (record) {
1737      record->call.type = CALL_TRANSFER_UNMAP;
1738      record->call.info.transfer_unmap.transfer_ptr = transfer;
1739      record->call.info.transfer_unmap.transfer = *transfer;
1740      record->call.info.transfer_unmap.transfer.resource = NULL;
1741      pipe_resource_reference(
1742            &record->call.info.transfer_unmap.transfer.resource,
1743            transfer->resource);
1744
1745      dd_before_draw(dctx, record);
1746   }
1747   pipe->buffer_unmap(pipe, transfer);
1748   if (record)
1749      dd_after_draw(dctx, record);
1750}
1751
1752static void
1753dd_context_texture_unmap(struct pipe_context *_pipe,
1754                          struct pipe_transfer *transfer)
1755{
1756   struct dd_context *dctx = dd_context(_pipe);
1757   struct pipe_context *pipe = dctx->pipe;
1758   struct dd_draw_record *record =
1759      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1760
1761   if (record) {
1762      record->call.type = CALL_TRANSFER_UNMAP;
1763      record->call.info.transfer_unmap.transfer_ptr = transfer;
1764      record->call.info.transfer_unmap.transfer = *transfer;
1765      record->call.info.transfer_unmap.transfer.resource = NULL;
1766      pipe_resource_reference(
1767            &record->call.info.transfer_unmap.transfer.resource,
1768            transfer->resource);
1769
1770      dd_before_draw(dctx, record);
1771   }
1772   pipe->texture_unmap(pipe, transfer);
1773   if (record)
1774      dd_after_draw(dctx, record);
1775}
1776
1777static void
1778dd_context_buffer_subdata(struct pipe_context *_pipe,
1779                          struct pipe_resource *resource,
1780                          unsigned usage, unsigned offset,
1781                          unsigned size, const void *data)
1782{
1783   struct dd_context *dctx = dd_context(_pipe);
1784   struct pipe_context *pipe = dctx->pipe;
1785   struct dd_draw_record *record =
1786      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1787
1788   if (record) {
1789      record->call.type = CALL_BUFFER_SUBDATA;
1790      record->call.info.buffer_subdata.resource = NULL;
1791      pipe_resource_reference(&record->call.info.buffer_subdata.resource, resource);
1792      record->call.info.buffer_subdata.usage = usage;
1793      record->call.info.buffer_subdata.offset = offset;
1794      record->call.info.buffer_subdata.size = size;
1795      record->call.info.buffer_subdata.data = data;
1796
1797      dd_before_draw(dctx, record);
1798   }
1799   pipe->buffer_subdata(pipe, resource, usage, offset, size, data);
1800   if (record)
1801      dd_after_draw(dctx, record);
1802}
1803
1804static void
1805dd_context_texture_subdata(struct pipe_context *_pipe,
1806                           struct pipe_resource *resource,
1807                           unsigned level, unsigned usage,
1808                           const struct pipe_box *box,
1809                           const void *data, unsigned stride,
1810                           unsigned layer_stride)
1811{
1812   struct dd_context *dctx = dd_context(_pipe);
1813   struct pipe_context *pipe = dctx->pipe;
1814   struct dd_draw_record *record =
1815      dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
1816
1817   if (record) {
1818      record->call.type = CALL_TEXTURE_SUBDATA;
1819      record->call.info.texture_subdata.resource = NULL;
1820      pipe_resource_reference(&record->call.info.texture_subdata.resource, resource);
1821      record->call.info.texture_subdata.level = level;
1822      record->call.info.texture_subdata.usage = usage;
1823      record->call.info.texture_subdata.box = *box;
1824      record->call.info.texture_subdata.data = data;
1825      record->call.info.texture_subdata.stride = stride;
1826      record->call.info.texture_subdata.layer_stride = layer_stride;
1827
1828      dd_before_draw(dctx, record);
1829   }
1830   pipe->texture_subdata(pipe, resource, level, usage, box, data,
1831                         stride, layer_stride);
1832   if (record)
1833      dd_after_draw(dctx, record);
1834}
1835
1836void
1837dd_init_draw_functions(struct dd_context *dctx)
1838{
1839   CTX_INIT(flush);
1840   CTX_INIT(draw_vbo);
1841   CTX_INIT(launch_grid);
1842   CTX_INIT(resource_copy_region);
1843   CTX_INIT(blit);
1844   CTX_INIT(clear);
1845   CTX_INIT(clear_render_target);
1846   CTX_INIT(clear_depth_stencil);
1847   CTX_INIT(clear_buffer);
1848   CTX_INIT(clear_texture);
1849   CTX_INIT(flush_resource);
1850   CTX_INIT(generate_mipmap);
1851   CTX_INIT(get_query_result_resource);
1852   CTX_INIT(buffer_map);
1853   CTX_INIT(texture_map);
1854   CTX_INIT(transfer_flush_region);
1855   CTX_INIT(buffer_unmap);
1856   CTX_INIT(texture_unmap);
1857   CTX_INIT(buffer_subdata);
1858   CTX_INIT(texture_subdata);
1859   CTX_INIT(draw_vertex_state);
1860}
1861