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