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