1 #include "util/u_math.h"
2 #include "lp_rast_priv.h"
3 #include "lp_state_fs.h"
4 
5 struct tile {
6    int coverage;
7    int overdraw;
8    const struct lp_rast_state *state;
9    char data[TILE_SIZE][TILE_SIZE];
10 };
11 
get_label(int i)12 static 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 
25 static 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 
cmd_name(unsigned cmd)47 static const char *cmd_name(unsigned cmd)
48 {
49    assert(Elements(cmd_names) > cmd);
50    return cmd_names[cmd];
51 }
52 
53 static const struct lp_fragment_shader_variant *
get_variant(const struct lp_rast_state * state,const struct cmd_block * block,int k)54 get_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 
76 static boolean
is_blend(const struct lp_rast_state * state,const struct cmd_block * block,int k)77 is_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 
91 static void
debug_bin(const struct cmd_bin * bin)92 debug_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 
plot(struct tile * tile,int x,int y,char val,boolean blend)114 static 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 
132 static int
debug_shade_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)133 debug_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 
157 static int
debug_clear_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)158 debug_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 
174 static int
debug_triangle(int tilex,int tiley,const union lp_rast_cmd_arg arg,struct tile * tile,char val)175 debug_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 
230 static void
do_debug_bin(struct tile * tile,const struct cmd_bin * bin,boolean print_cmds)231 do_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 
287 void
lp_debug_bin(const struct cmd_bin * bin)288 lp_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 */
316 static unsigned
lp_scene_bin_size(const struct lp_scene * scene,unsigned x,unsigned y)317 lp_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 
331 void
lp_debug_draw_bins_by_coverage(struct lp_scene * scene)332 lp_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 
393 void
lp_debug_draw_bins_by_cmd_length(struct lp_scene * scene)394 lp_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 
410 void
lp_debug_bins(struct lp_scene * scene)411 lp_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