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 6struct tile { 7 int coverage; 8 int overdraw; 9 const struct lp_rast_state *state; 10 char data[TILE_SIZE][TILE_SIZE]; 11}; 12 13static 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 26static const char *cmd_names[] = 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 "lp_rast_triangle_ms_1", 58 "lp_rast_triangle_ms_2", 59 "lp_rast_triangle_ms_3", 60 "lp_rast_triangle_ms_4", 61 "lp_rast_triangle_ms_5", 62 "lp_rast_triangle_ms_6", 63 "lp_rast_triangle_ms_7", 64 "lp_rast_triangle_ms_8", 65 "lp_rast_triangle_ms_3_4", 66 "lp_rast_triangle_ms_3_16", 67 "lp_rast_triangle_ms_4_16", 68 "rectangle", 69 "blit_tile", 70}; 71 72static const char *cmd_name(unsigned cmd) 73{ 74 STATIC_ASSERT(ARRAY_SIZE(cmd_names) == LP_RAST_OP_MAX); 75 assert(ARRAY_SIZE(cmd_names) > cmd); 76 return cmd_names[cmd]; 77} 78 79static const struct lp_fragment_shader_variant * 80get_variant( const struct lp_rast_state *state, 81 const struct cmd_block *block, 82 int k ) 83{ 84 if (!state) 85 return NULL; 86 87 if (block->cmd[k] == LP_RAST_OP_SHADE_TILE || 88 block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE || 89 block->cmd[k] == LP_RAST_OP_TRIANGLE_1 || 90 block->cmd[k] == LP_RAST_OP_TRIANGLE_2 || 91 block->cmd[k] == LP_RAST_OP_TRIANGLE_3 || 92 block->cmd[k] == LP_RAST_OP_TRIANGLE_4 || 93 block->cmd[k] == LP_RAST_OP_TRIANGLE_5 || 94 block->cmd[k] == LP_RAST_OP_TRIANGLE_6 || 95 block->cmd[k] == LP_RAST_OP_TRIANGLE_7 || 96 block->cmd[k] == LP_RAST_OP_RECTANGLE || 97 block->cmd[k] == LP_RAST_OP_BLIT) 98 return state->variant; 99 100 return NULL; 101} 102 103 104static boolean 105is_blend( const struct lp_rast_state *state, 106 const struct cmd_block *block, 107 int k ) 108{ 109 const struct lp_fragment_shader_variant *variant = get_variant(state, block, k); 110 111 if (variant) 112 return variant->key.blend.rt[0].blend_enable; 113 114 return FALSE; 115} 116 117static boolean 118is_linear( const struct lp_rast_state *state, 119 const struct cmd_block *block, 120 int k ) 121{ 122 if (block->cmd[k] == LP_RAST_OP_BLIT) 123 return state->variant->jit_linear_blit != NULL; 124 125 if (block->cmd[k] == LP_RAST_OP_SHADE_TILE || 126 block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE) 127 return state->variant->jit_linear != NULL; 128 129 if (block->cmd[k] == LP_RAST_OP_RECTANGLE) 130 return state->variant->jit_linear != NULL; 131 132 return FALSE; 133} 134 135 136static const char * 137get_fs_kind( const struct lp_rast_state *state, 138 const struct cmd_block *block, 139 int k ) 140{ 141 const struct lp_fragment_shader_variant *variant = get_variant(state, block, k); 142 143 if (variant) 144 return lp_debug_fs_kind(variant->shader->kind); 145 146 return ""; 147} 148 149 150 151 152static void 153debug_bin( const struct cmd_bin *bin, int x, int y ) 154{ 155 const struct lp_rast_state *state = NULL; 156 const struct cmd_block *head = bin->head; 157 const char *type; 158 struct lp_bin_info info; 159 int i, j = 0; 160 161 info = lp_characterize_bin(bin); 162 163 if (info.type & LP_RAST_FLAGS_BLIT) 164 type = "blit"; 165 else if (info.type & LP_RAST_FLAGS_TILE) 166 type = "tile"; 167 else if (info.type & LP_RAST_FLAGS_RECT) 168 type = "rect"; 169 else if (info.type & LP_RAST_FLAGS_TRI) 170 type = "tri"; 171 else 172 type = "unknown"; 173 174 175 debug_printf("bin %d,%d: type %s\n", x, y, type); 176 177 while (head) { 178 for (i = 0; i < head->count; i++, j++) { 179 if (head->cmd[i] == LP_RAST_OP_SET_STATE) 180 state = head->arg[i].set_state; 181 182 debug_printf("%d: %s %s\n", j, 183 cmd_name(head->cmd[i]), 184 is_blend(state, head, i) ? "blended" : ""); 185 } 186 head = head->next; 187 } 188} 189 190 191static void plot(struct tile *tile, 192 int x, int y, 193 char val, 194 boolean blend) 195{ 196 if (tile->data[x][y] == ' ') 197 tile->coverage++; 198 else 199 tile->overdraw++; 200 201 tile->data[x][y] = val; 202} 203 204 205 206/** 207 * Scan the tile in chunks and figure out which pixels to rasterize 208 * for this rectangle. 209 */ 210static int 211debug_rectangle(int x, int y, 212 const union lp_rast_cmd_arg arg, 213 struct tile *tile, 214 char val) 215{ 216 const struct lp_rast_rectangle *rect = arg.rectangle; 217 boolean blend = tile->state->variant->key.blend.rt[0].blend_enable; 218 unsigned i,j, count = 0; 219 220 /* Check for "disabled" rectangles generated in out-of-memory 221 * conditions. 222 */ 223 if (rect->inputs.disable) { 224 /* This command was partially binned and has been disabled */ 225 return 0; 226 } 227 228 for (i = 0; i < TILE_SIZE; i++) 229 { 230 for (j = 0; j < TILE_SIZE; j++) 231 { 232 if (rect->box.x0 <= x + i && 233 rect->box.x1 >= x + i && 234 rect->box.y0 <= y + j && 235 rect->box.y1 >= y + j) 236 { 237 plot(tile, i, j, val, blend); 238 count++; 239 } 240 } 241 } 242 return count; 243} 244 245 246static int 247debug_blit_tile(int x, int y, 248 const union lp_rast_cmd_arg arg, 249 struct tile *tile, 250 char val) 251{ 252 const struct lp_rast_shader_inputs *inputs = arg.shade_tile; 253 unsigned i,j; 254 255 if (inputs->disable) 256 return 0; 257 258 for (i = 0; i < TILE_SIZE; i++) 259 for (j = 0; j < TILE_SIZE; j++) 260 plot(tile, i, j, val, FALSE); 261 262 return TILE_SIZE * TILE_SIZE; 263} 264 265 266static int 267debug_shade_tile(int x, int y, 268 const union lp_rast_cmd_arg arg, 269 struct tile *tile, 270 char val) 271{ 272 const struct lp_rast_shader_inputs *inputs = arg.shade_tile; 273 boolean blend; 274 unsigned i,j; 275 276 if (!tile->state) 277 return 0; 278 279 blend = tile->state->variant->key.blend.rt[0].blend_enable; 280 281 if (inputs->disable) 282 return 0; 283 284 for (i = 0; i < TILE_SIZE; i++) 285 for (j = 0; j < TILE_SIZE; j++) 286 plot(tile, i, j, val, blend); 287 288 return TILE_SIZE * TILE_SIZE; 289} 290 291static int 292debug_clear_tile(int x, int y, 293 const union lp_rast_cmd_arg arg, 294 struct tile *tile, 295 char val) 296{ 297 unsigned i,j; 298 299 for (i = 0; i < TILE_SIZE; i++) 300 for (j = 0; j < TILE_SIZE; j++) 301 plot(tile, i, j, val, FALSE); 302 303 return TILE_SIZE * TILE_SIZE; 304 305} 306 307 308static int 309debug_triangle(int tilex, int tiley, 310 const union lp_rast_cmd_arg arg, 311 struct tile *tile, 312 char val) 313{ 314 const struct lp_rast_triangle *tri = arg.triangle.tri; 315 unsigned plane_mask = arg.triangle.plane_mask; 316 const struct lp_rast_plane *tri_plane = GET_PLANES(tri); 317 struct lp_rast_plane plane[8]; 318 int x, y; 319 int count = 0; 320 unsigned i, nr_planes = 0; 321 boolean blend = tile->state->variant->key.blend.rt[0].blend_enable; 322 323 if (tri->inputs.disable) { 324 /* This triangle was partially binned and has been disabled */ 325 return 0; 326 } 327 328 while (plane_mask) { 329 plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)]; 330 plane[nr_planes].c = (plane[nr_planes].c + 331 IMUL64(plane[nr_planes].dcdy, tiley) - 332 IMUL64(plane[nr_planes].dcdx, tilex)); 333 nr_planes++; 334 } 335 336 for(y = 0; y < TILE_SIZE; y++) 337 { 338 for(x = 0; x < TILE_SIZE; x++) 339 { 340 for (i = 0; i < nr_planes; i++) 341 if (plane[i].c <= 0) 342 goto out; 343 344 plot(tile, x, y, val, blend); 345 count++; 346 347 out: 348 for (i = 0; i < nr_planes; i++) 349 plane[i].c -= plane[i].dcdx; 350 } 351 352 for (i = 0; i < nr_planes; i++) { 353 plane[i].c += IMUL64(plane[i].dcdx, TILE_SIZE); 354 plane[i].c += plane[i].dcdy; 355 } 356 } 357 return count; 358} 359 360 361 362 363 364static void 365do_debug_bin( struct tile *tile, 366 const struct cmd_bin *bin, 367 int x, int y, 368 boolean print_cmds) 369{ 370 unsigned k, j = 0; 371 const struct cmd_block *block; 372 373 int tx = x * TILE_SIZE; 374 int ty = y * TILE_SIZE; 375 376 memset(tile->data, ' ', sizeof tile->data); 377 tile->coverage = 0; 378 tile->overdraw = 0; 379 tile->state = NULL; 380 381 for (block = bin->head; block; block = block->next) { 382 for (k = 0; k < block->count; k++, j++) { 383 boolean blend = is_blend(tile->state, block, k); 384 boolean linear = is_linear(tile->state, block, k); 385 const char *fskind = get_fs_kind(tile->state, block, k); 386 char val = get_label(j); 387 int count = 0; 388 389 if (print_cmds) 390 debug_printf("%c: %15s", val, cmd_name(block->cmd[k])); 391 392 if (block->cmd[k] == LP_RAST_OP_SET_STATE) 393 tile->state = block->arg[k].set_state; 394 395 if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR || 396 block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL) 397 count = debug_clear_tile(tx, ty, block->arg[k], tile, val); 398 399 if (block->cmd[k] == LP_RAST_OP_BLIT) 400 count = debug_blit_tile(tx, ty, block->arg[k], tile, val); 401 402 if (block->cmd[k] == LP_RAST_OP_SHADE_TILE || 403 block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE) 404 count = debug_shade_tile(tx, ty, block->arg[k], tile, val); 405 406 if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 || 407 block->cmd[k] == LP_RAST_OP_TRIANGLE_2 || 408 block->cmd[k] == LP_RAST_OP_TRIANGLE_3 || 409 block->cmd[k] == LP_RAST_OP_TRIANGLE_4 || 410 block->cmd[k] == LP_RAST_OP_TRIANGLE_5 || 411 block->cmd[k] == LP_RAST_OP_TRIANGLE_6 || 412 block->cmd[k] == LP_RAST_OP_TRIANGLE_7) 413 count = debug_triangle(tx, ty, block->arg[k], tile, val); 414 415 if (block->cmd[k] == LP_RAST_OP_RECTANGLE) 416 count = debug_rectangle(tx, ty, block->arg[k], tile, val); 417 418 if (print_cmds) { 419 debug_printf(" % 5d", count); 420 421 debug_printf(" %20s", fskind); 422 423 if (blend) 424 debug_printf(" blended"); 425 426 if (linear) 427 debug_printf(" linear"); 428 429 debug_printf("\n"); 430 } 431 } 432 } 433} 434 435void 436lp_debug_bin( const struct cmd_bin *bin, int i, int j) 437{ 438 struct tile tile; 439 int x,y; 440 441 if (bin->head) { 442 do_debug_bin(&tile, bin, i, j, TRUE); 443 444 debug_printf("------------------------------------------------------------------\n"); 445 for (y = 0; y < TILE_SIZE; y++) { 446 for (x = 0; x < TILE_SIZE; x++) { 447 debug_printf("%c", tile.data[y][x]); 448 } 449 debug_printf("|\n"); 450 } 451 debug_printf("------------------------------------------------------------------\n"); 452 453 debug_printf("each pixel drawn avg %f times\n", 454 ((float)tile.overdraw + tile.coverage)/(float)tile.coverage); 455 } 456} 457 458 459 460 461 462 463/** Return number of bytes used for a single bin */ 464static unsigned 465lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) 466{ 467 struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y); 468 const struct cmd_block *cmd; 469 unsigned size = 0; 470 for (cmd = bin->head; cmd; cmd = cmd->next) { 471 size += (cmd->count * 472 (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg))); 473 } 474 return size; 475} 476 477 478 479void 480lp_debug_draw_bins_by_coverage( struct lp_scene *scene ) 481{ 482 unsigned x, y; 483 unsigned total = 0; 484 unsigned possible = 0; 485 static uint64_t _total = 0; 486 static uint64_t _possible = 0; 487 488 for (x = 0; x < scene->tiles_x; x++) 489 debug_printf("-"); 490 debug_printf("\n"); 491 492 for (y = 0; y < scene->tiles_y; y++) { 493 for (x = 0; x < scene->tiles_x; x++) { 494 struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); 495 const char *bits = "0123456789"; 496 struct tile tile; 497 498 if (bin->head) { 499 //lp_debug_bin(bin, x, y); 500 501 do_debug_bin(&tile, bin, x, y, FALSE); 502 503 total += tile.coverage; 504 possible += 64*64; 505 506 if (tile.coverage == 64*64) 507 debug_printf("*"); 508 else if (tile.coverage) { 509 int bit = tile.coverage/(64.0*64.0)*10; 510 debug_printf("%c", bits[MIN2(bit,10)]); 511 } 512 else 513 debug_printf("?"); 514 } 515 else { 516 debug_printf(" "); 517 } 518 } 519 debug_printf("|\n"); 520 } 521 522 for (x = 0; x < scene->tiles_x; x++) 523 debug_printf("-"); 524 debug_printf("\n"); 525 526 debug_printf("this tile total: %u possible %u: percentage: %f\n", 527 total, 528 possible, 529 total * 100.0 / (float)possible); 530 531 _total += total; 532 _possible += possible; 533 534 535 debug_printf("overall total: %" PRIu64 536 " possible %" PRIu64 ": percentage: %f\n", 537 _total, 538 _possible, 539 (double) _total * 100.0 / (double)_possible); 540} 541 542 543void 544lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene ) 545{ 546 unsigned x, y; 547 548 for (y = 0; y < scene->tiles_y; y++) { 549 for (x = 0; x < scene->tiles_x; x++) { 550 const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW"; 551 unsigned sz = lp_scene_bin_size(scene, x, y); 552 unsigned sz2 = util_logbase2(sz); 553 debug_printf("%c", bits[MIN2(sz2,32)]); 554 } 555 debug_printf("\n"); 556 } 557} 558 559 560void 561lp_debug_bins( struct lp_scene *scene ) 562{ 563 unsigned x, y; 564 565 for (y = 0; y < scene->tiles_y; y++) { 566 for (x = 0; x < scene->tiles_x; x++) { 567 struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); 568 if (bin->head) { 569 debug_bin(bin, x, y); 570 } 571 } 572 } 573} 574