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