1#include "util/u_math.h" 2#include "lp_rast_priv.h" 3#include "lp_state_fs.h" 4 5struct tile { 6 int coverage; 7 int overdraw; 8 const struct lp_rast_state *state; 9 char data[TILE_SIZE][TILE_SIZE]; 10}; 11 12static 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 25static 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 47static const char *cmd_name(unsigned cmd) 48{ 49 assert(Elements(cmd_names) > cmd); 50 return cmd_names[cmd]; 51} 52 53static const struct lp_fragment_shader_variant * 54get_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 76static boolean 77is_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 91static void 92debug_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 114static 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 132static int 133debug_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 157static int 158debug_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 174static int 175debug_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 230static void 231do_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 287void 288lp_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 */ 316static unsigned 317lp_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 331void 332lp_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 393void 394lp_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 410void 411lp_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