1/**************************************************************************
2 *
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "dd_pipe.h"
29
30#include "util/u_dump.h"
31#include "util/u_format.h"
32#include "util/u_framebuffer.h"
33#include "util/u_helpers.h"
34#include "util/u_inlines.h"
35#include "util/u_memory.h"
36#include "tgsi/tgsi_parse.h"
37#include "tgsi/tgsi_scan.h"
38#include "os/os_time.h"
39#include <inttypes.h>
40
41
42static FILE *
43dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number)
44{
45   struct pipe_screen *screen = dscreen->screen;
46   char cmd_line[4096];
47
48   FILE *f = dd_get_debug_file(dscreen->verbose);
49   if (!f)
50      return NULL;
51
52   if (os_get_command_line(cmd_line, sizeof(cmd_line)))
53      fprintf(f, "Command: %s\n", cmd_line);
54   fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
55   fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
56   fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
57
58   if (apitrace_call_number)
59      fprintf(f, "Last apitrace call: %u\n\n",
60              apitrace_call_number);
61   return f;
62}
63
64static void
65dd_dump_dmesg(FILE *f)
66{
67   char line[2000];
68   FILE *p = popen("dmesg | tail -n60", "r");
69
70   if (!p)
71      return;
72
73   fprintf(f, "\nLast 60 lines of dmesg:\n\n");
74   while (fgets(line, sizeof(line), p))
75      fputs(line, f);
76
77   pclose(p);
78}
79
80static void
81dd_close_file_stream(FILE *f)
82{
83   fclose(f);
84}
85
86static unsigned
87dd_num_active_viewports(struct dd_draw_state *dstate)
88{
89   struct tgsi_shader_info info;
90   const struct tgsi_token *tokens;
91
92   if (dstate->shaders[PIPE_SHADER_GEOMETRY])
93      tokens = dstate->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens;
94   else if (dstate->shaders[PIPE_SHADER_TESS_EVAL])
95      tokens = dstate->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens;
96   else if (dstate->shaders[PIPE_SHADER_VERTEX])
97      tokens = dstate->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens;
98   else
99      return 1;
100
101   tgsi_scan_shader(tokens, &info);
102   return info.writes_viewport_index ? PIPE_MAX_VIEWPORTS : 1;
103}
104
105#define COLOR_RESET	"\033[0m"
106#define COLOR_SHADER	"\033[1;32m"
107#define COLOR_STATE	"\033[1;33m"
108
109#define DUMP(name, var) do { \
110   fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \
111   util_dump_##name(f, var); \
112   fprintf(f, "\n"); \
113} while(0)
114
115#define DUMP_I(name, var, i) do { \
116   fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \
117   util_dump_##name(f, var); \
118   fprintf(f, "\n"); \
119} while(0)
120
121#define DUMP_M(name, var, member) do { \
122   fprintf(f, "  " #member ": "); \
123   util_dump_##name(f, (var)->member); \
124   fprintf(f, "\n"); \
125} while(0)
126
127#define DUMP_M_ADDR(name, var, member) do { \
128   fprintf(f, "  " #member ": "); \
129   util_dump_##name(f, &(var)->member); \
130   fprintf(f, "\n"); \
131} while(0)
132
133static void
134print_named_value(FILE *f, const char *name, int value)
135{
136   fprintf(f, COLOR_STATE "%s" COLOR_RESET " = %i\n", name, value);
137}
138
139static void
140print_named_xvalue(FILE *f, const char *name, int value)
141{
142   fprintf(f, COLOR_STATE "%s" COLOR_RESET " = 0x%08x\n", name, value);
143}
144
145static void
146util_dump_uint(FILE *f, unsigned i)
147{
148   fprintf(f, "%u", i);
149}
150
151static void
152util_dump_hex(FILE *f, unsigned i)
153{
154   fprintf(f, "0x%x", i);
155}
156
157static void
158util_dump_double(FILE *f, double d)
159{
160   fprintf(f, "%f", d);
161}
162
163static void
164util_dump_format(FILE *f, enum pipe_format format)
165{
166   fprintf(f, "%s", util_format_name(format));
167}
168
169static void
170util_dump_color_union(FILE *f, const union pipe_color_union *color)
171{
172   fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}",
173           color->f[0], color->f[1], color->f[2], color->f[3],
174           color->ui[0], color->ui[1], color->ui[2], color->ui[3]);
175}
176
177static void
178util_dump_query(FILE *f, struct dd_query *query)
179{
180   if (query->type >= PIPE_QUERY_DRIVER_SPECIFIC)
181      fprintf(f, "PIPE_QUERY_DRIVER_SPECIFIC + %i",
182              query->type - PIPE_QUERY_DRIVER_SPECIFIC);
183   else
184      fprintf(f, "%s", util_dump_query_type(query->type, false));
185}
186
187static void
188dd_dump_render_condition(struct dd_draw_state *dstate, FILE *f)
189{
190   if (dstate->render_cond.query) {
191      fprintf(f, "render condition:\n");
192      DUMP_M(query, &dstate->render_cond, query);
193      DUMP_M(uint, &dstate->render_cond, condition);
194      DUMP_M(uint, &dstate->render_cond, mode);
195      fprintf(f, "\n");
196   }
197}
198
199static void
200dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f)
201{
202   int sh, i;
203   const char *shader_str[PIPE_SHADER_TYPES];
204
205   shader_str[PIPE_SHADER_VERTEX] = "VERTEX";
206   shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL";
207   shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL";
208   shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY";
209   shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT";
210   shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE";
211
212   DUMP(draw_info, info);
213   if (info->indexed) {
214      DUMP(index_buffer, &dstate->index_buffer);
215      if (dstate->index_buffer.buffer)
216         DUMP_M(resource, &dstate->index_buffer, buffer);
217   }
218   if (info->count_from_stream_output)
219      DUMP_M(stream_output_target, info,
220             count_from_stream_output);
221   if (info->indirect)
222      DUMP_M(resource, info, indirect);
223   fprintf(f, "\n");
224
225   /* TODO: dump active queries */
226
227   dd_dump_render_condition(dstate, f);
228
229   for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
230      if (dstate->vertex_buffers[i].buffer ||
231          dstate->vertex_buffers[i].user_buffer) {
232         DUMP_I(vertex_buffer, &dstate->vertex_buffers[i], i);
233         if (dstate->vertex_buffers[i].buffer)
234            DUMP_M(resource, &dstate->vertex_buffers[i], buffer);
235      }
236
237   if (dstate->velems) {
238      print_named_value(f, "num vertex elements",
239                        dstate->velems->state.velems.count);
240      for (i = 0; i < dstate->velems->state.velems.count; i++) {
241         fprintf(f, "  ");
242         DUMP_I(vertex_element, &dstate->velems->state.velems.velems[i], i);
243      }
244   }
245
246   print_named_value(f, "num stream output targets", dstate->num_so_targets);
247   for (i = 0; i < dstate->num_so_targets; i++)
248      if (dstate->so_targets[i]) {
249         DUMP_I(stream_output_target, dstate->so_targets[i], i);
250         DUMP_M(resource, dstate->so_targets[i], buffer);
251         fprintf(f, "  offset = %i\n", dstate->so_offsets[i]);
252      }
253
254   fprintf(f, "\n");
255   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
256      if (sh == PIPE_SHADER_COMPUTE)
257         continue;
258
259      if (sh == PIPE_SHADER_TESS_CTRL &&
260          !dstate->shaders[PIPE_SHADER_TESS_CTRL] &&
261          dstate->shaders[PIPE_SHADER_TESS_EVAL])
262         fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, "
263                 "default_inner_level = {%f, %f}}\n",
264                 dstate->tess_default_levels[0],
265                 dstate->tess_default_levels[1],
266                 dstate->tess_default_levels[2],
267                 dstate->tess_default_levels[3],
268                 dstate->tess_default_levels[4],
269                 dstate->tess_default_levels[5]);
270
271      if (sh == PIPE_SHADER_FRAGMENT)
272         if (dstate->rs) {
273            unsigned num_viewports = dd_num_active_viewports(dstate);
274
275            if (dstate->rs->state.rs.clip_plane_enable)
276               DUMP(clip_state, &dstate->clip_state);
277
278            for (i = 0; i < num_viewports; i++)
279               DUMP_I(viewport_state, &dstate->viewports[i], i);
280
281            if (dstate->rs->state.rs.scissor)
282               for (i = 0; i < num_viewports; i++)
283                  DUMP_I(scissor_state, &dstate->scissors[i], i);
284
285            DUMP(rasterizer_state, &dstate->rs->state.rs);
286
287            if (dstate->rs->state.rs.poly_stipple_enable)
288               DUMP(poly_stipple, &dstate->polygon_stipple);
289            fprintf(f, "\n");
290         }
291
292      if (!dstate->shaders[sh])
293         continue;
294
295      fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]);
296      DUMP(shader_state, &dstate->shaders[sh]->state.shader);
297
298      for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++)
299         if (dstate->constant_buffers[sh][i].buffer ||
300             dstate->constant_buffers[sh][i].user_buffer) {
301            DUMP_I(constant_buffer, &dstate->constant_buffers[sh][i], i);
302            if (dstate->constant_buffers[sh][i].buffer)
303               DUMP_M(resource, &dstate->constant_buffers[sh][i], buffer);
304         }
305
306      for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
307         if (dstate->sampler_states[sh][i])
308            DUMP_I(sampler_state, &dstate->sampler_states[sh][i]->state.sampler, i);
309
310      for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
311         if (dstate->sampler_views[sh][i]) {
312            DUMP_I(sampler_view, dstate->sampler_views[sh][i], i);
313            DUMP_M(resource, dstate->sampler_views[sh][i], texture);
314         }
315
316      for (i = 0; i < PIPE_MAX_SHADER_IMAGES; i++)
317         if (dstate->shader_images[sh][i].resource) {
318            DUMP_I(image_view, &dstate->shader_images[sh][i], i);
319            if (dstate->shader_images[sh][i].resource)
320               DUMP_M(resource, &dstate->shader_images[sh][i], resource);
321         }
322
323      for (i = 0; i < PIPE_MAX_SHADER_BUFFERS; i++)
324         if (dstate->shader_buffers[sh][i].buffer) {
325            DUMP_I(shader_buffer, &dstate->shader_buffers[sh][i], i);
326            if (dstate->shader_buffers[sh][i].buffer)
327               DUMP_M(resource, &dstate->shader_buffers[sh][i], buffer);
328         }
329
330      fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]);
331   }
332
333   if (dstate->dsa)
334      DUMP(depth_stencil_alpha_state, &dstate->dsa->state.dsa);
335   DUMP(stencil_ref, &dstate->stencil_ref);
336
337   if (dstate->blend)
338      DUMP(blend_state, &dstate->blend->state.blend);
339   DUMP(blend_color, &dstate->blend_color);
340
341   print_named_value(f, "min_samples", dstate->min_samples);
342   print_named_xvalue(f, "sample_mask", dstate->sample_mask);
343   fprintf(f, "\n");
344
345   DUMP(framebuffer_state, &dstate->framebuffer_state);
346   for (i = 0; i < dstate->framebuffer_state.nr_cbufs; i++)
347      if (dstate->framebuffer_state.cbufs[i]) {
348         fprintf(f, "  " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n    ", i);
349         DUMP(surface, dstate->framebuffer_state.cbufs[i]);
350         fprintf(f, "    ");
351         DUMP(resource, dstate->framebuffer_state.cbufs[i]->texture);
352      }
353   if (dstate->framebuffer_state.zsbuf) {
354      fprintf(f, "  " COLOR_STATE "zsbuf:" COLOR_RESET "\n    ");
355      DUMP(surface, dstate->framebuffer_state.zsbuf);
356      fprintf(f, "    ");
357      DUMP(resource, dstate->framebuffer_state.zsbuf->texture);
358   }
359   fprintf(f, "\n");
360}
361
362static void
363dd_dump_launch_grid(struct dd_draw_state *dstate, struct pipe_grid_info *info, FILE *f)
364{
365   fprintf(f, "%s:\n", __func__+8);
366   /* TODO */
367}
368
369static void
370dd_dump_resource_copy_region(struct dd_draw_state *dstate,
371                             struct call_resource_copy_region *info,
372                             FILE *f)
373{
374   fprintf(f, "%s:\n", __func__+8);
375   DUMP_M(resource, info, dst);
376   DUMP_M(uint, info, dst_level);
377   DUMP_M(uint, info, dstx);
378   DUMP_M(uint, info, dsty);
379   DUMP_M(uint, info, dstz);
380   DUMP_M(resource, info, src);
381   DUMP_M(uint, info, src_level);
382   DUMP_M_ADDR(box, info, src_box);
383}
384
385static void
386dd_dump_blit(struct dd_draw_state *dstate, struct pipe_blit_info *info, FILE *f)
387{
388   fprintf(f, "%s:\n", __func__+8);
389   DUMP_M(resource, info, dst.resource);
390   DUMP_M(uint, info, dst.level);
391   DUMP_M_ADDR(box, info, dst.box);
392   DUMP_M(format, info, dst.format);
393
394   DUMP_M(resource, info, src.resource);
395   DUMP_M(uint, info, src.level);
396   DUMP_M_ADDR(box, info, src.box);
397   DUMP_M(format, info, src.format);
398
399   DUMP_M(hex, info, mask);
400   DUMP_M(uint, info, filter);
401   DUMP_M(uint, info, scissor_enable);
402   DUMP_M_ADDR(scissor_state, info, scissor);
403   DUMP_M(uint, info, render_condition_enable);
404
405   if (info->render_condition_enable)
406      dd_dump_render_condition(dstate, f);
407}
408
409static void
410dd_dump_generate_mipmap(struct dd_draw_state *dstate, FILE *f)
411{
412   fprintf(f, "%s:\n", __func__+8);
413   /* TODO */
414}
415
416static void
417dd_dump_flush_resource(struct dd_draw_state *dstate, struct pipe_resource *res,
418                       FILE *f)
419{
420   fprintf(f, "%s:\n", __func__+8);
421   DUMP(resource, res);
422}
423
424static void
425dd_dump_clear(struct dd_draw_state *dstate, struct call_clear *info, FILE *f)
426{
427   fprintf(f, "%s:\n", __func__+8);
428   DUMP_M(uint, info, buffers);
429   DUMP_M_ADDR(color_union, info, color);
430   DUMP_M(double, info, depth);
431   DUMP_M(hex, info, stencil);
432}
433
434static void
435dd_dump_clear_buffer(struct dd_draw_state *dstate, struct call_clear_buffer *info,
436                     FILE *f)
437{
438   int i;
439   const char *value = (const char*)info->clear_value;
440
441   fprintf(f, "%s:\n", __func__+8);
442   DUMP_M(resource, info, res);
443   DUMP_M(uint, info, offset);
444   DUMP_M(uint, info, size);
445   DUMP_M(uint, info, clear_value_size);
446
447   fprintf(f, "  clear_value:");
448   for (i = 0; i < info->clear_value_size; i++)
449      fprintf(f, " %02x", value[i]);
450   fprintf(f, "\n");
451}
452
453static void
454dd_dump_clear_render_target(struct dd_draw_state *dstate, FILE *f)
455{
456   fprintf(f, "%s:\n", __func__+8);
457   /* TODO */
458}
459
460static void
461dd_dump_clear_depth_stencil(struct dd_draw_state *dstate, FILE *f)
462{
463   fprintf(f, "%s:\n", __func__+8);
464   /* TODO */
465}
466
467static void
468dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags)
469{
470   if (dctx->pipe->dump_debug_state) {
471	   fprintf(f,"\n\n**************************************************"
472		     "***************************\n");
473	   fprintf(f, "Driver-specific state:\n\n");
474	   dctx->pipe->dump_debug_state(dctx->pipe, f, flags);
475   }
476}
477
478static void
479dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call)
480{
481   switch (call->type) {
482   case CALL_DRAW_VBO:
483      dd_dump_draw_vbo(state, &call->info.draw_vbo, f);
484      break;
485   case CALL_LAUNCH_GRID:
486      dd_dump_launch_grid(state, &call->info.launch_grid, f);
487      break;
488   case CALL_RESOURCE_COPY_REGION:
489      dd_dump_resource_copy_region(state,
490                                   &call->info.resource_copy_region, f);
491      break;
492   case CALL_BLIT:
493      dd_dump_blit(state, &call->info.blit, f);
494      break;
495   case CALL_FLUSH_RESOURCE:
496      dd_dump_flush_resource(state, call->info.flush_resource, f);
497      break;
498   case CALL_CLEAR:
499      dd_dump_clear(state, &call->info.clear, f);
500      break;
501   case CALL_CLEAR_BUFFER:
502      dd_dump_clear_buffer(state, &call->info.clear_buffer, f);
503      break;
504   case CALL_CLEAR_RENDER_TARGET:
505      dd_dump_clear_render_target(state, f);
506      break;
507   case CALL_CLEAR_DEPTH_STENCIL:
508      dd_dump_clear_depth_stencil(state, f);
509      break;
510   case CALL_GENERATE_MIPMAP:
511      dd_dump_generate_mipmap(state, f);
512      break;
513   }
514}
515
516static void
517dd_write_report(struct dd_context *dctx, struct dd_call *call, unsigned flags,
518                bool dump_dmesg)
519{
520   FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen),
521                                dctx->draw_state.apitrace_call_number);
522
523   if (!f)
524      return;
525
526   dd_dump_call(f, &dctx->draw_state, call);
527   dd_dump_driver_state(dctx, f, flags);
528   if (dump_dmesg)
529      dd_dump_dmesg(f);
530   dd_close_file_stream(f);
531}
532
533static void
534dd_kill_process(void)
535{
536   sync();
537   fprintf(stderr, "dd: Aborting the process...\n");
538   fflush(stdout);
539   fflush(stderr);
540   exit(1);
541}
542
543static bool
544dd_flush_and_check_hang(struct dd_context *dctx,
545                        struct pipe_fence_handle **flush_fence,
546                        unsigned flush_flags)
547{
548   struct pipe_fence_handle *fence = NULL;
549   struct pipe_context *pipe = dctx->pipe;
550   struct pipe_screen *screen = pipe->screen;
551   uint64_t timeout_ms = dd_screen(dctx->base.screen)->timeout_ms;
552   bool idle;
553
554   assert(timeout_ms > 0);
555
556   pipe->flush(pipe, &fence, flush_flags);
557   if (flush_fence)
558      screen->fence_reference(screen, flush_fence, fence);
559   if (!fence)
560      return false;
561
562   idle = screen->fence_finish(screen, pipe, fence, timeout_ms * 1000000);
563   screen->fence_reference(screen, &fence, NULL);
564   if (!idle)
565      fprintf(stderr, "dd: GPU hang detected!\n");
566   return !idle;
567}
568
569static void
570dd_flush_and_handle_hang(struct dd_context *dctx,
571                         struct pipe_fence_handle **fence, unsigned flags,
572                         const char *cause)
573{
574   if (dd_flush_and_check_hang(dctx, fence, flags)) {
575      FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen),
576                                   dctx->draw_state.apitrace_call_number);
577
578      if (f) {
579         fprintf(f, "dd: %s.\n", cause);
580         dd_dump_driver_state(dctx, f,
581                              PIPE_DUMP_DEVICE_STATUS_REGISTERS |
582                              PIPE_DUMP_CURRENT_STATES |
583                              PIPE_DUMP_CURRENT_SHADERS |
584                              PIPE_DUMP_LAST_COMMAND_BUFFER);
585         dd_dump_dmesg(f);
586         dd_close_file_stream(f);
587      }
588
589      /* Terminate the process to prevent future hangs. */
590      dd_kill_process();
591   }
592}
593
594static void
595dd_unreference_copy_of_call(struct dd_call *dst)
596{
597   switch (dst->type) {
598   case CALL_DRAW_VBO:
599      pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output, NULL);
600      pipe_resource_reference(&dst->info.draw_vbo.indirect, NULL);
601      pipe_resource_reference(&dst->info.draw_vbo.indirect_params, NULL);
602      break;
603   case CALL_LAUNCH_GRID:
604      pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
605      break;
606   case CALL_RESOURCE_COPY_REGION:
607      pipe_resource_reference(&dst->info.resource_copy_region.dst, NULL);
608      pipe_resource_reference(&dst->info.resource_copy_region.src, NULL);
609      break;
610   case CALL_BLIT:
611      pipe_resource_reference(&dst->info.blit.dst.resource, NULL);
612      pipe_resource_reference(&dst->info.blit.src.resource, NULL);
613      break;
614   case CALL_FLUSH_RESOURCE:
615      pipe_resource_reference(&dst->info.flush_resource, NULL);
616      break;
617   case CALL_CLEAR:
618      break;
619   case CALL_CLEAR_BUFFER:
620      pipe_resource_reference(&dst->info.clear_buffer.res, NULL);
621      break;
622   case CALL_CLEAR_RENDER_TARGET:
623      break;
624   case CALL_CLEAR_DEPTH_STENCIL:
625      break;
626   case CALL_GENERATE_MIPMAP:
627      pipe_resource_reference(&dst->info.generate_mipmap.res, NULL);
628      break;
629   }
630}
631
632static void
633dd_copy_call(struct dd_call *dst, struct dd_call *src)
634{
635   dst->type = src->type;
636
637   switch (src->type) {
638   case CALL_DRAW_VBO:
639      pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output,
640                               src->info.draw_vbo.count_from_stream_output);
641      pipe_resource_reference(&dst->info.draw_vbo.indirect,
642                              src->info.draw_vbo.indirect);
643      pipe_resource_reference(&dst->info.draw_vbo.indirect_params,
644                              src->info.draw_vbo.indirect_params);
645      dst->info.draw_vbo = src->info.draw_vbo;
646      break;
647   case CALL_LAUNCH_GRID:
648      pipe_resource_reference(&dst->info.launch_grid.indirect,
649                              src->info.launch_grid.indirect);
650      dst->info.launch_grid = src->info.launch_grid;
651      break;
652   case CALL_RESOURCE_COPY_REGION:
653      pipe_resource_reference(&dst->info.resource_copy_region.dst,
654                              src->info.resource_copy_region.dst);
655      pipe_resource_reference(&dst->info.resource_copy_region.src,
656                              src->info.resource_copy_region.src);
657      dst->info.resource_copy_region = src->info.resource_copy_region;
658      break;
659   case CALL_BLIT:
660      pipe_resource_reference(&dst->info.blit.dst.resource,
661                              src->info.blit.dst.resource);
662      pipe_resource_reference(&dst->info.blit.src.resource,
663                              src->info.blit.src.resource);
664      dst->info.blit = src->info.blit;
665      break;
666   case CALL_FLUSH_RESOURCE:
667      pipe_resource_reference(&dst->info.flush_resource,
668                              src->info.flush_resource);
669      break;
670   case CALL_CLEAR:
671      dst->info.clear = src->info.clear;
672      break;
673   case CALL_CLEAR_BUFFER:
674      pipe_resource_reference(&dst->info.clear_buffer.res,
675                              src->info.clear_buffer.res);
676      dst->info.clear_buffer = src->info.clear_buffer;
677      break;
678   case CALL_CLEAR_RENDER_TARGET:
679      break;
680   case CALL_CLEAR_DEPTH_STENCIL:
681      break;
682   case CALL_GENERATE_MIPMAP:
683      pipe_resource_reference(&dst->info.generate_mipmap.res,
684                              src->info.generate_mipmap.res);
685      dst->info.generate_mipmap = src->info.generate_mipmap;
686      break;
687   }
688}
689
690static void
691dd_init_copy_of_draw_state(struct dd_draw_state_copy *state)
692{
693   unsigned i,j;
694
695   /* Just clear pointers to gallium objects. Don't clear the whole structure,
696    * because it would kill performance with its size of 130 KB.
697    */
698   memset(&state->base.index_buffer, 0,
699          sizeof(state->base.index_buffer));
700   memset(state->base.vertex_buffers, 0,
701          sizeof(state->base.vertex_buffers));
702   memset(state->base.so_targets, 0,
703          sizeof(state->base.so_targets));
704   memset(state->base.constant_buffers, 0,
705          sizeof(state->base.constant_buffers));
706   memset(state->base.sampler_views, 0,
707          sizeof(state->base.sampler_views));
708   memset(state->base.shader_images, 0,
709          sizeof(state->base.shader_images));
710   memset(state->base.shader_buffers, 0,
711          sizeof(state->base.shader_buffers));
712   memset(&state->base.framebuffer_state, 0,
713          sizeof(state->base.framebuffer_state));
714
715   memset(state->shaders, 0, sizeof(state->shaders));
716
717   state->base.render_cond.query = &state->render_cond;
718
719   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
720      state->base.shaders[i] = &state->shaders[i];
721      for (j = 0; j < PIPE_MAX_SAMPLERS; j++)
722         state->base.sampler_states[i][j] = &state->sampler_states[i][j];
723   }
724
725   state->base.velems = &state->velems;
726   state->base.rs = &state->rs;
727   state->base.dsa = &state->dsa;
728   state->base.blend = &state->blend;
729}
730
731static void
732dd_unreference_copy_of_draw_state(struct dd_draw_state_copy *state)
733{
734   struct dd_draw_state *dst = &state->base;
735   unsigned i,j;
736
737   util_set_index_buffer(&dst->index_buffer, NULL);
738
739   for (i = 0; i < ARRAY_SIZE(dst->vertex_buffers); i++)
740      pipe_resource_reference(&dst->vertex_buffers[i].buffer, NULL);
741   for (i = 0; i < ARRAY_SIZE(dst->so_targets); i++)
742      pipe_so_target_reference(&dst->so_targets[i], NULL);
743
744   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
745      if (dst->shaders[i])
746         tgsi_free_tokens(dst->shaders[i]->state.shader.tokens);
747
748      for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++)
749         pipe_resource_reference(&dst->constant_buffers[i][j].buffer, NULL);
750      for (j = 0; j < PIPE_MAX_SAMPLERS; j++)
751         pipe_sampler_view_reference(&dst->sampler_views[i][j], NULL);
752      for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++)
753         pipe_resource_reference(&dst->shader_images[i][j].resource, NULL);
754      for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++)
755         pipe_resource_reference(&dst->shader_buffers[i][j].buffer, NULL);
756   }
757
758   util_unreference_framebuffer_state(&dst->framebuffer_state);
759}
760
761static void
762dd_copy_draw_state(struct dd_draw_state *dst, struct dd_draw_state *src)
763{
764   unsigned i,j;
765
766   if (src->render_cond.query) {
767      *dst->render_cond.query = *src->render_cond.query;
768      dst->render_cond.condition = src->render_cond.condition;
769      dst->render_cond.mode = src->render_cond.mode;
770   } else {
771      dst->render_cond.query = NULL;
772   }
773
774   util_set_index_buffer(&dst->index_buffer, &src->index_buffer);
775
776   for (i = 0; i < ARRAY_SIZE(src->vertex_buffers); i++) {
777      pipe_resource_reference(&dst->vertex_buffers[i].buffer,
778                              src->vertex_buffers[i].buffer);
779      memcpy(&dst->vertex_buffers[i], &src->vertex_buffers[i],
780             sizeof(src->vertex_buffers[i]));
781   }
782
783   dst->num_so_targets = src->num_so_targets;
784   for (i = 0; i < ARRAY_SIZE(src->so_targets); i++)
785      pipe_so_target_reference(&dst->so_targets[i], src->so_targets[i]);
786   memcpy(dst->so_offsets, src->so_offsets, sizeof(src->so_offsets));
787
788   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
789      if (!src->shaders[i]) {
790         dst->shaders[i] = NULL;
791         continue;
792      }
793
794      if (src->shaders[i]) {
795         dst->shaders[i]->state.shader = src->shaders[i]->state.shader;
796         dst->shaders[i]->state.shader.tokens =
797            tgsi_dup_tokens(src->shaders[i]->state.shader.tokens);
798      } else {
799         dst->shaders[i] = NULL;
800      }
801
802      for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
803         pipe_resource_reference(&dst->constant_buffers[i][j].buffer,
804                                 src->constant_buffers[i][j].buffer);
805         memcpy(&dst->constant_buffers[i][j], &src->constant_buffers[i][j],
806                sizeof(src->constant_buffers[i][j]));
807      }
808
809      for (j = 0; j < PIPE_MAX_SAMPLERS; j++) {
810         pipe_sampler_view_reference(&dst->sampler_views[i][j],
811                                     src->sampler_views[i][j]);
812         if (src->sampler_states[i][j])
813            dst->sampler_states[i][j]->state.sampler =
814               src->sampler_states[i][j]->state.sampler;
815         else
816            dst->sampler_states[i][j] = NULL;
817      }
818
819      for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) {
820         pipe_resource_reference(&dst->shader_images[i][j].resource,
821                                 src->shader_images[i][j].resource);
822         memcpy(&dst->shader_images[i][j], &src->shader_images[i][j],
823                sizeof(src->shader_images[i][j]));
824      }
825
826      for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) {
827         pipe_resource_reference(&dst->shader_buffers[i][j].buffer,
828                                 src->shader_buffers[i][j].buffer);
829         memcpy(&dst->shader_buffers[i][j], &src->shader_buffers[i][j],
830                sizeof(src->shader_buffers[i][j]));
831      }
832   }
833
834   if (src->velems)
835      dst->velems->state.velems = src->velems->state.velems;
836   else
837      dst->velems = NULL;
838
839   if (src->rs)
840      dst->rs->state.rs = src->rs->state.rs;
841   else
842      dst->rs = NULL;
843
844   if (src->dsa)
845      dst->dsa->state.dsa = src->dsa->state.dsa;
846   else
847      dst->dsa = NULL;
848
849   if (src->blend)
850      dst->blend->state.blend = src->blend->state.blend;
851   else
852      dst->blend = NULL;
853
854   dst->blend_color = src->blend_color;
855   dst->stencil_ref = src->stencil_ref;
856   dst->sample_mask = src->sample_mask;
857   dst->min_samples = src->min_samples;
858   dst->clip_state = src->clip_state;
859   util_copy_framebuffer_state(&dst->framebuffer_state, &src->framebuffer_state);
860   memcpy(dst->scissors, src->scissors, sizeof(src->scissors));
861   memcpy(dst->viewports, src->viewports, sizeof(src->viewports));
862   memcpy(dst->tess_default_levels, src->tess_default_levels,
863          sizeof(src->tess_default_levels));
864   dst->apitrace_call_number = src->apitrace_call_number;
865}
866
867static void
868dd_free_record(struct dd_draw_record **record)
869{
870   struct dd_draw_record *next = (*record)->next;
871
872   dd_unreference_copy_of_call(&(*record)->call);
873   dd_unreference_copy_of_draw_state(&(*record)->draw_state);
874   FREE((*record)->driver_state_log);
875   FREE(*record);
876   *record = next;
877}
878
879static void
880dd_dump_record(struct dd_context *dctx, struct dd_draw_record *record,
881               uint32_t hw_sequence_no, int64_t now)
882{
883   FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen),
884                                record->draw_state.base.apitrace_call_number);
885   if (!f)
886      return;
887
888   fprintf(f, "Draw call sequence # = %u\n", record->sequence_no);
889   fprintf(f, "HW reached sequence # = %u\n", hw_sequence_no);
890   fprintf(f, "Elapsed time = %"PRIi64" ms\n\n",
891           (now - record->timestamp) / 1000);
892
893   dd_dump_call(f, &record->draw_state.base, &record->call);
894   fprintf(f, "%s\n", record->driver_state_log);
895
896   dctx->pipe->dump_debug_state(dctx->pipe, f,
897                                PIPE_DUMP_DEVICE_STATUS_REGISTERS);
898   dd_dump_dmesg(f);
899   fclose(f);
900}
901
902PIPE_THREAD_ROUTINE(dd_thread_pipelined_hang_detect, input)
903{
904   struct dd_context *dctx = (struct dd_context *)input;
905   struct dd_screen *dscreen = dd_screen(dctx->base.screen);
906
907   pipe_mutex_lock(dctx->mutex);
908
909   while (!dctx->kill_thread) {
910      struct dd_draw_record **record = &dctx->records;
911
912      /* Loop over all records. */
913      while (*record) {
914         int64_t now;
915
916         /* If the fence has been signalled, release the record and all older
917          * records.
918          */
919         if (*dctx->mapped_fence >= (*record)->sequence_no) {
920            while (*record)
921               dd_free_record(record);
922            break;
923         }
924
925         /* The fence hasn't been signalled. Check the timeout. */
926         now = os_time_get();
927         if (os_time_timeout((*record)->timestamp,
928                             (*record)->timestamp + dscreen->timeout_ms * 1000,
929                             now)) {
930            fprintf(stderr, "GPU hang detected.\n");
931
932            /* Get the oldest unsignalled draw call. */
933            while ((*record)->next &&
934                   *dctx->mapped_fence < (*record)->next->sequence_no)
935               record = &(*record)->next;
936
937            dd_dump_record(dctx, *record, *dctx->mapped_fence, now);
938            dd_kill_process();
939         }
940
941         record = &(*record)->next;
942      }
943
944      /* Unlock and sleep before starting all over again. */
945      pipe_mutex_unlock(dctx->mutex);
946      os_time_sleep(10000); /* 10 ms */
947      pipe_mutex_lock(dctx->mutex);
948   }
949
950   /* Thread termination. */
951   while (dctx->records)
952      dd_free_record(&dctx->records);
953
954   pipe_mutex_unlock(dctx->mutex);
955   return 0;
956}
957
958static char *
959dd_get_driver_shader_log(struct dd_context *dctx)
960{
961#if defined(PIPE_OS_LINUX)
962   FILE *f;
963   char *buf;
964   int written_bytes;
965
966   if (!dctx->max_log_buffer_size)
967      dctx->max_log_buffer_size = 16 * 1024;
968
969   /* Keep increasing the buffer size until there is enough space.
970    *
971    * open_memstream can resize automatically, but it's VERY SLOW.
972    * fmemopen is much faster.
973    */
974   while (1) {
975      buf = malloc(dctx->max_log_buffer_size);
976      buf[0] = 0;
977
978      f = fmemopen(buf, dctx->max_log_buffer_size, "a");
979      if (!f) {
980         free(buf);
981         return NULL;
982      }
983
984      dd_dump_driver_state(dctx, f, PIPE_DUMP_CURRENT_SHADERS);
985      written_bytes = ftell(f);
986      fclose(f);
987
988      /* Return if the backing buffer is large enough. */
989      if (written_bytes < dctx->max_log_buffer_size - 1)
990         break;
991
992      /* Try again. */
993      free(buf);
994      dctx->max_log_buffer_size *= 2;
995   }
996
997   return buf;
998#else
999   /* Return an empty string. */
1000   return (char*)calloc(1, 4);
1001#endif
1002}
1003
1004static void
1005dd_pipelined_process_draw(struct dd_context *dctx, struct dd_call *call)
1006{
1007   struct pipe_context *pipe = dctx->pipe;
1008   struct dd_draw_record *record;
1009   char *log;
1010
1011   /* Make a record of the draw call. */
1012   record = MALLOC_STRUCT(dd_draw_record);
1013   if (!record)
1014      return;
1015
1016   /* Create the log. */
1017   log = dd_get_driver_shader_log(dctx);
1018   if (!log) {
1019      FREE(record);
1020      return;
1021   }
1022
1023   /* Update the fence with the GPU.
1024    *
1025    * radeonsi/clear_buffer waits in the command processor until shaders are
1026    * idle before writing to memory. That's a necessary condition for isolating
1027    * draw calls.
1028    */
1029   dctx->sequence_no++;
1030   pipe->clear_buffer(pipe, dctx->fence, 0, 4, &dctx->sequence_no, 4);
1031
1032   /* Initialize the record. */
1033   record->timestamp = os_time_get();
1034   record->sequence_no = dctx->sequence_no;
1035   record->driver_state_log = log;
1036
1037   memset(&record->call, 0, sizeof(record->call));
1038   dd_copy_call(&record->call, call);
1039
1040   dd_init_copy_of_draw_state(&record->draw_state);
1041   dd_copy_draw_state(&record->draw_state.base, &dctx->draw_state);
1042
1043   /* Add the record to the list. */
1044   pipe_mutex_lock(dctx->mutex);
1045   record->next = dctx->records;
1046   dctx->records = record;
1047   pipe_mutex_unlock(dctx->mutex);
1048}
1049
1050static void
1051dd_context_flush(struct pipe_context *_pipe,
1052                 struct pipe_fence_handle **fence, unsigned flags)
1053{
1054   struct dd_context *dctx = dd_context(_pipe);
1055   struct pipe_context *pipe = dctx->pipe;
1056
1057   switch (dd_screen(dctx->base.screen)->mode) {
1058   case DD_DETECT_HANGS:
1059      dd_flush_and_handle_hang(dctx, fence, flags,
1060                               "GPU hang detected in pipe->flush()");
1061      break;
1062   case DD_DETECT_HANGS_PIPELINED: /* nothing to do here */
1063   case DD_DUMP_ALL_CALLS:
1064   case DD_DUMP_APITRACE_CALL:
1065      pipe->flush(pipe, fence, flags);
1066      break;
1067   default:
1068      assert(0);
1069   }
1070}
1071
1072static void
1073dd_before_draw(struct dd_context *dctx)
1074{
1075   struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1076
1077   if (dscreen->mode == DD_DETECT_HANGS &&
1078       !dscreen->no_flush &&
1079       dctx->num_draw_calls >= dscreen->skip_count)
1080      dd_flush_and_handle_hang(dctx, NULL, 0,
1081                               "GPU hang most likely caused by internal "
1082                               "driver commands");
1083}
1084
1085static void
1086dd_after_draw(struct dd_context *dctx, struct dd_call *call)
1087{
1088   struct dd_screen *dscreen = dd_screen(dctx->base.screen);
1089   struct pipe_context *pipe = dctx->pipe;
1090
1091   if (dctx->num_draw_calls >= dscreen->skip_count) {
1092      switch (dscreen->mode) {
1093      case DD_DETECT_HANGS:
1094         if (!dscreen->no_flush &&
1095            dd_flush_and_check_hang(dctx, NULL, 0)) {
1096            dd_write_report(dctx, call,
1097                         PIPE_DUMP_DEVICE_STATUS_REGISTERS |
1098                         PIPE_DUMP_CURRENT_STATES |
1099                         PIPE_DUMP_CURRENT_SHADERS |
1100                         PIPE_DUMP_LAST_COMMAND_BUFFER,
1101                         true);
1102
1103            /* Terminate the process to prevent future hangs. */
1104            dd_kill_process();
1105         }
1106         break;
1107      case DD_DETECT_HANGS_PIPELINED:
1108         dd_pipelined_process_draw(dctx, call);
1109         break;
1110      case DD_DUMP_ALL_CALLS:
1111         if (!dscreen->no_flush)
1112            pipe->flush(pipe, NULL, 0);
1113         dd_write_report(dctx, call,
1114                         PIPE_DUMP_CURRENT_STATES |
1115                         PIPE_DUMP_CURRENT_SHADERS |
1116                         PIPE_DUMP_LAST_COMMAND_BUFFER,
1117                         false);
1118         break;
1119      case DD_DUMP_APITRACE_CALL:
1120         if (dscreen->apitrace_dump_call ==
1121             dctx->draw_state.apitrace_call_number) {
1122            dd_write_report(dctx, call,
1123                            PIPE_DUMP_CURRENT_STATES |
1124                            PIPE_DUMP_CURRENT_SHADERS,
1125                            false);
1126            /* No need to continue. */
1127            exit(0);
1128         }
1129         break;
1130      default:
1131         assert(0);
1132      }
1133   }
1134
1135   ++dctx->num_draw_calls;
1136   if (dscreen->skip_count && dctx->num_draw_calls % 10000 == 0)
1137      fprintf(stderr, "Gallium debugger reached %u draw calls.\n",
1138              dctx->num_draw_calls);
1139}
1140
1141static void
1142dd_context_draw_vbo(struct pipe_context *_pipe,
1143                    const struct pipe_draw_info *info)
1144{
1145   struct dd_context *dctx = dd_context(_pipe);
1146   struct pipe_context *pipe = dctx->pipe;
1147   struct dd_call call;
1148
1149   call.type = CALL_DRAW_VBO;
1150   call.info.draw_vbo = *info;
1151
1152   dd_before_draw(dctx);
1153   pipe->draw_vbo(pipe, info);
1154   dd_after_draw(dctx, &call);
1155}
1156
1157static void
1158dd_context_launch_grid(struct pipe_context *_pipe,
1159                       const struct pipe_grid_info *info)
1160{
1161   struct dd_context *dctx = dd_context(_pipe);
1162   struct pipe_context *pipe = dctx->pipe;
1163   struct dd_call call;
1164
1165   call.type = CALL_LAUNCH_GRID;
1166   call.info.launch_grid = *info;
1167
1168   dd_before_draw(dctx);
1169   pipe->launch_grid(pipe, info);
1170   dd_after_draw(dctx, &call);
1171}
1172
1173static void
1174dd_context_resource_copy_region(struct pipe_context *_pipe,
1175                                struct pipe_resource *dst, unsigned dst_level,
1176                                unsigned dstx, unsigned dsty, unsigned dstz,
1177                                struct pipe_resource *src, unsigned src_level,
1178                                const struct pipe_box *src_box)
1179{
1180   struct dd_context *dctx = dd_context(_pipe);
1181   struct pipe_context *pipe = dctx->pipe;
1182   struct dd_call call;
1183
1184   call.type = CALL_RESOURCE_COPY_REGION;
1185   call.info.resource_copy_region.dst = dst;
1186   call.info.resource_copy_region.dst_level = dst_level;
1187   call.info.resource_copy_region.dstx = dstx;
1188   call.info.resource_copy_region.dsty = dsty;
1189   call.info.resource_copy_region.dstz = dstz;
1190   call.info.resource_copy_region.src = src;
1191   call.info.resource_copy_region.src_level = src_level;
1192   call.info.resource_copy_region.src_box = *src_box;
1193
1194   dd_before_draw(dctx);
1195   pipe->resource_copy_region(pipe,
1196                              dst, dst_level, dstx, dsty, dstz,
1197                              src, src_level, src_box);
1198   dd_after_draw(dctx, &call);
1199}
1200
1201static void
1202dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
1203{
1204   struct dd_context *dctx = dd_context(_pipe);
1205   struct pipe_context *pipe = dctx->pipe;
1206   struct dd_call call;
1207
1208   call.type = CALL_BLIT;
1209   call.info.blit = *info;
1210
1211   dd_before_draw(dctx);
1212   pipe->blit(pipe, info);
1213   dd_after_draw(dctx, &call);
1214}
1215
1216static boolean
1217dd_context_generate_mipmap(struct pipe_context *_pipe,
1218                           struct pipe_resource *res,
1219                           enum pipe_format format,
1220                           unsigned base_level,
1221                           unsigned last_level,
1222                           unsigned first_layer,
1223                           unsigned last_layer)
1224{
1225   struct dd_context *dctx = dd_context(_pipe);
1226   struct pipe_context *pipe = dctx->pipe;
1227   struct dd_call call;
1228   boolean result;
1229
1230   call.type = CALL_GENERATE_MIPMAP;
1231   call.info.generate_mipmap.res = res;
1232   call.info.generate_mipmap.format = format;
1233   call.info.generate_mipmap.base_level = base_level;
1234   call.info.generate_mipmap.last_level = last_level;
1235   call.info.generate_mipmap.first_layer = first_layer;
1236   call.info.generate_mipmap.last_layer = last_layer;
1237
1238   dd_before_draw(dctx);
1239   result = pipe->generate_mipmap(pipe, res, format, base_level, last_level,
1240                                  first_layer, last_layer);
1241   dd_after_draw(dctx, &call);
1242   return result;
1243}
1244
1245static void
1246dd_context_flush_resource(struct pipe_context *_pipe,
1247                          struct pipe_resource *resource)
1248{
1249   struct dd_context *dctx = dd_context(_pipe);
1250   struct pipe_context *pipe = dctx->pipe;
1251   struct dd_call call;
1252
1253   call.type = CALL_FLUSH_RESOURCE;
1254   call.info.flush_resource = resource;
1255
1256   dd_before_draw(dctx);
1257   pipe->flush_resource(pipe, resource);
1258   dd_after_draw(dctx, &call);
1259}
1260
1261static void
1262dd_context_clear(struct pipe_context *_pipe, unsigned buffers,
1263                 const union pipe_color_union *color, double depth,
1264                 unsigned stencil)
1265{
1266   struct dd_context *dctx = dd_context(_pipe);
1267   struct pipe_context *pipe = dctx->pipe;
1268   struct dd_call call;
1269
1270   call.type = CALL_CLEAR;
1271   call.info.clear.buffers = buffers;
1272   call.info.clear.color = *color;
1273   call.info.clear.depth = depth;
1274   call.info.clear.stencil = stencil;
1275
1276   dd_before_draw(dctx);
1277   pipe->clear(pipe, buffers, color, depth, stencil);
1278   dd_after_draw(dctx, &call);
1279}
1280
1281static void
1282dd_context_clear_render_target(struct pipe_context *_pipe,
1283                               struct pipe_surface *dst,
1284                               const union pipe_color_union *color,
1285                               unsigned dstx, unsigned dsty,
1286                               unsigned width, unsigned height,
1287                               bool render_condition_enabled)
1288{
1289   struct dd_context *dctx = dd_context(_pipe);
1290   struct pipe_context *pipe = dctx->pipe;
1291   struct dd_call call;
1292
1293   call.type = CALL_CLEAR_RENDER_TARGET;
1294
1295   dd_before_draw(dctx);
1296   pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height,
1297                             render_condition_enabled);
1298   dd_after_draw(dctx, &call);
1299}
1300
1301static void
1302dd_context_clear_depth_stencil(struct pipe_context *_pipe,
1303                               struct pipe_surface *dst, unsigned clear_flags,
1304                               double depth, unsigned stencil, unsigned dstx,
1305                               unsigned dsty, unsigned width, unsigned height,
1306                               bool render_condition_enabled)
1307{
1308   struct dd_context *dctx = dd_context(_pipe);
1309   struct pipe_context *pipe = dctx->pipe;
1310   struct dd_call call;
1311
1312   call.type = CALL_CLEAR_DEPTH_STENCIL;
1313
1314   dd_before_draw(dctx);
1315   pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
1316                             dstx, dsty, width, height,
1317                             render_condition_enabled);
1318   dd_after_draw(dctx, &call);
1319}
1320
1321static void
1322dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res,
1323                        unsigned offset, unsigned size,
1324                        const void *clear_value, int clear_value_size)
1325{
1326   struct dd_context *dctx = dd_context(_pipe);
1327   struct pipe_context *pipe = dctx->pipe;
1328   struct dd_call call;
1329
1330   call.type = CALL_CLEAR_BUFFER;
1331   call.info.clear_buffer.res = res;
1332   call.info.clear_buffer.offset = offset;
1333   call.info.clear_buffer.size = size;
1334   call.info.clear_buffer.clear_value = clear_value;
1335   call.info.clear_buffer.clear_value_size = clear_value_size;
1336
1337   dd_before_draw(dctx);
1338   pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size);
1339   dd_after_draw(dctx, &call);
1340}
1341
1342void
1343dd_init_draw_functions(struct dd_context *dctx)
1344{
1345   CTX_INIT(flush);
1346   CTX_INIT(draw_vbo);
1347   CTX_INIT(launch_grid);
1348   CTX_INIT(resource_copy_region);
1349   CTX_INIT(blit);
1350   CTX_INIT(clear);
1351   CTX_INIT(clear_render_target);
1352   CTX_INIT(clear_depth_stencil);
1353   CTX_INIT(clear_buffer);
1354   CTX_INIT(flush_resource);
1355   CTX_INIT(generate_mipmap);
1356}
1357