Path: blob/21.2-virgl/src/gallium/drivers/llvmpipe/lp_rast_debug.c
4570 views
#include <inttypes.h> /* for PRIu64 macro */1#include "util/u_math.h"2#include "lp_rast_priv.h"3#include "lp_state_fs.h"45struct tile {6int coverage;7int overdraw;8const struct lp_rast_state *state;9char data[TILE_SIZE][TILE_SIZE];10};1112static char get_label( int i )13{14static const char *cmd_labels = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";15unsigned max_label = (2*26+10);1617if (i < max_label)18return cmd_labels[i];19else20return '?';21}22232425static 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"triangle_32_1",46"triangle_32_2",47"triangle_32_3",48"triangle_32_4",49"triangle_32_5",50"triangle_32_6",51"triangle_32_7",52"triangle_32_8",53"triangle_32_3_4",54"triangle_32_3_16",55"triangle_32_4_16",56};5758static const char *cmd_name(unsigned cmd)59{60assert(ARRAY_SIZE(cmd_names) > cmd);61return cmd_names[cmd];62}6364static const struct lp_fragment_shader_variant *65get_variant( const struct lp_rast_state *state,66const struct cmd_block *block,67int k )68{69if (!state)70return NULL;7172if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||73block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE ||74block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||75block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||76block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||77block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||78block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||79block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||80block->cmd[k] == LP_RAST_OP_TRIANGLE_7)81return state->variant;8283return NULL;84}858687static boolean88is_blend( const struct lp_rast_state *state,89const struct cmd_block *block,90int k )91{92const struct lp_fragment_shader_variant *variant = get_variant(state, block, k);9394if (variant)95return variant->key.blend.rt[0].blend_enable;9697return FALSE;98}99100101102static void103debug_bin( const struct cmd_bin *bin, int x, int y )104{105const struct lp_rast_state *state = NULL;106const struct cmd_block *head = bin->head;107int i, j = 0;108109debug_printf("bin %d,%d:\n", x, y);110111while (head) {112for (i = 0; i < head->count; i++, j++) {113if (head->cmd[i] == LP_RAST_OP_SET_STATE)114state = head->arg[i].state;115116debug_printf("%d: %s %s\n", j,117cmd_name(head->cmd[i]),118is_blend(state, head, i) ? "blended" : "");119}120head = head->next;121}122}123124125static void plot(struct tile *tile,126int x, int y,127char val,128boolean blend)129{130if (tile->data[x][y] == ' ')131tile->coverage++;132else133tile->overdraw++;134135tile->data[x][y] = val;136}137138139140141142143static int144debug_shade_tile(int x, int y,145const union lp_rast_cmd_arg arg,146struct tile *tile,147char val)148{149const struct lp_rast_shader_inputs *inputs = arg.shade_tile;150boolean blend;151unsigned i,j;152153if (!tile->state)154return 0;155156blend = tile->state->variant->key.blend.rt[0].blend_enable;157158if (inputs->disable)159return 0;160161for (i = 0; i < TILE_SIZE; i++)162for (j = 0; j < TILE_SIZE; j++)163plot(tile, i, j, val, blend);164165return TILE_SIZE * TILE_SIZE;166}167168static int169debug_clear_tile(int x, int y,170const union lp_rast_cmd_arg arg,171struct tile *tile,172char val)173{174unsigned i,j;175176for (i = 0; i < TILE_SIZE; i++)177for (j = 0; j < TILE_SIZE; j++)178plot(tile, i, j, val, FALSE);179180return TILE_SIZE * TILE_SIZE;181182}183184185static int186debug_triangle(int tilex, int tiley,187const union lp_rast_cmd_arg arg,188struct tile *tile,189char val)190{191const struct lp_rast_triangle *tri = arg.triangle.tri;192unsigned plane_mask = arg.triangle.plane_mask;193const struct lp_rast_plane *tri_plane = GET_PLANES(tri);194struct lp_rast_plane plane[8];195int x, y;196int count = 0;197unsigned i, nr_planes = 0;198boolean blend = tile->state->variant->key.blend.rt[0].blend_enable;199200if (tri->inputs.disable) {201/* This triangle was partially binned and has been disabled */202return 0;203}204205while (plane_mask) {206plane[nr_planes] = tri_plane[u_bit_scan(&plane_mask)];207plane[nr_planes].c = (plane[nr_planes].c +208IMUL64(plane[nr_planes].dcdy, tiley) -209IMUL64(plane[nr_planes].dcdx, tilex));210nr_planes++;211}212213for(y = 0; y < TILE_SIZE; y++)214{215for(x = 0; x < TILE_SIZE; x++)216{217for (i = 0; i < nr_planes; i++)218if (plane[i].c <= 0)219goto out;220221plot(tile, x, y, val, blend);222count++;223224out:225for (i = 0; i < nr_planes; i++)226plane[i].c -= plane[i].dcdx;227}228229for (i = 0; i < nr_planes; i++) {230plane[i].c += IMUL64(plane[i].dcdx, TILE_SIZE);231plane[i].c += plane[i].dcdy;232}233}234return count;235}236237238239240241static void242do_debug_bin( struct tile *tile,243const struct cmd_bin *bin,244int x, int y,245boolean print_cmds)246{247unsigned k, j = 0;248const struct cmd_block *block;249250int tx = x * TILE_SIZE;251int ty = y * TILE_SIZE;252253memset(tile->data, ' ', sizeof tile->data);254tile->coverage = 0;255tile->overdraw = 0;256tile->state = NULL;257258for (block = bin->head; block; block = block->next) {259for (k = 0; k < block->count; k++, j++) {260boolean blend = is_blend(tile->state, block, k);261char val = get_label(j);262int count = 0;263264if (print_cmds)265debug_printf("%c: %15s", val, cmd_name(block->cmd[k]));266267if (block->cmd[k] == LP_RAST_OP_SET_STATE)268tile->state = block->arg[k].state;269270if (block->cmd[k] == LP_RAST_OP_CLEAR_COLOR ||271block->cmd[k] == LP_RAST_OP_CLEAR_ZSTENCIL)272count = debug_clear_tile(tx, ty, block->arg[k], tile, val);273274if (block->cmd[k] == LP_RAST_OP_SHADE_TILE ||275block->cmd[k] == LP_RAST_OP_SHADE_TILE_OPAQUE)276count = debug_shade_tile(tx, ty, block->arg[k], tile, val);277278if (block->cmd[k] == LP_RAST_OP_TRIANGLE_1 ||279block->cmd[k] == LP_RAST_OP_TRIANGLE_2 ||280block->cmd[k] == LP_RAST_OP_TRIANGLE_3 ||281block->cmd[k] == LP_RAST_OP_TRIANGLE_4 ||282block->cmd[k] == LP_RAST_OP_TRIANGLE_5 ||283block->cmd[k] == LP_RAST_OP_TRIANGLE_6 ||284block->cmd[k] == LP_RAST_OP_TRIANGLE_7)285count = debug_triangle(tx, ty, block->arg[k], tile, val);286287if (print_cmds) {288debug_printf(" % 5d", count);289290if (blend)291debug_printf(" blended");292293debug_printf("\n");294}295}296}297}298299void300lp_debug_bin( const struct cmd_bin *bin, int i, int j)301{302struct tile tile;303int x,y;304305if (bin->head) {306do_debug_bin(&tile, bin, i, j, TRUE);307308debug_printf("------------------------------------------------------------------\n");309for (y = 0; y < TILE_SIZE; y++) {310for (x = 0; x < TILE_SIZE; x++) {311debug_printf("%c", tile.data[y][x]);312}313debug_printf("|\n");314}315debug_printf("------------------------------------------------------------------\n");316317debug_printf("each pixel drawn avg %f times\n",318((float)tile.overdraw + tile.coverage)/(float)tile.coverage);319}320}321322323324325326327/** Return number of bytes used for a single bin */328static unsigned329lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )330{331struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);332const struct cmd_block *cmd;333unsigned size = 0;334for (cmd = bin->head; cmd; cmd = cmd->next) {335size += (cmd->count *336(sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));337}338return size;339}340341342343void344lp_debug_draw_bins_by_coverage( struct lp_scene *scene )345{346unsigned x, y;347unsigned total = 0;348unsigned possible = 0;349static uint64_t _total = 0;350static uint64_t _possible = 0;351352for (x = 0; x < scene->tiles_x; x++)353debug_printf("-");354debug_printf("\n");355356for (y = 0; y < scene->tiles_y; y++) {357for (x = 0; x < scene->tiles_x; x++) {358struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);359const char *bits = "0123456789";360struct tile tile;361362if (bin->head) {363//lp_debug_bin(bin, x, y);364365do_debug_bin(&tile, bin, x, y, FALSE);366367total += tile.coverage;368possible += 64*64;369370if (tile.coverage == 64*64)371debug_printf("*");372else if (tile.coverage) {373int bit = tile.coverage/(64.0*64.0)*10;374debug_printf("%c", bits[MIN2(bit,10)]);375}376else377debug_printf("?");378}379else {380debug_printf(" ");381}382}383debug_printf("|\n");384}385386for (x = 0; x < scene->tiles_x; x++)387debug_printf("-");388debug_printf("\n");389390debug_printf("this tile total: %u possible %u: percentage: %f\n",391total,392possible,393total * 100.0 / (float)possible);394395_total += total;396_possible += possible;397398399debug_printf("overall total: %" PRIu64400" possible %" PRIu64 ": percentage: %f\n",401_total,402_possible,403(double) _total * 100.0 / (double)_possible);404}405406407void408lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene )409{410unsigned x, y;411412for (y = 0; y < scene->tiles_y; y++) {413for (x = 0; x < scene->tiles_x; x++) {414const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";415unsigned sz = lp_scene_bin_size(scene, x, y);416unsigned sz2 = util_logbase2(sz);417debug_printf("%c", bits[MIN2(sz2,32)]);418}419debug_printf("\n");420}421}422423424void425lp_debug_bins( struct lp_scene *scene )426{427unsigned x, y;428429for (y = 0; y < scene->tiles_y; y++) {430for (x = 0; x < scene->tiles_x; x++) {431struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);432if (bin->head) {433debug_bin(bin, x, y);434}435}436}437}438439440