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