Home | History | Annotate | Download | only in ddebug
      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 
     42 static FILE *
     43 dd_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 
     64 static void
     65 dd_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 
     80 static void
     81 dd_close_file_stream(FILE *f)
     82 {
     83    fclose(f);
     84 }
     85 
     86 static unsigned
     87 dd_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 
    133 static void
    134 print_named_value(FILE *f, const char *name, int value)
    135 {
    136    fprintf(f, COLOR_STATE "%s" COLOR_RESET " = %i\n", name, value);
    137 }
    138 
    139 static void
    140 print_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 
    145 static void
    146 util_dump_uint(FILE *f, unsigned i)
    147 {
    148    fprintf(f, "%u", i);
    149 }
    150 
    151 static void
    152 util_dump_hex(FILE *f, unsigned i)
    153 {
    154    fprintf(f, "0x%x", i);
    155 }
    156 
    157 static void
    158 util_dump_double(FILE *f, double d)
    159 {
    160    fprintf(f, "%f", d);
    161 }
    162 
    163 static void
    164 util_dump_format(FILE *f, enum pipe_format format)
    165 {
    166    fprintf(f, "%s", util_format_name(format));
    167 }
    168 
    169 static void
    170 util_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 
    177 static void
    178 util_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 
    187 static void
    188 dd_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 
    199 static void
    200 dd_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 
    362 static void
    363 dd_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 
    369 static void
    370 dd_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 
    385 static void
    386 dd_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 
    409 static void
    410 dd_dump_generate_mipmap(struct dd_draw_state *dstate, FILE *f)
    411 {
    412    fprintf(f, "%s:\n", __func__+8);
    413    /* TODO */
    414 }
    415 
    416 static void
    417 dd_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 
    424 static void
    425 dd_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 
    434 static void
    435 dd_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 
    453 static void
    454 dd_dump_clear_render_target(struct dd_draw_state *dstate, FILE *f)
    455 {
    456    fprintf(f, "%s:\n", __func__+8);
    457    /* TODO */
    458 }
    459 
    460 static void
    461 dd_dump_clear_depth_stencil(struct dd_draw_state *dstate, FILE *f)
    462 {
    463    fprintf(f, "%s:\n", __func__+8);
    464    /* TODO */
    465 }
    466 
    467 static void
    468 dd_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 
    478 static void
    479 dd_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 
    516 static void
    517 dd_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 
    533 static void
    534 dd_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 
    543 static bool
    544 dd_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 
    569 static void
    570 dd_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 
    594 static void
    595 dd_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 
    632 static void
    633 dd_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 
    690 static void
    691 dd_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 
    731 static void
    732 dd_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 
    761 static void
    762 dd_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 
    867 static void
    868 dd_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 
    879 static void
    880 dd_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 
    902 PIPE_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 
    958 static char *
    959 dd_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 
   1004 static void
   1005 dd_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 
   1050 static void
   1051 dd_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 
   1072 static void
   1073 dd_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 
   1085 static void
   1086 dd_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 
   1141 static void
   1142 dd_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 
   1157 static void
   1158 dd_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 
   1173 static void
   1174 dd_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 
   1201 static void
   1202 dd_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 
   1216 static boolean
   1217 dd_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 
   1245 static void
   1246 dd_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 
   1261 static void
   1262 dd_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 
   1281 static void
   1282 dd_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 
   1301 static void
   1302 dd_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 
   1321 static void
   1322 dd_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 
   1342 void
   1343 dd_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