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