Home | History | Annotate | Download | only in llvmpipe
      1 #include "util/u_math.h"
      2 #include "lp_rast_priv.h"
      3 #include "lp_state_fs.h"
      4 
      5 struct tile {
      6    int coverage;
      7    int overdraw;
      8    const struct lp_rast_state *state;
      9    char data[TILE_SIZE][TILE_SIZE];
     10 };
     11 
     12 static char get_label( int i )
     13 {
     14    static const char *cmd_labels = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     15    unsigned max_label = (2*26+10);
     16 
     17    if (i < max_label)
     18       return cmd_labels[i];
     19    else
     20       return '?';
     21 }
     22 
     23 
     24 
     25 static const char *cmd_names[LP_RAST_OP_MAX] =
     26 {
     27    "clear_color",
     28    "clear_zstencil",
     29    "triangle_1",
     30    "triangle_2",
     31    "triangle_3",
     32    "triangle_4",
     33    "triangle_5",
     34    "triangle_6",
     35    "triangle_7",
     36    "triangle_8",
     37    "triangle_3_4",
     38    "triangle_3_16",
     39    "triangle_4_16",
     40    "shade_tile",
     41    "shade_tile_opaque",
     42    "begin_query",
     43    "end_query",
     44    "set_state",
     45 };
     46 
     47 static const char *cmd_name(unsigned cmd)
     48 {
     49    assert(Elements(cmd_names) > cmd);
     50    return cmd_names[cmd];
     51 }
     52 
     53 static const struct lp_fragment_shader_variant *
     54 get_variant( const struct lp_rast_state *state,
     55              const struct cmd_block *block,
     56              int k )
     57 {
     58    if (!state)
     59       return NULL;
     60 
     61    if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
     62        block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE ||
     63        block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
     64        block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
     65        block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
     66        block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
     67        block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
     68        block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
     69        block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
     70       return state->variant;
     71 
     72    return NULL;
     73 }
     74 
     75 
     76 static boolean
     77 is_blend( const struct lp_rast_state *state,
     78           const struct cmd_block *block,
     79           int k )
     80 {
     81    const struct lp_fragment_shader_variant *variant = get_variant(state, block, k);
     82 
     83    if (variant)
     84       return  variant->key.blend.rt[0].blend_enable;
     85 
     86    return FALSE;
     87 }
     88 
     89 
     90 
     91 static void
     92 debug_bin( const struct cmd_bin *bin )
     93 {
     94    const struct lp_rast_state *state = NULL;
     95    const struct cmd_block *head = bin->head;
     96    int i, j = 0;
     97 
     98    debug_printf("bin %d,%d:\n", bin->x, bin->y);
     99 
    100    while (head) {
    101       for (i = 0; i < head->count; i++, j++) {
    102          if (head->cmd[i] == LP_RAST_OP_SET_STATE)
    103             state = head->arg[i].state;
    104 
    105          debug_printf("%d: %s %s\n", j,
    106                       cmd_name(head->cmd[i]),
    107                       is_blend(state, head, i) ? "blended" : "");
    108       }
    109       head = head->next;
    110    }
    111 }
    112 
    113 
    114 static void plot(struct tile *tile,
    115                  int x, int y,
    116                  char val,
    117                  boolean blend)
    118 {
    119    if (tile->data[x][y] == ' ')
    120       tile->coverage++;
    121    else
    122       tile->overdraw++;
    123 
    124    tile->data[x][y] = val;
    125 }
    126 
    127 
    128 
    129 
    130 
    131 
    132 static int
    133 debug_shade_tile(int x, int y,
    134                  const union lp_rast_cmd_arg arg,
    135                  struct tile *tile,
    136                  char val)
    137 {
    138    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
    139    boolean blend;
    140    unsigned i,j;
    141 
    142    if (!tile->state)
    143       return 0;
    144 
    145    blend = tile->state->variant->key.blend.rt[0].blend_enable;
    146 
    147    if (inputs->disable)
    148       return 0;
    149 
    150    for (i = 0; i < TILE_SIZE; i++)
    151       for (j = 0; j < TILE_SIZE; j++)
    152          plot(tile, i, j, val, blend);
    153 
    154    return TILE_SIZE * TILE_SIZE;
    155 }
    156 
    157 static int
    158 debug_clear_tile(int x, int y,
    159                  const union lp_rast_cmd_arg arg,
    160                  struct tile *tile,
    161                  char val)
    162 {
    163    unsigned i,j;
    164 
    165    for (i = 0; i < TILE_SIZE; i++)
    166       for (j = 0; j < TILE_SIZE; j++)
    167          plot(tile, i, j, val, FALSE);
    168 
    169    return TILE_SIZE * TILE_SIZE;
    170 
    171 }
    172 
    173 
    174 static int
    175 debug_triangle(int tilex, int tiley,
    176                const union lp_rast_cmd_arg arg,
    177                struct tile *tile,
    178                char val)
    179 {
    180    const struct lp_rast_triangle *tri = arg.triangle.tri;
    181    unsigned plane_mask = arg.triangle.plane_mask;
    182    const struct lp_rast_plane *tri_plane = GET_PLANES(tri);
    183    struct lp_rast_plane plane[8];
    184    int x, y;
    185    int count = 0;
    186    unsigned i, nr_planes = 0;
    187    boolean blend = tile->state->variant->key.blend.rt[0].blend_enable;
    188 
    189    if (tri->inputs.disable) {
    190       /* This triangle was partially binned and has been disabled */
    191       return 0;
    192    }
    193 
    194    while (plane_mask) {
    195       plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)];
    196       plane[nr_planes].c = (plane[nr_planes].c +
    197                             plane[nr_planes].dcdy * tiley -
    198                             plane[nr_planes].dcdx * tilex);
    199       nr_planes++;
    200    }
    201 
    202    for(y = 0; y < TILE_SIZE; y++)
    203    {
    204       for(x = 0; x < TILE_SIZE; x++)
    205       {
    206          for (i = 0; i < nr_planes; i++)
    207             if (plane[i].c <= 0)
    208                goto out;
    209 
    210          plot(tile, x, y, val, blend);
    211          count++;
    212 
    213       out:
    214          for (i = 0; i < nr_planes; i++)
    215             plane[i].c -= plane[i].dcdx;
    216       }
    217 
    218       for (i = 0; i < nr_planes; i++) {
    219          plane[i].c += plane[i].dcdx * TILE_SIZE;
    220          plane[i].c += plane[i].dcdy;
    221       }
    222    }
    223    return count;
    224 }
    225 
    226 
    227 
    228 
    229 
    230 static void
    231 do_debug_bin( struct tile *tile,
    232               const struct cmd_bin *bin,
    233               boolean print_cmds)
    234 {
    235    unsigned k, j = 0;
    236    const struct cmd_block *block;
    237 
    238    int tx = bin->x * TILE_SIZE;
    239    int ty = bin->y * TILE_SIZE;
    240 
    241    memset(tile->data, ' ', sizeof tile->data);
    242    tile->coverage = 0;
    243    tile->overdraw = 0;
    244    tile->state = NULL;
    245 
    246    for (block = bin->head; block; block = block->next) {
    247       for (k = 0; k < block->count; k++, j++) {
    248          boolean blend = is_blend(tile->state, block, k);
    249          char val = get_label(j);
    250          int count = 0;
    251 
    252          if (print_cmds)
    253             debug_printf("%c: %15s", val, cmd_name(block->cmd[k]));
    254 
    255          if (block->cmd[k] == LP_RAST_OP_SET_STATE)
    256             tile->state = block->arg[k].state;
    257 
    258          if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR ||
    259              block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL)
    260             count = debug_clear_tile(tx, ty, block->arg[k], tile, val);
    261 
    262          if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
    263              block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)
    264             count = debug_shade_tile(tx, ty, block->arg[k], tile, val);
    265 
    266          if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
    267              block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
    268              block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
    269              block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
    270              block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
    271              block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
    272              block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
    273             count = debug_triangle(tx, ty, block->arg[k], tile, val);
    274 
    275          if (print_cmds) {
    276             debug_printf(" % 5d", count);
    277 
    278             if (blend)
    279                debug_printf(" blended");
    280 
    281             debug_printf("\n");
    282          }
    283       }
    284    }
    285 }
    286 
    287 void
    288 lp_debug_bin( const struct cmd_bin *bin)
    289 {
    290    struct tile tile;
    291    int x,y;
    292 
    293    if (bin->head) {
    294       do_debug_bin(&tile, bin, TRUE);
    295 
    296       debug_printf("------------------------------------------------------------------\n");
    297       for (y = 0; y < TILE_SIZE; y++) {
    298          for (x = 0; x < TILE_SIZE; x++) {
    299             debug_printf("%c", tile.data[y][x]);
    300          }
    301          debug_printf("|\n");
    302       }
    303       debug_printf("------------------------------------------------------------------\n");
    304 
    305       debug_printf("each pixel drawn avg %f times\n",
    306                    ((float)tile.overdraw + tile.coverage)/(float)tile.coverage);
    307    }
    308 }
    309 
    310 
    311 
    312 
    313 
    314 
    315 /** Return number of bytes used for a single bin */
    316 static unsigned
    317 lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )
    318 {
    319    struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);
    320    const struct cmd_block *cmd;
    321    unsigned size = 0;
    322    for (cmd = bin->head; cmd; cmd = cmd->next) {
    323       size += (cmd->count *
    324                (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));
    325    }
    326    return size;
    327 }
    328 
    329 
    330 
    331 void
    332 lp_debug_draw_bins_by_coverage( struct lp_scene *scene )
    333 {
    334    unsigned x, y;
    335    unsigned total = 0;
    336    unsigned possible = 0;
    337    static unsigned long long _total;
    338    static unsigned long long _possible;
    339 
    340    for (x = 0; x < scene->tiles_x; x++)
    341       debug_printf("-");
    342    debug_printf("\n");
    343 
    344    for (y = 0; y < scene->tiles_y; y++) {
    345       for (x = 0; x < scene->tiles_x; x++) {
    346          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
    347          const char *bits = "0123456789";
    348          struct tile tile;
    349 
    350          if (bin->head) {
    351             //lp_debug_bin(bin);
    352 
    353             do_debug_bin(&tile, bin, FALSE);
    354 
    355             total += tile.coverage;
    356             possible += 64*64;
    357 
    358             if (tile.coverage == 64*64)
    359                debug_printf("*");
    360             else if (tile.coverage) {
    361                int bit = tile.coverage/(64.0*64.0)*10;
    362                debug_printf("%c", bits[MIN2(bit,10)]);
    363             }
    364             else
    365                debug_printf("?");
    366          }
    367          else {
    368             debug_printf(" ");
    369          }
    370       }
    371       debug_printf("|\n");
    372    }
    373 
    374    for (x = 0; x < scene->tiles_x; x++)
    375       debug_printf("-");
    376    debug_printf("\n");
    377 
    378    debug_printf("this tile total: %u possible %u: percentage: %f\n",
    379                 total,
    380                 possible,
    381                 total * 100.0 / (float)possible);
    382 
    383    _total += total;
    384    _possible += possible;
    385 
    386    debug_printf("overall   total: %llu possible %llu: percentage: %f\n",
    387                 _total,
    388                 _possible,
    389                 _total * 100.0 / (double)_possible);
    390 }
    391 
    392 
    393 void
    394 lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene )
    395 {
    396    unsigned x, y;
    397 
    398    for (y = 0; y < scene->tiles_y; y++) {
    399       for (x = 0; x < scene->tiles_x; x++) {
    400          const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";
    401          unsigned sz = lp_scene_bin_size(scene, x, y);
    402          unsigned sz2 = util_logbase2(sz);
    403          debug_printf("%c", bits[MIN2(sz2,32)]);
    404       }
    405       debug_printf("\n");
    406    }
    407 }
    408 
    409 
    410 void
    411 lp_debug_bins( struct lp_scene *scene )
    412 {
    413    unsigned x, y;
    414 
    415    for (y = 0; y < scene->tiles_y; y++) {
    416       for (x = 0; x < scene->tiles_x; x++) {
    417          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
    418          if (bin->head) {
    419             debug_bin(bin);
    420          }
    421       }
    422    }
    423 }
    424