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