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