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