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
get_label(int i)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[] =
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
cmd_name(unsigned cmd)72 static 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
79 static const struct lp_fragment_shader_variant *
get_variant(const struct lp_rast_state * state,const struct cmd_block * block,int k)80 get_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
104 static boolean
is_blend(const struct lp_rast_state * state,const struct cmd_block * block,int k)105 is_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
117 static boolean
is_linear(const struct lp_rast_state * state,const struct cmd_block * block,int k)118 is_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
136 static const char *
get_fs_kind(const struct lp_rast_state * state,const struct cmd_block * block,int k)137 get_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
152 static void
debug_bin(const struct cmd_bin * bin,int x,int y)153 debug_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].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
plot(struct tile * tile,int x,int y,char val,boolean blend)191 static 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 */
210 static int
debug_rectangle(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)211 debug_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
246 static int
debug_blit_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)247 debug_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
266 static int
debug_shade_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)267 debug_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
291 static int
debug_clear_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)292 debug_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
308 static int
debug_triangle(int tilex,int tiley,const union lp_rast_cmd_arg arg,struct tile * tile,char val)309 debug_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
364 static void
do_debug_bin(struct tile * tile,const struct cmd_bin * bin,int x,int y,boolean print_cmds)365 do_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].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
435 void
lp_debug_bin(const struct cmd_bin * bin,int i,int j)436 lp_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 */
464 static unsigned
lp_scene_bin_size(const struct lp_scene * scene,unsigned x,unsigned y)465 lp_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
479 void
lp_debug_draw_bins_by_coverage(struct lp_scene * scene)480 lp_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
543 void
lp_debug_draw_bins_by_cmd_length(struct lp_scene * scene)544 lp_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
560 void
lp_debug_bins(struct lp_scene * scene)561 lp_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