• 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[LP_RAST_OP_MAX] =
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 };
58 
cmd_name(unsigned cmd)59 static const char *cmd_name(unsigned cmd)
60 {
61    assert(ARRAY_SIZE(cmd_names) > cmd);
62    return cmd_names[cmd];
63 }
64 
65 static const struct lp_fragment_shader_variant *
get_variant(const struct lp_rast_state * state,const struct cmd_block * block,int k)66 get_variant( const struct lp_rast_state *state,
67              const struct cmd_block *block,
68              int k )
69 {
70    if (!state)
71       return NULL;
72 
73    if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
74        block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE ||
75        block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
76        block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
77        block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
78        block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
79        block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
80        block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
81        block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
82       return state->variant;
83 
84    return NULL;
85 }
86 
87 
88 static boolean
is_blend(const struct lp_rast_state * state,const struct cmd_block * block,int k)89 is_blend( const struct lp_rast_state *state,
90           const struct cmd_block *block,
91           int k )
92 {
93    const struct lp_fragment_shader_variant *variant = get_variant(state, block, k);
94 
95    if (variant)
96       return  variant->key.blend.rt[0].blend_enable;
97 
98    return FALSE;
99 }
100 
101 
102 
103 static void
debug_bin(const struct cmd_bin * bin,int x,int y)104 debug_bin( const struct cmd_bin *bin, int x, int y )
105 {
106    const struct lp_rast_state *state = NULL;
107    const struct cmd_block *head = bin->head;
108    int i, j = 0;
109 
110    debug_printf("bin %d,%d:\n", x, y);
111 
112    while (head) {
113       for (i = 0; i < head->count; i++, j++) {
114          if (head->cmd[i] == LP_RAST_OP_SET_STATE)
115             state = head->arg[i].state;
116 
117          debug_printf("%d: %s %s\n", j,
118                       cmd_name(head->cmd[i]),
119                       is_blend(state, head, i) ? "blended" : "");
120       }
121       head = head->next;
122    }
123 }
124 
125 
plot(struct tile * tile,int x,int y,char val,boolean blend)126 static void plot(struct tile *tile,
127                  int x, int y,
128                  char val,
129                  boolean blend)
130 {
131    if (tile->data[x][y] == ' ')
132       tile->coverage++;
133    else
134       tile->overdraw++;
135 
136    tile->data[x][y] = val;
137 }
138 
139 
140 
141 
142 
143 
144 static int
debug_shade_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)145 debug_shade_tile(int x, int y,
146                  const union lp_rast_cmd_arg arg,
147                  struct tile *tile,
148                  char val)
149 {
150    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
151    boolean blend;
152    unsigned i,j;
153 
154    if (!tile->state)
155       return 0;
156 
157    blend = tile->state->variant->key.blend.rt[0].blend_enable;
158 
159    if (inputs->disable)
160       return 0;
161 
162    for (i = 0; i < TILE_SIZE; i++)
163       for (j = 0; j < TILE_SIZE; j++)
164          plot(tile, i, j, val, blend);
165 
166    return TILE_SIZE * TILE_SIZE;
167 }
168 
169 static int
debug_clear_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)170 debug_clear_tile(int x, int y,
171                  const union lp_rast_cmd_arg arg,
172                  struct tile *tile,
173                  char val)
174 {
175    unsigned i,j;
176 
177    for (i = 0; i < TILE_SIZE; i++)
178       for (j = 0; j < TILE_SIZE; j++)
179          plot(tile, i, j, val, FALSE);
180 
181    return TILE_SIZE * TILE_SIZE;
182 
183 }
184 
185 
186 static int
debug_triangle(int tilex,int tiley,const union lp_rast_cmd_arg arg,struct tile * tile,char val)187 debug_triangle(int tilex, int tiley,
188                const union lp_rast_cmd_arg arg,
189                struct tile *tile,
190                char val)
191 {
192    const struct lp_rast_triangle *tri = arg.triangle.tri;
193    unsigned plane_mask = arg.triangle.plane_mask;
194    const struct lp_rast_plane *tri_plane = GET_PLANES(tri);
195    struct lp_rast_plane plane[8];
196    int x, y;
197    int count = 0;
198    unsigned i, nr_planes = 0;
199    boolean blend = tile->state->variant->key.blend.rt[0].blend_enable;
200 
201    if (tri->inputs.disable) {
202       /* This triangle was partially binned and has been disabled */
203       return 0;
204    }
205 
206    while (plane_mask) {
207       plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)];
208       plane[nr_planes].c = (plane[nr_planes].c +
209                             IMUL64(plane[nr_planes].dcdy, tiley) -
210                             IMUL64(plane[nr_planes].dcdx, tilex));
211       nr_planes++;
212    }
213 
214    for(y = 0; y < TILE_SIZE; y++)
215    {
216       for(x = 0; x < TILE_SIZE; x++)
217       {
218          for (i = 0; i < nr_planes; i++)
219             if (plane[i].c <= 0)
220                goto out;
221 
222          plot(tile, x, y, val, blend);
223          count++;
224 
225       out:
226          for (i = 0; i < nr_planes; i++)
227             plane[i].c -= plane[i].dcdx;
228       }
229 
230       for (i = 0; i < nr_planes; i++) {
231          plane[i].c += IMUL64(plane[i].dcdx, TILE_SIZE);
232          plane[i].c += plane[i].dcdy;
233       }
234    }
235    return count;
236 }
237 
238 
239 
240 
241 
242 static void
do_debug_bin(struct tile * tile,const struct cmd_bin * bin,int x,int y,boolean print_cmds)243 do_debug_bin( struct tile *tile,
244               const struct cmd_bin *bin,
245               int x, int y,
246               boolean print_cmds)
247 {
248    unsigned k, j = 0;
249    const struct cmd_block *block;
250 
251    int tx = x * TILE_SIZE;
252    int ty = y * TILE_SIZE;
253 
254    memset(tile->data, ' ', sizeof tile->data);
255    tile->coverage = 0;
256    tile->overdraw = 0;
257    tile->state = NULL;
258 
259    for (block = bin->head; block; block = block->next) {
260       for (k = 0; k < block->count; k++, j++) {
261          boolean blend = is_blend(tile->state, block, k);
262          char val = get_label(j);
263          int count = 0;
264 
265          if (print_cmds)
266             debug_printf("%c: %15s", val, cmd_name(block->cmd[k]));
267 
268          if (block->cmd[k] == LP_RAST_OP_SET_STATE)
269             tile->state = block->arg[k].state;
270 
271          if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR ||
272              block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL)
273             count = debug_clear_tile(tx, ty, block->arg[k], tile, val);
274 
275          if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
276              block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)
277             count = debug_shade_tile(tx, ty, block->arg[k], tile, val);
278 
279          if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
280              block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
281              block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
282              block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
283              block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
284              block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
285              block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
286             count = debug_triangle(tx, ty, block->arg[k], tile, val);
287 
288          if (print_cmds) {
289             debug_printf(" % 5d", count);
290 
291             if (blend)
292                debug_printf(" blended");
293 
294             debug_printf("\n");
295          }
296       }
297    }
298 }
299 
300 void
lp_debug_bin(const struct cmd_bin * bin,int i,int j)301 lp_debug_bin( const struct cmd_bin *bin, int i, int j)
302 {
303    struct tile tile;
304    int x,y;
305 
306    if (bin->head) {
307       do_debug_bin(&tile, bin, i, j, TRUE);
308 
309       debug_printf("------------------------------------------------------------------\n");
310       for (y = 0; y < TILE_SIZE; y++) {
311          for (x = 0; x < TILE_SIZE; x++) {
312             debug_printf("%c", tile.data[y][x]);
313          }
314          debug_printf("|\n");
315       }
316       debug_printf("------------------------------------------------------------------\n");
317 
318       debug_printf("each pixel drawn avg %f times\n",
319                    ((float)tile.overdraw + tile.coverage)/(float)tile.coverage);
320    }
321 }
322 
323 
324 
325 
326 
327 
328 /** Return number of bytes used for a single bin */
329 static unsigned
lp_scene_bin_size(const struct lp_scene * scene,unsigned x,unsigned y)330 lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )
331 {
332    struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);
333    const struct cmd_block *cmd;
334    unsigned size = 0;
335    for (cmd = bin->head; cmd; cmd = cmd->next) {
336       size += (cmd->count *
337                (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));
338    }
339    return size;
340 }
341 
342 
343 
344 void
lp_debug_draw_bins_by_coverage(struct lp_scene * scene)345 lp_debug_draw_bins_by_coverage( struct lp_scene *scene )
346 {
347    unsigned x, y;
348    unsigned total = 0;
349    unsigned possible = 0;
350    static uint64_t _total = 0;
351    static uint64_t _possible = 0;
352 
353    for (x = 0; x < scene->tiles_x; x++)
354       debug_printf("-");
355    debug_printf("\n");
356 
357    for (y = 0; y < scene->tiles_y; y++) {
358       for (x = 0; x < scene->tiles_x; x++) {
359          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
360          const char *bits = "0123456789";
361          struct tile tile;
362 
363          if (bin->head) {
364             //lp_debug_bin(bin, x, y);
365 
366             do_debug_bin(&tile, bin, x, y, FALSE);
367 
368             total += tile.coverage;
369             possible += 64*64;
370 
371             if (tile.coverage == 64*64)
372                debug_printf("*");
373             else if (tile.coverage) {
374                int bit = tile.coverage/(64.0*64.0)*10;
375                debug_printf("%c", bits[MIN2(bit,10)]);
376             }
377             else
378                debug_printf("?");
379          }
380          else {
381             debug_printf(" ");
382          }
383       }
384       debug_printf("|\n");
385    }
386 
387    for (x = 0; x < scene->tiles_x; x++)
388       debug_printf("-");
389    debug_printf("\n");
390 
391    debug_printf("this tile total: %u possible %u: percentage: %f\n",
392                 total,
393                 possible,
394                 total * 100.0 / (float)possible);
395 
396    _total += total;
397    _possible += possible;
398 
399 
400    debug_printf("overall   total: %" PRIu64
401                 " possible %" PRIu64 ": percentage: %f\n",
402                 _total,
403                 _possible,
404                 (double) _total * 100.0 / (double)_possible);
405 }
406 
407 
408 void
lp_debug_draw_bins_by_cmd_length(struct lp_scene * scene)409 lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene )
410 {
411    unsigned x, y;
412 
413    for (y = 0; y < scene->tiles_y; y++) {
414       for (x = 0; x < scene->tiles_x; x++) {
415          const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";
416          unsigned sz = lp_scene_bin_size(scene, x, y);
417          unsigned sz2 = util_logbase2(sz);
418          debug_printf("%c", bits[MIN2(sz2,32)]);
419       }
420       debug_printf("\n");
421    }
422 }
423 
424 
425 void
lp_debug_bins(struct lp_scene * scene)426 lp_debug_bins( struct lp_scene *scene )
427 {
428    unsigned x, y;
429 
430    for (y = 0; y < scene->tiles_y; y++) {
431       for (x = 0; x < scene->tiles_x; x++) {
432          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
433          if (bin->head) {
434             debug_bin(bin, x, y);
435          }
436       }
437    }
438 }
439