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