xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/llvmpipe/lp_rast_debug.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 
7 struct tile {
8    int coverage;
9    int overdraw;
10    const struct lp_rast_state *state;
11    char data[TILE_SIZE][TILE_SIZE];
12 };
13 
14 
15 static char
get_label(int i)16 get_label(int i)
17 {
18    static const char *cmd_labels =
19       "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
20    unsigned max_label = (2*26+10);
21 
22    if (i < max_label)
23       return cmd_labels[i];
24    else
25       return '?';
26 }
27 
28 
29 static const char *cmd_names[] =
30 {
31    "clear_color",
32    "clear_zstencil",
33    "triangle_1",
34    "triangle_2",
35    "triangle_3",
36    "triangle_4",
37    "triangle_5",
38    "triangle_6",
39    "triangle_7",
40    "triangle_8",
41    "triangle_3_4",
42    "triangle_3_16",
43    "triangle_4_16",
44    "shade_tile",
45    "shade_tile_opaque",
46    "begin_query",
47    "end_query",
48    "set_state",
49    "triangle_32_1",
50    "triangle_32_2",
51    "triangle_32_3",
52    "triangle_32_4",
53    "triangle_32_5",
54    "triangle_32_6",
55    "triangle_32_7",
56    "triangle_32_8",
57    "triangle_32_3_4",
58    "triangle_32_3_16",
59    "triangle_32_4_16",
60    "lp_rast_triangle_ms_1",
61    "lp_rast_triangle_ms_2",
62    "lp_rast_triangle_ms_3",
63    "lp_rast_triangle_ms_4",
64    "lp_rast_triangle_ms_5",
65    "lp_rast_triangle_ms_6",
66    "lp_rast_triangle_ms_7",
67    "lp_rast_triangle_ms_8",
68    "lp_rast_triangle_ms_3_4",
69    "lp_rast_triangle_ms_3_16",
70    "lp_rast_triangle_ms_4_16",
71    "rectangle",
72    "blit_tile",
73 };
74 
75 
76 static const char *
cmd_name(unsigned cmd)77 cmd_name(unsigned cmd)
78 {
79    STATIC_ASSERT(ARRAY_SIZE(cmd_names) == LP_RAST_OP_MAX);
80    assert(ARRAY_SIZE(cmd_names) > cmd);
81    return cmd_names[cmd];
82 }
83 
84 
85 static const struct lp_fragment_shader_variant *
get_variant(const struct lp_rast_state * state,const struct cmd_block * block,int k)86 get_variant(const struct lp_rast_state *state,
87             const struct cmd_block *block,
88             int k)
89 {
90    if (!state)
91       return NULL;
92 
93    if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
94        block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE ||
95        block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
96        block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
97        block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
98        block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
99        block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
100        block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
101        block->cmd[k] == LP_RAST_OP_TRIANGLE_7 ||
102        block->cmd[k] == LP_RAST_OP_RECTANGLE ||
103        block->cmd[k] == LP_RAST_OP_BLIT)
104       return state->variant;
105 
106    return NULL;
107 }
108 
109 
110 static bool
is_blend(const struct lp_rast_state * state,const struct cmd_block * block,int k)111 is_blend(const struct lp_rast_state *state,
112          const struct cmd_block *block,
113          int k)
114 {
115    const struct lp_fragment_shader_variant *variant =
116       get_variant(state, block, k);
117 
118    if (variant)
119       return  variant->key.blend.rt[0].blend_enable;
120 
121    return false;
122 }
123 
124 
125 static bool
is_linear(const struct lp_rast_state * state,const struct cmd_block * block,int k)126 is_linear(const struct lp_rast_state *state,
127           const struct cmd_block *block,
128           int k)
129 {
130    if (block->cmd[k] == LP_RAST_OP_BLIT)
131       return state->variant->jit_linear_blit != NULL;
132 
133    if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
134        block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)
135       return state->variant->jit_linear != NULL;
136 
137    if (block->cmd[k] == LP_RAST_OP_RECTANGLE)
138       return state->variant->jit_linear != NULL;
139 
140    return false;
141 }
142 
143 
144 static const char *
get_fs_kind(const struct lp_rast_state * state,const struct cmd_block * block,int k)145 get_fs_kind(const struct lp_rast_state *state,
146             const struct cmd_block *block,
147             int k)
148 {
149    const struct lp_fragment_shader_variant *variant =
150       get_variant(state, block, k);
151 
152    if (variant)
153       return lp_debug_fs_kind(variant->shader->kind);
154 
155    return "";
156 }
157 
158 
159 static void
debug_bin(const struct cmd_bin * bin,int x,int y)160 debug_bin(const struct cmd_bin *bin, int x, int y)
161 {
162    const struct lp_rast_state *state = NULL;
163    const struct cmd_block *head = bin->head;
164    const char *type;
165 
166    struct lp_bin_info info = lp_characterize_bin(bin);
167 
168    if (info.type & LP_RAST_FLAGS_BLIT)
169       type = "blit";
170    else if (info.type & LP_RAST_FLAGS_TILE)
171       type = "tile";
172    else if (info.type & LP_RAST_FLAGS_RECT)
173       type = "rect";
174    else if (info.type & LP_RAST_FLAGS_TRI)
175       type = "tri";
176    else
177       type = "unknown";
178 
179    debug_printf("bin %d,%d: type %s\n", x, y, type);
180 
181    int j = 0;
182    while (head) {
183       for (int i = 0; i < head->count; i++, j++) {
184          if (head->cmd[i] == LP_RAST_OP_SET_STATE)
185             state = head->arg[i].set_state;
186 
187          debug_printf("%d: %s %s\n", j,
188                       cmd_name(head->cmd[i]),
189                       is_blend(state, head, i) ? "blended" : "");
190       }
191       head = head->next;
192    }
193 }
194 
195 
196 static void
plot(struct tile * tile,int x,int y,char val,bool blend)197 plot(struct tile *tile,
198      int x, int y,
199      char val,
200      bool blend)
201 {
202    if (tile->data[x][y] == ' ')
203       tile->coverage++;
204    else
205       tile->overdraw++;
206 
207    tile->data[x][y] = val;
208 }
209 
210 
211 /**
212  * Scan the tile in chunks and figure out which pixels to rasterize
213  * for this rectangle.
214  */
215 static int
debug_rectangle(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)216 debug_rectangle(int x, int y,
217                 const union lp_rast_cmd_arg arg,
218                 struct tile *tile,
219                 char val)
220 {
221    const struct lp_rast_rectangle *rect = arg.rectangle;
222 
223    /* Check for "disabled" rectangles generated in out-of-memory
224     * conditions.
225     */
226    if (rect->inputs.disable) {
227       /* This command was partially binned and has been disabled */
228       return 0;
229    }
230 
231    bool blend = tile->state->variant->key.blend.rt[0].blend_enable;
232    unsigned count = 0;
233    for (unsigned i = 0; i < TILE_SIZE; i++) {
234       for (unsigned j = 0; j < TILE_SIZE; j++) {
235          if (rect->box.x0 <= x + i &&
236              rect->box.x1 >= x + i &&
237              rect->box.y0 <= y + j &&
238              rect->box.y1 >= y + j) {
239             plot(tile, i, j, val, blend);
240             count++;
241          }
242       }
243    }
244    return count;
245 }
246 
247 
248 static int
debug_blit_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)249 debug_blit_tile(int x, int y,
250                 const union lp_rast_cmd_arg arg,
251                 struct tile *tile,
252                 char val)
253 {
254    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
255 
256    if (inputs->disable)
257       return 0;
258 
259    for (unsigned i = 0; i < TILE_SIZE; i++)
260       for (unsigned j = 0; j < TILE_SIZE; j++)
261          plot(tile, i, j, val, false);
262 
263    return TILE_SIZE * TILE_SIZE;
264 }
265 
266 
267 static int
debug_shade_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)268 debug_shade_tile(int x, int y,
269                  const union lp_rast_cmd_arg arg,
270                  struct tile *tile,
271                  char val)
272 {
273    if (!tile->state)
274       return 0;
275 
276    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
277    if (inputs->disable)
278       return 0;
279 
280    bool blend = tile->state->variant->key.blend.rt[0].blend_enable;
281 
282    for (unsigned i = 0; i < TILE_SIZE; i++)
283       for (unsigned j = 0; j < TILE_SIZE; j++)
284          plot(tile, i, j, val, blend);
285 
286    return TILE_SIZE * TILE_SIZE;
287 }
288 
289 
290 static int
debug_clear_tile(int x,int y,const union lp_rast_cmd_arg arg,struct tile * tile,char val)291 debug_clear_tile(int x, int y,
292                  const union lp_rast_cmd_arg arg,
293                  struct tile *tile,
294                  char val)
295 {
296    for (unsigned i = 0; i < TILE_SIZE; i++)
297       for (unsigned j = 0; j < TILE_SIZE; j++)
298          plot(tile, i, j, val, false);
299 
300    return TILE_SIZE * TILE_SIZE;
301 }
302 
303 
304 static int
debug_triangle(int tilex,int tiley,const union lp_rast_cmd_arg arg,struct tile * tile,char val)305 debug_triangle(int tilex, int tiley,
306                const union lp_rast_cmd_arg arg,
307                struct tile *tile,
308                char val)
309 {
310    const struct lp_rast_triangle *tri = arg.triangle.tri;
311    unsigned plane_mask = arg.triangle.plane_mask;
312    const struct lp_rast_plane *tri_plane = GET_PLANES(tri);
313    struct lp_rast_plane plane[8];
314    int x, y;
315    int count = 0;
316    unsigned i, nr_planes = 0;
317    bool blend = tile->state->variant->key.blend.rt[0].blend_enable;
318 
319    if (tri->inputs.disable) {
320       /* This triangle was partially binned and has been disabled */
321       return 0;
322    }
323 
324    while (plane_mask) {
325       plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)];
326       plane[nr_planes].c = (plane[nr_planes].c +
327                             IMUL64(plane[nr_planes].dcdy, tiley) -
328                             IMUL64(plane[nr_planes].dcdx, tilex));
329       nr_planes++;
330    }
331 
332    for (y = 0; y < TILE_SIZE; y++) {
333       for (x = 0; x < TILE_SIZE; x++) {
334          for (i = 0; i < nr_planes; i++)
335             if (plane[i].c <= 0)
336                goto out;
337 
338          plot(tile, x, y, val, blend);
339          count++;
340 
341       out:
342          for (i = 0; i < nr_planes; i++)
343             plane[i].c -= plane[i].dcdx;
344       }
345 
346       for (i = 0; i < nr_planes; i++) {
347          plane[i].c += IMUL64(plane[i].dcdx, TILE_SIZE);
348          plane[i].c += plane[i].dcdy;
349       }
350    }
351    return count;
352 }
353 
354 
355 static void
do_debug_bin(struct tile * tile,const struct cmd_bin * bin,int x,int y,bool print_cmds)356 do_debug_bin(struct tile *tile,
357              const struct cmd_bin *bin,
358              int x, int y,
359              bool print_cmds)
360 {
361    unsigned k, j = 0;
362    const struct cmd_block *block;
363 
364    int tx = x * TILE_SIZE;
365    int ty = y * TILE_SIZE;
366 
367    memset(tile->data, ' ', sizeof tile->data);
368    tile->coverage = 0;
369    tile->overdraw = 0;
370    tile->state = NULL;
371 
372    for (block = bin->head; block; block = block->next) {
373       for (k = 0; k < block->count; k++, j++) {
374          bool blend = is_blend(tile->state, block, k);
375          bool linear = is_linear(tile->state, block, k);
376          const char *fskind = get_fs_kind(tile->state, block, k);
377          char val = get_label(j);
378          int count = 0;
379 
380          if (print_cmds)
381             debug_printf("%c: %15s", val, cmd_name(block->cmd[k]));
382 
383          if (block->cmd[k] == LP_RAST_OP_SET_STATE)
384             tile->state = block->arg[k].set_state;
385 
386          if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR ||
387              block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL)
388             count = debug_clear_tile(tx, ty, block->arg[k], tile, val);
389 
390          if (block->cmd[k] == LP_RAST_OP_BLIT)
391             count = debug_blit_tile(tx, ty, block->arg[k], tile, val);
392 
393          if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||
394              block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)
395             count = debug_shade_tile(tx, ty, block->arg[k], tile, val);
396 
397          if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||
398              block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||
399              block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||
400              block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||
401              block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||
402              block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||
403              block->cmd[k] == LP_RAST_OP_TRIANGLE_7)
404             count = debug_triangle(tx, ty, block->arg[k], tile, val);
405 
406          if (block->cmd[k] == LP_RAST_OP_RECTANGLE)
407             count = debug_rectangle(tx, ty, block->arg[k], tile, val);
408 
409          if (print_cmds) {
410             debug_printf(" % 5d", count);
411 
412             debug_printf(" %20s", fskind);
413 
414             if (blend)
415                debug_printf(" blended");
416 
417             if (linear)
418                debug_printf(" linear");
419 
420             debug_printf("\n");
421          }
422       }
423    }
424 }
425 
426 
427 void
lp_debug_bin(const struct cmd_bin * bin,int i,int j)428 lp_debug_bin(const struct cmd_bin *bin, int i, int j)
429 {
430    struct tile tile;
431 
432    if (bin->head) {
433       do_debug_bin(&tile, bin, i, j, true);
434 
435       debug_printf("------------------------------------------------------------------\n");
436       for (int y = 0; y < TILE_SIZE; y++) {
437          for (int x = 0; x < TILE_SIZE; x++) {
438             debug_printf("%c", tile.data[y][x]);
439          }
440          debug_printf("|\n");
441       }
442       debug_printf("------------------------------------------------------------------\n");
443 
444       debug_printf("each pixel drawn avg %f times\n",
445                    ((float)tile.overdraw + tile.coverage)/(float)tile.coverage);
446    }
447 }
448 
449 
450 /** Return number of bytes used for a single bin */
451 static unsigned
lp_scene_bin_size(const struct lp_scene * scene,unsigned x,unsigned y)452 lp_scene_bin_size(const struct lp_scene *scene, unsigned x, unsigned y)
453 {
454    struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);
455    const struct cmd_block *cmd;
456    unsigned size = 0;
457    for (cmd = bin->head; cmd; cmd = cmd->next) {
458       size += (cmd->count *
459                (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));
460    }
461    return size;
462 }
463 
464 
465 void
lp_debug_draw_bins_by_coverage(struct lp_scene * scene)466 lp_debug_draw_bins_by_coverage(struct lp_scene *scene)
467 {
468    unsigned total = 0;
469    unsigned possible = 0;
470    static uint64_t _total = 0;
471    static uint64_t _possible = 0;
472 
473    for (unsigned x = 0; x < scene->tiles_x; x++)
474       debug_printf("-");
475    debug_printf("\n");
476 
477    for (unsigned y = 0; y < scene->tiles_y; y++) {
478       for (unsigned x = 0; x < scene->tiles_x; x++) {
479          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
480 
481          if (bin->head) {
482             struct tile tile;
483             //lp_debug_bin(bin, x, y);
484 
485             do_debug_bin(&tile, bin, x, y, false);
486 
487             total += tile.coverage;
488             possible += 64*64;
489 
490             if (tile.coverage == 64*64)
491                debug_printf("*");
492             else if (tile.coverage) {
493                const char *bits = "0123456789";
494                int bit = tile.coverage/(64.0*64.0)*10;
495                debug_printf("%c", bits[MIN2(bit,10)]);
496             }
497             else
498                debug_printf("?");
499          } else {
500             debug_printf(" ");
501          }
502       }
503       debug_printf("|\n");
504    }
505 
506    for (unsigned x = 0; x < scene->tiles_x; x++)
507       debug_printf("-");
508    debug_printf("\n");
509 
510    debug_printf("this tile total: %u possible %u: percentage: %f\n",
511                 total,
512                 possible,
513                 total * 100.0 / (float)possible);
514 
515    _total += total;
516    _possible += possible;
517 
518    debug_printf("overall   total: %" PRIu64
519                 " possible %" PRIu64 ": percentage: %f\n",
520                 _total,
521                 _possible,
522                 (double) _total * 100.0 / (double)_possible);
523 }
524 
525 
526 void
lp_debug_draw_bins_by_cmd_length(struct lp_scene * scene)527 lp_debug_draw_bins_by_cmd_length(struct lp_scene *scene)
528 {
529    for (unsigned y = 0; y < scene->tiles_y; y++) {
530       for (unsigned x = 0; x < scene->tiles_x; x++) {
531          const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";
532          unsigned sz = lp_scene_bin_size(scene, x, y);
533          unsigned sz2 = util_logbase2(sz);
534          debug_printf("%c", bits[MIN2(sz2,32)]);
535       }
536       debug_printf("\n");
537    }
538 }
539 
540 
541 void
lp_debug_bins(struct lp_scene * scene)542 lp_debug_bins(struct lp_scene *scene)
543 {
544    for (unsigned y = 0; y < scene->tiles_y; y++) {
545       for (unsigned x = 0; x < scene->tiles_x; x++) {
546          struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
547          if (bin->head) {
548             debug_bin(bin, x, y);
549          }
550       }
551    }
552 }
553