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
6struct tile {
7   int coverage;
8   int overdraw;
9   const struct lp_rast_state *state;
10   char data[TILE_SIZE][TILE_SIZE];
11};
12
13static 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
26static 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
72static 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
79static const struct lp_fragment_shader_variant *
80get_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
104static boolean
105is_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
117static boolean
118is_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
136static const char *
137get_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
152static void
153debug_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].set_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
191static 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 */
210static int
211debug_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
246static int
247debug_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
266static int
267debug_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
291static int
292debug_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
308static int
309debug_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
364static void
365do_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].set_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
435void
436lp_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 */
464static unsigned
465lp_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
479void
480lp_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
543void
544lp_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
560void
561lp_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