Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.    "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.  
  59. static const char *cmd_name(unsigned cmd)
  60. {
  61.    assert(Elements(cmd_names) > cmd);
  62.    return cmd_names[cmd];
  63. }
  64.  
  65. static const struct lp_fragment_shader_variant *
  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
  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
  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.  
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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.