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