• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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