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