Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /*
  29.  * Binning code for triangles
  30.  */
  31.  
  32. #include "util/u_math.h"
  33. #include "util/u_memory.h"
  34. #include "util/u_rect.h"
  35. #include "util/u_sse.h"
  36. #include "lp_perf.h"
  37. #include "lp_setup_context.h"
  38. #include "lp_rast.h"
  39. #include "lp_state_fs.h"
  40. #include "lp_state_setup.h"
  41. #include "lp_context.h"
  42.  
  43. #include <inttypes.h>
  44.  
  45. #define NUM_CHANNELS 4
  46.  
  47. #if defined(PIPE_ARCH_SSE)
  48. #include <emmintrin.h>
  49. #endif
  50.  
  51. static INLINE int
  52. subpixel_snap(float a)
  53. {
  54.    return util_iround(FIXED_ONE * a);
  55. }
  56.  
  57. static INLINE float
  58. fixed_to_float(int a)
  59. {
  60.    return a * (1.0f / FIXED_ONE);
  61. }
  62.  
  63.  
  64. /* Position and area in fixed point coordinates */
  65. struct fixed_position {
  66.    int32_t x[4];
  67.    int32_t y[4];
  68.    int64_t area;
  69.    int32_t dx01;
  70.    int32_t dy01;
  71.    int32_t dx20;
  72.    int32_t dy20;
  73. };
  74.  
  75.  
  76. /**
  77.  * Alloc space for a new triangle plus the input.a0/dadx/dady arrays
  78.  * immediately after it.
  79.  * The memory is allocated from the per-scene pool, not per-tile.
  80.  * \param tri_size  returns number of bytes allocated
  81.  * \param num_inputs  number of fragment shader inputs
  82.  * \return pointer to triangle space
  83.  */
  84. struct lp_rast_triangle *
  85. lp_setup_alloc_triangle(struct lp_scene *scene,
  86.                         unsigned nr_inputs,
  87.                         unsigned nr_planes,
  88.                         unsigned *tri_size)
  89. {
  90.    unsigned input_array_sz = NUM_CHANNELS * (nr_inputs + 1) * sizeof(float);
  91.    unsigned plane_sz = nr_planes * sizeof(struct lp_rast_plane);
  92.    struct lp_rast_triangle *tri;
  93.  
  94.    *tri_size = (sizeof(struct lp_rast_triangle) +
  95.                 3 * input_array_sz +
  96.                 plane_sz);
  97.  
  98.    tri = lp_scene_alloc_aligned( scene, *tri_size, 16 );
  99.    if (tri == NULL)
  100.       return NULL;
  101.  
  102.    tri->inputs.stride = input_array_sz;
  103.  
  104.    {
  105.       char *a = (char *)tri;
  106.       char *b = (char *)&GET_PLANES(tri)[nr_planes];
  107.       assert(b - a == *tri_size);
  108.    }
  109.  
  110.    return tri;
  111. }
  112.  
  113. void
  114. lp_setup_print_vertex(struct lp_setup_context *setup,
  115.                       const char *name,
  116.                       const float (*v)[4])
  117. {
  118.    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
  119.    int i, j;
  120.  
  121.    debug_printf("   wpos (%s[0]) xyzw %f %f %f %f\n",
  122.                 name,
  123.                 v[0][0], v[0][1], v[0][2], v[0][3]);
  124.  
  125.    for (i = 0; i < key->num_inputs; i++) {
  126.       const float *in = v[key->inputs[i].src_index];
  127.  
  128.       debug_printf("  in[%d] (%s[%d]) %s%s%s%s ",
  129.                    i,
  130.                    name, key->inputs[i].src_index,
  131.                    (key->inputs[i].usage_mask & 0x1) ? "x" : " ",
  132.                    (key->inputs[i].usage_mask & 0x2) ? "y" : " ",
  133.                    (key->inputs[i].usage_mask & 0x4) ? "z" : " ",
  134.                    (key->inputs[i].usage_mask & 0x8) ? "w" : " ");
  135.  
  136.       for (j = 0; j < 4; j++)
  137.          if (key->inputs[i].usage_mask & (1<<j))
  138.             debug_printf("%.5f ", in[j]);
  139.  
  140.       debug_printf("\n");
  141.    }
  142. }
  143.  
  144.  
  145. /**
  146.  * Print triangle vertex attribs (for debug).
  147.  */
  148. void
  149. lp_setup_print_triangle(struct lp_setup_context *setup,
  150.                         const float (*v0)[4],
  151.                         const float (*v1)[4],
  152.                         const float (*v2)[4])
  153. {
  154.    debug_printf("triangle\n");
  155.  
  156.    {
  157.       const float ex = v0[0][0] - v2[0][0];
  158.       const float ey = v0[0][1] - v2[0][1];
  159.       const float fx = v1[0][0] - v2[0][0];
  160.       const float fy = v1[0][1] - v2[0][1];
  161.  
  162.       /* det = cross(e,f).z */
  163.       const float det = ex * fy - ey * fx;
  164.       if (det < 0.0f)
  165.          debug_printf("   - ccw\n");
  166.       else if (det > 0.0f)
  167.          debug_printf("   - cw\n");
  168.       else
  169.          debug_printf("   - zero area\n");
  170.    }
  171.  
  172.    lp_setup_print_vertex(setup, "v0", v0);
  173.    lp_setup_print_vertex(setup, "v1", v1);
  174.    lp_setup_print_vertex(setup, "v2", v2);
  175. }
  176.  
  177.  
  178. #define MAX_PLANES 8
  179. static unsigned
  180. lp_rast_tri_tab[MAX_PLANES+1] = {
  181.    0,               /* should be impossible */
  182.    LP_RAST_OP_TRIANGLE_1,
  183.    LP_RAST_OP_TRIANGLE_2,
  184.    LP_RAST_OP_TRIANGLE_3,
  185.    LP_RAST_OP_TRIANGLE_4,
  186.    LP_RAST_OP_TRIANGLE_5,
  187.    LP_RAST_OP_TRIANGLE_6,
  188.    LP_RAST_OP_TRIANGLE_7,
  189.    LP_RAST_OP_TRIANGLE_8
  190. };
  191.  
  192. static unsigned
  193. lp_rast_32_tri_tab[MAX_PLANES+1] = {
  194.    0,               /* should be impossible */
  195.    LP_RAST_OP_TRIANGLE_32_1,
  196.    LP_RAST_OP_TRIANGLE_32_2,
  197.    LP_RAST_OP_TRIANGLE_32_3,
  198.    LP_RAST_OP_TRIANGLE_32_4,
  199.    LP_RAST_OP_TRIANGLE_32_5,
  200.    LP_RAST_OP_TRIANGLE_32_6,
  201.    LP_RAST_OP_TRIANGLE_32_7,
  202.    LP_RAST_OP_TRIANGLE_32_8
  203. };
  204.  
  205.  
  206.  
  207. /**
  208.  * The primitive covers the whole tile- shade whole tile.
  209.  *
  210.  * \param tx, ty  the tile position in tiles, not pixels
  211.  */
  212. static boolean
  213. lp_setup_whole_tile(struct lp_setup_context *setup,
  214.                     const struct lp_rast_shader_inputs *inputs,
  215.                     int tx, int ty)
  216. {
  217.    struct lp_scene *scene = setup->scene;
  218.  
  219.    LP_COUNT(nr_fully_covered_64);
  220.  
  221.    /* if variant is opaque and scissor doesn't effect the tile */
  222.    if (inputs->opaque) {
  223.       /* Several things prevent this optimization from working:
  224.        * - For layered rendering we can't determine if this covers the same layer
  225.        * as previous rendering (or in case of clears those actually always cover
  226.        * all layers so optimization is impossible). Need to use fb_max_layer and
  227.        * not setup->layer_slot to determine this since even if there's currently
  228.        * no slot assigned previous rendering could have used one.
  229.        * - If there were any Begin/End query commands in the scene then those
  230.        * would get removed which would be very wrong. Furthermore, if queries
  231.        * were just active we also can't do the optimization since to get
  232.        * accurate query results we unfortunately need to execute the rendering
  233.        * commands.
  234.        */
  235.       if (!scene->fb.zsbuf && scene->fb_max_layer == 0 && !scene->had_queries) {
  236.          /*
  237.           * All previous rendering will be overwritten so reset the bin.
  238.           */
  239.          lp_scene_bin_reset( scene, tx, ty );
  240.       }
  241.  
  242.       LP_COUNT(nr_shade_opaque_64);
  243.       return lp_scene_bin_cmd_with_state( scene, tx, ty,
  244.                                           setup->fs.stored,
  245.                                           LP_RAST_OP_SHADE_TILE_OPAQUE,
  246.                                           lp_rast_arg_inputs(inputs) );
  247.    } else {
  248.       LP_COUNT(nr_shade_64);
  249.       return lp_scene_bin_cmd_with_state( scene, tx, ty,
  250.                                           setup->fs.stored,
  251.                                           LP_RAST_OP_SHADE_TILE,
  252.                                           lp_rast_arg_inputs(inputs) );
  253.    }
  254. }
  255.  
  256.  
  257. /**
  258.  * Do basic setup for triangle rasterization and determine which
  259.  * framebuffer tiles are touched.  Put the triangle in the scene's
  260.  * bins for the tiles which we overlap.
  261.  */
  262. static boolean
  263. do_triangle_ccw(struct lp_setup_context *setup,
  264.                 struct fixed_position* position,
  265.                 const float (*v0)[4],
  266.                 const float (*v1)[4],
  267.                 const float (*v2)[4],
  268.                 boolean frontfacing )
  269. {
  270.    struct lp_scene *scene = setup->scene;
  271.    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
  272.    struct lp_rast_triangle *tri;
  273.    struct lp_rast_plane *plane;
  274.    struct u_rect bbox;
  275.    unsigned tri_bytes;
  276.    int nr_planes = 3;
  277.    unsigned viewport_index = 0;
  278.    unsigned layer = 0;
  279.  
  280.    /* Area should always be positive here */
  281.    assert(position->area > 0);
  282.  
  283.    if (0)
  284.       lp_setup_print_triangle(setup, v0, v1, v2);
  285.  
  286.    if (setup->scissor_test) {
  287.       nr_planes = 7;
  288.       if (setup->viewport_index_slot > 0) {
  289.          unsigned *udata = (unsigned*)v0[setup->viewport_index_slot];
  290.          viewport_index = lp_clamp_viewport_idx(*udata);
  291.       }
  292.    }
  293.    else {
  294.       nr_planes = 3;
  295.    }
  296.    if (setup->layer_slot > 0) {
  297.       layer = *(unsigned*)v1[setup->layer_slot];
  298.       layer = MIN2(layer, scene->fb_max_layer);
  299.    }
  300.  
  301.    /* Bounding rectangle (in pixels) */
  302.    {
  303.       /* Yes this is necessary to accurately calculate bounding boxes
  304.        * with the two fill-conventions we support.  GL (normally) ends
  305.        * up needing a bottom-left fill convention, which requires
  306.        * slightly different rounding.
  307.        */
  308.       int adj = (setup->bottom_edge_rule != 0) ? 1 : 0;
  309.  
  310.       /* Inclusive x0, exclusive x1 */
  311.       bbox.x0 =  MIN3(position->x[0], position->x[1], position->x[2]) >> FIXED_ORDER;
  312.       bbox.x1 = (MAX3(position->x[0], position->x[1], position->x[2]) - 1) >> FIXED_ORDER;
  313.  
  314.       /* Inclusive / exclusive depending upon adj (bottom-left or top-right) */
  315.       bbox.y0 = (MIN3(position->y[0], position->y[1], position->y[2]) + adj) >> FIXED_ORDER;
  316.       bbox.y1 = (MAX3(position->y[0], position->y[1], position->y[2]) - 1 + adj) >> FIXED_ORDER;
  317.    }
  318.  
  319.    if (bbox.x1 < bbox.x0 ||
  320.        bbox.y1 < bbox.y0) {
  321.       if (0) debug_printf("empty bounding box\n");
  322.       LP_COUNT(nr_culled_tris);
  323.       return TRUE;
  324.    }
  325.  
  326.    if (!u_rect_test_intersection(&setup->draw_regions[viewport_index], &bbox)) {
  327.       if (0) debug_printf("offscreen\n");
  328.       LP_COUNT(nr_culled_tris);
  329.       return TRUE;
  330.    }
  331.  
  332.    /* Can safely discard negative regions, but need to keep hold of
  333.     * information about when the triangle extends past screen
  334.     * boundaries.  See trimmed_box in lp_setup_bin_triangle().
  335.     */
  336.    bbox.x0 = MAX2(bbox.x0, 0);
  337.    bbox.y0 = MAX2(bbox.y0, 0);
  338.  
  339.    tri = lp_setup_alloc_triangle(scene,
  340.                                  key->num_inputs,
  341.                                  nr_planes,
  342.                                  &tri_bytes);
  343.    if (!tri)
  344.       return FALSE;
  345.  
  346. #if 0
  347.    tri->v[0][0] = v0[0][0];
  348.    tri->v[1][0] = v1[0][0];
  349.    tri->v[2][0] = v2[0][0];
  350.    tri->v[0][1] = v0[0][1];
  351.    tri->v[1][1] = v1[0][1];
  352.    tri->v[2][1] = v2[0][1];
  353. #endif
  354.  
  355.    LP_COUNT(nr_tris);
  356.  
  357.    /* Setup parameter interpolants:
  358.     */
  359.    setup->setup.variant->jit_function( v0,
  360.                                        v1,
  361.                                        v2,
  362.                                        frontfacing,
  363.                                        GET_A0(&tri->inputs),
  364.                                        GET_DADX(&tri->inputs),
  365.                                        GET_DADY(&tri->inputs) );
  366.  
  367.    tri->inputs.frontfacing = frontfacing;
  368.    tri->inputs.disable = FALSE;
  369.    tri->inputs.opaque = setup->fs.current.variant->opaque;
  370.    tri->inputs.layer = layer;
  371.    tri->inputs.viewport_index = viewport_index;
  372.  
  373.    if (0)
  374.       lp_dump_setup_coef(&setup->setup.variant->key,
  375.                          (const float (*)[4])GET_A0(&tri->inputs),
  376.                          (const float (*)[4])GET_DADX(&tri->inputs),
  377.                          (const float (*)[4])GET_DADY(&tri->inputs));
  378.  
  379.    plane = GET_PLANES(tri);
  380.  
  381. #if defined(PIPE_ARCH_SSE)
  382.    if (setup->fb.width <= MAX_FIXED_LENGTH32 &&
  383.        setup->fb.height <= MAX_FIXED_LENGTH32 &&
  384.        (bbox.x1 - bbox.x0) <= MAX_FIXED_LENGTH32 &&
  385.        (bbox.y1 - bbox.y0) <= MAX_FIXED_LENGTH32) {
  386.       __m128i vertx, verty;
  387.       __m128i shufx, shufy;
  388.       __m128i dcdx, dcdy, c;
  389.       __m128i unused;
  390.       __m128i dcdx_neg_mask;
  391.       __m128i dcdy_neg_mask;
  392.       __m128i dcdx_zero_mask;
  393.       __m128i top_left_flag;
  394.       __m128i c_inc_mask, c_inc;
  395.       __m128i eo, p0, p1, p2;
  396.       __m128i zero = _mm_setzero_si128();
  397.       PIPE_ALIGN_VAR(16) int32_t temp_vec[4];
  398.  
  399.       vertx = _mm_loadu_si128((__m128i *)position->x); /* vertex x coords */
  400.       verty = _mm_loadu_si128((__m128i *)position->y); /* vertex y coords */
  401.  
  402.       shufx = _mm_shuffle_epi32(vertx, _MM_SHUFFLE(3,0,2,1));
  403.       shufy = _mm_shuffle_epi32(verty, _MM_SHUFFLE(3,0,2,1));
  404.  
  405.       dcdx = _mm_sub_epi32(verty, shufy);
  406.       dcdy = _mm_sub_epi32(vertx, shufx);
  407.  
  408.       dcdx_neg_mask = _mm_srai_epi32(dcdx, 31);
  409.       dcdx_zero_mask = _mm_cmpeq_epi32(dcdx, zero);
  410.       dcdy_neg_mask = _mm_srai_epi32(dcdy, 31);
  411.  
  412.       top_left_flag = _mm_set1_epi32((setup->bottom_edge_rule == 0) ? ~0 : 0);
  413.  
  414.       c_inc_mask = _mm_or_si128(dcdx_neg_mask,
  415.                                 _mm_and_si128(dcdx_zero_mask,
  416.                                               _mm_xor_si128(dcdy_neg_mask,
  417.                                                             top_left_flag)));
  418.  
  419.       c_inc = _mm_srli_epi32(c_inc_mask, 31);
  420.  
  421.       c = _mm_sub_epi32(mm_mullo_epi32(dcdx, vertx),
  422.                         mm_mullo_epi32(dcdy, verty));
  423.  
  424.       c = _mm_add_epi32(c, c_inc);
  425.  
  426.       /* Scale up to match c:
  427.        */
  428.       dcdx = _mm_slli_epi32(dcdx, FIXED_ORDER);
  429.       dcdy = _mm_slli_epi32(dcdy, FIXED_ORDER);
  430.  
  431.       /* Calculate trivial reject values:
  432.        */
  433.       eo = _mm_sub_epi32(_mm_andnot_si128(dcdy_neg_mask, dcdy),
  434.                          _mm_and_si128(dcdx_neg_mask, dcdx));
  435.  
  436.       /* ei = _mm_sub_epi32(_mm_sub_epi32(dcdy, dcdx), eo); */
  437.  
  438.       /* Pointless transpose which gets undone immediately in
  439.        * rasterization:
  440.        */
  441.       transpose4_epi32(&c, &dcdx, &dcdy, &eo,
  442.                        &p0, &p1, &p2, &unused);
  443.  
  444. #define STORE_PLANE(plane, vec) do {                 \
  445.          _mm_store_si128((__m128i *)&temp_vec, vec); \
  446.          plane.c    = (int64_t)temp_vec[0];          \
  447.          plane.dcdx = temp_vec[1];                   \
  448.          plane.dcdy = temp_vec[2];                   \
  449.          plane.eo   = temp_vec[3];                   \
  450.       } while(0)
  451.  
  452.       STORE_PLANE(plane[0], p0);
  453.       STORE_PLANE(plane[1], p1);
  454.       STORE_PLANE(plane[2], p2);
  455. #undef STORE_PLANE
  456.    } else
  457. #endif
  458.    {
  459.       int i;
  460.       plane[0].dcdy = position->dx01;
  461.       plane[1].dcdy = position->x[1] - position->x[2];
  462.       plane[2].dcdy = position->dx20;
  463.       plane[0].dcdx = position->dy01;
  464.       plane[1].dcdx = position->y[1] - position->y[2];
  465.       plane[2].dcdx = position->dy20;
  466.  
  467.       for (i = 0; i < 3; i++) {
  468.          /* half-edge constants, will be interated over the whole render
  469.           * target.
  470.           */
  471.          plane[i].c = IMUL64(plane[i].dcdx, position->x[i]) -
  472.                IMUL64(plane[i].dcdy, position->y[i]);
  473.  
  474.          /* correct for top-left vs. bottom-left fill convention.
  475.           */        
  476.          if (plane[i].dcdx < 0) {
  477.             /* both fill conventions want this - adjust for left edges */
  478.             plane[i].c++;            
  479.          }
  480.          else if (plane[i].dcdx == 0) {
  481.             if (setup->bottom_edge_rule == 0){
  482.                /* correct for top-left fill convention:
  483.                 */
  484.                if (plane[i].dcdy > 0) plane[i].c++;
  485.             }
  486.             else {
  487.                /* correct for bottom-left fill convention:
  488.                 */
  489.                if (plane[i].dcdy < 0) plane[i].c++;
  490.             }
  491.          }
  492.  
  493.          /* Scale up to match c:
  494.           */
  495.          assert((plane[i].dcdx << FIXED_ORDER) >> FIXED_ORDER == plane[i].dcdx);
  496.          assert((plane[i].dcdy << FIXED_ORDER) >> FIXED_ORDER == plane[i].dcdy);
  497.          plane[i].dcdx <<= FIXED_ORDER;
  498.          plane[i].dcdy <<= FIXED_ORDER;
  499.  
  500.          /* find trivial reject offsets for each edge for a single-pixel
  501.           * sized block.  These will be scaled up at each recursive level to
  502.           * match the active blocksize.  Scaling in this way works best if
  503.           * the blocks are square.
  504.           */
  505.          plane[i].eo = 0;
  506.          if (plane[i].dcdx < 0) plane[i].eo -= plane[i].dcdx;
  507.          if (plane[i].dcdy > 0) plane[i].eo += plane[i].dcdy;
  508.       }
  509.    }
  510.  
  511.    if (0) {
  512.       debug_printf("p0: %"PRIx64"/%08x/%08x/%"PRIx64"\n",
  513.                    plane[0].c,
  514.                    plane[0].dcdx,
  515.                    plane[0].dcdy,
  516.                    plane[0].eo);
  517.      
  518.       debug_printf("p1: %"PRIx64"/%08x/%08x/%"PRIx64"\n",
  519.                    plane[1].c,
  520.                    plane[1].dcdx,
  521.                    plane[1].dcdy,
  522.                    plane[1].eo);
  523.      
  524.       debug_printf("p2: %"PRIx64"/%08x/%08x/%"PRIx64"\n",
  525.                    plane[2].c,
  526.                    plane[2].dcdx,
  527.                    plane[2].dcdy,
  528.                    plane[2].eo);
  529.    }
  530.  
  531.  
  532.    /*
  533.     * When rasterizing scissored tris, use the intersection of the
  534.     * triangle bounding box and the scissor rect to generate the
  535.     * scissor planes.
  536.     *
  537.     * This permits us to cut off the triangle "tails" that are present
  538.     * in the intermediate recursive levels caused when two of the
  539.     * triangles edges don't diverge quickly enough to trivially reject
  540.     * exterior blocks from the triangle.
  541.     *
  542.     * It's not really clear if it's worth worrying about these tails,
  543.     * but since we generate the planes for each scissored tri, it's
  544.     * free to trim them in this case.
  545.     *
  546.     * Note that otherwise, the scissor planes only vary in 'C' value,
  547.     * and even then only on state-changes.  Could alternatively store
  548.     * these planes elsewhere.
  549.     */
  550.    if (nr_planes == 7) {
  551.       const struct u_rect *scissor = &setup->scissors[viewport_index];
  552.  
  553.       plane[3].dcdx = -1;
  554.       plane[3].dcdy = 0;
  555.       plane[3].c = 1-scissor->x0;
  556.       plane[3].eo = 1;
  557.  
  558.       plane[4].dcdx = 1;
  559.       plane[4].dcdy = 0;
  560.       plane[4].c = scissor->x1+1;
  561.       plane[4].eo = 0;
  562.  
  563.       plane[5].dcdx = 0;
  564.       plane[5].dcdy = 1;
  565.       plane[5].c = 1-scissor->y0;
  566.       plane[5].eo = 1;
  567.  
  568.       plane[6].dcdx = 0;
  569.       plane[6].dcdy = -1;
  570.       plane[6].c = scissor->y1+1;
  571.       plane[6].eo = 0;
  572.    }
  573.  
  574.    return lp_setup_bin_triangle(setup, tri, &bbox, nr_planes, viewport_index);
  575. }
  576.  
  577. /*
  578.  * Round to nearest less or equal power of two of the input.
  579.  *
  580.  * Undefined if no bit set exists, so code should check against 0 first.
  581.  */
  582. static INLINE uint32_t
  583. floor_pot(uint32_t n)
  584. {
  585. #if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
  586.    if (n == 0)
  587.       return 0;
  588.  
  589.    __asm__("bsr %1,%0"
  590.           : "=r" (n)
  591.           : "rm" (n));
  592.    return 1 << n;
  593. #else
  594.    n |= (n >>  1);
  595.    n |= (n >>  2);
  596.    n |= (n >>  4);
  597.    n |= (n >>  8);
  598.    n |= (n >> 16);
  599.    return n - (n >> 1);
  600. #endif
  601. }
  602.  
  603.  
  604. boolean
  605. lp_setup_bin_triangle( struct lp_setup_context *setup,
  606.                        struct lp_rast_triangle *tri,
  607.                        const struct u_rect *bbox,
  608.                        int nr_planes,
  609.                        unsigned viewport_index )
  610. {
  611.    struct lp_scene *scene = setup->scene;
  612.    struct u_rect trimmed_box = *bbox;  
  613.    int i;
  614.    /* What is the largest power-of-two boundary this triangle crosses:
  615.     */
  616.    int dx = floor_pot((bbox->x0 ^ bbox->x1) |
  617.                       (bbox->y0 ^ bbox->y1));
  618.  
  619.    /* The largest dimension of the rasterized area of the triangle
  620.     * (aligned to a 4x4 grid), rounded down to the nearest power of two:
  621.     */
  622.    int max_sz = ((bbox->x1 - (bbox->x0 & ~3)) |
  623.                  (bbox->y1 - (bbox->y0 & ~3)));
  624.    int sz = floor_pot(max_sz);
  625.    boolean use_32bits = max_sz <= MAX_FIXED_LENGTH32;
  626.  
  627.    /* Now apply scissor, etc to the bounding box.  Could do this
  628.     * earlier, but it confuses the logic for tri-16 and would force
  629.     * the rasterizer to also respect scissor, etc, just for the rare
  630.     * cases where a small triangle extends beyond the scissor.
  631.     */
  632.    u_rect_find_intersection(&setup->draw_regions[viewport_index],
  633.                             &trimmed_box);
  634.  
  635.    /* Determine which tile(s) intersect the triangle's bounding box
  636.     */
  637.    if (dx < TILE_SIZE)
  638.    {
  639.       int ix0 = bbox->x0 / TILE_SIZE;
  640.       int iy0 = bbox->y0 / TILE_SIZE;
  641.       unsigned px = bbox->x0 & 63 & ~3;
  642.       unsigned py = bbox->y0 & 63 & ~3;
  643.  
  644.       assert(iy0 == bbox->y1 / TILE_SIZE &&
  645.              ix0 == bbox->x1 / TILE_SIZE);
  646.  
  647.       if (nr_planes == 3) {
  648.          if (sz < 4)
  649.          {
  650.             /* Triangle is contained in a single 4x4 stamp:
  651.              */
  652.             assert(px + 4 <= TILE_SIZE);
  653.             assert(py + 4 <= TILE_SIZE);
  654.             return lp_scene_bin_cmd_with_state( scene, ix0, iy0,
  655.                                                 setup->fs.stored,
  656.                                                 use_32bits ?
  657.                                                 LP_RAST_OP_TRIANGLE_32_3_4 :
  658.                                                 LP_RAST_OP_TRIANGLE_3_4,
  659.                                                 lp_rast_arg_triangle_contained(tri, px, py) );
  660.          }
  661.  
  662.          if (sz < 16)
  663.          {
  664.             /* Triangle is contained in a single 16x16 block:
  665.              */
  666.  
  667.             /*
  668.              * The 16x16 block is only 4x4 aligned, and can exceed the tile
  669.              * dimensions if the triangle is 16 pixels in one dimension but 4
  670.              * in the other. So budge the 16x16 back inside the tile.
  671.              */
  672.             px = MIN2(px, TILE_SIZE - 16);
  673.             py = MIN2(py, TILE_SIZE - 16);
  674.  
  675.             assert(px + 16 <= TILE_SIZE);
  676.             assert(py + 16 <= TILE_SIZE);
  677.  
  678.             return lp_scene_bin_cmd_with_state( scene, ix0, iy0,
  679.                                                 setup->fs.stored,
  680.                                                 use_32bits ?
  681.                                                 LP_RAST_OP_TRIANGLE_32_3_16 :
  682.                                                 LP_RAST_OP_TRIANGLE_3_16,
  683.                                                 lp_rast_arg_triangle_contained(tri, px, py) );
  684.          }
  685.       }
  686.       else if (nr_planes == 4 && sz < 16)
  687.       {
  688.          px = MIN2(px, TILE_SIZE - 16);
  689.          py = MIN2(py, TILE_SIZE - 16);
  690.  
  691.          assert(px + 16 <= TILE_SIZE);
  692.          assert(py + 16 <= TILE_SIZE);
  693.  
  694.          return lp_scene_bin_cmd_with_state(scene, ix0, iy0,
  695.                                             setup->fs.stored,
  696.                                             use_32bits ?
  697.                                             LP_RAST_OP_TRIANGLE_32_4_16 :
  698.                                             LP_RAST_OP_TRIANGLE_4_16,
  699.                                             lp_rast_arg_triangle_contained(tri, px, py));
  700.       }
  701.  
  702.  
  703.       /* Triangle is contained in a single tile:
  704.        */
  705.       return lp_scene_bin_cmd_with_state(
  706.          scene, ix0, iy0, setup->fs.stored,
  707.          use_32bits ? lp_rast_32_tri_tab[nr_planes] : lp_rast_tri_tab[nr_planes],
  708.          lp_rast_arg_triangle(tri, (1<<nr_planes)-1));
  709.    }
  710.    else
  711.    {
  712.       struct lp_rast_plane *plane = GET_PLANES(tri);
  713.       int64_t c[MAX_PLANES];
  714.       int64_t ei[MAX_PLANES];
  715.  
  716.       int64_t eo[MAX_PLANES];
  717.       int64_t xstep[MAX_PLANES];
  718.       int64_t ystep[MAX_PLANES];
  719.       int x, y;
  720.  
  721.       int ix0 = trimmed_box.x0 / TILE_SIZE;
  722.       int iy0 = trimmed_box.y0 / TILE_SIZE;
  723.       int ix1 = trimmed_box.x1 / TILE_SIZE;
  724.       int iy1 = trimmed_box.y1 / TILE_SIZE;
  725.      
  726.       for (i = 0; i < nr_planes; i++) {
  727.          c[i] = (plane[i].c +
  728.                  IMUL64(plane[i].dcdy, iy0) * TILE_SIZE -
  729.                  IMUL64(plane[i].dcdx, ix0) * TILE_SIZE);
  730.  
  731.          ei[i] = (plane[i].dcdy -
  732.                   plane[i].dcdx -
  733.                   plane[i].eo) << TILE_ORDER;
  734.  
  735.          eo[i] = plane[i].eo << TILE_ORDER;
  736.          xstep[i] = -(((int64_t)plane[i].dcdx) << TILE_ORDER);
  737.          ystep[i] = ((int64_t)plane[i].dcdy) << TILE_ORDER;
  738.       }
  739.  
  740.  
  741.  
  742.       /* Test tile-sized blocks against the triangle.
  743.        * Discard blocks fully outside the tri.  If the block is fully
  744.        * contained inside the tri, bin an lp_rast_shade_tile command.
  745.        * Else, bin a lp_rast_triangle command.
  746.        */
  747.       for (y = iy0; y <= iy1; y++)
  748.       {
  749.          boolean in = FALSE;  /* are we inside the triangle? */
  750.          int64_t cx[MAX_PLANES];
  751.  
  752.          for (i = 0; i < nr_planes; i++)
  753.             cx[i] = c[i];
  754.  
  755.          for (x = ix0; x <= ix1; x++)
  756.          {
  757.             int out = 0;
  758.             int partial = 0;
  759.  
  760.             for (i = 0; i < nr_planes; i++) {
  761.                int64_t planeout = cx[i] + eo[i];
  762.                int64_t planepartial = cx[i] + ei[i] - 1;
  763.                out |= (int) (planeout >> 63);
  764.                partial |= ((int) (planepartial >> 63)) & (1<<i);
  765.             }
  766.  
  767.             if (out) {
  768.                /* do nothing */
  769.                if (in)
  770.                   break;  /* exiting triangle, all done with this row */
  771.                LP_COUNT(nr_empty_64);
  772.             }
  773.             else if (partial) {
  774.                /* Not trivially accepted by at least one plane -
  775.                 * rasterize/shade partial tile
  776.                 */
  777.                int count = util_bitcount(partial);
  778.                in = TRUE;
  779.                
  780.                if (!lp_scene_bin_cmd_with_state( scene, x, y,
  781.                                                  setup->fs.stored,
  782.                                                  use_32bits ?
  783.                                                  lp_rast_32_tri_tab[count] :
  784.                                                  lp_rast_tri_tab[count],
  785.                                                  lp_rast_arg_triangle(tri, partial) ))
  786.                   goto fail;
  787.  
  788.                LP_COUNT(nr_partially_covered_64);
  789.             }
  790.             else {
  791.                /* triangle covers the whole tile- shade whole tile */
  792.                LP_COUNT(nr_fully_covered_64);
  793.                in = TRUE;
  794.                if (!lp_setup_whole_tile(setup, &tri->inputs, x, y))
  795.                   goto fail;
  796.             }
  797.  
  798.             /* Iterate cx values across the region: */
  799.             for (i = 0; i < nr_planes; i++)
  800.                cx[i] += xstep[i];
  801.          }
  802.  
  803.          /* Iterate c values down the region: */
  804.          for (i = 0; i < nr_planes; i++)
  805.             c[i] += ystep[i];
  806.       }
  807.    }
  808.  
  809.    return TRUE;
  810.  
  811. fail:
  812.    /* Need to disable any partially binned triangle.  This is easier
  813.     * than trying to locate all the triangle, shade-tile, etc,
  814.     * commands which may have been binned.
  815.     */
  816.    tri->inputs.disable = TRUE;
  817.    return FALSE;
  818. }
  819.  
  820.  
  821. /**
  822.  * Try to draw the triangle, restart the scene on failure.
  823.  */
  824. static void retry_triangle_ccw( struct lp_setup_context *setup,
  825.                                 struct fixed_position* position,
  826.                                 const float (*v0)[4],
  827.                                 const float (*v1)[4],
  828.                                 const float (*v2)[4],
  829.                                 boolean front)
  830. {
  831.    if (!do_triangle_ccw( setup, position, v0, v1, v2, front ))
  832.    {
  833.       if (!lp_setup_flush_and_restart(setup))
  834.          return;
  835.  
  836.       if (!do_triangle_ccw( setup, position, v0, v1, v2, front ))
  837.          return;
  838.    }
  839. }
  840.  
  841. /**
  842.  * Calculate fixed position data for a triangle
  843.  */
  844. static INLINE void
  845. calc_fixed_position( struct lp_setup_context *setup,
  846.                      struct fixed_position* position,
  847.                      const float (*v0)[4],
  848.                      const float (*v1)[4],
  849.                      const float (*v2)[4])
  850. {
  851.    position->x[0] = subpixel_snap(v0[0][0] - setup->pixel_offset);
  852.    position->x[1] = subpixel_snap(v1[0][0] - setup->pixel_offset);
  853.    position->x[2] = subpixel_snap(v2[0][0] - setup->pixel_offset);
  854.    position->x[3] = 0;
  855.  
  856.    position->y[0] = subpixel_snap(v0[0][1] - setup->pixel_offset);
  857.    position->y[1] = subpixel_snap(v1[0][1] - setup->pixel_offset);
  858.    position->y[2] = subpixel_snap(v2[0][1] - setup->pixel_offset);
  859.    position->y[3] = 0;
  860.  
  861.    position->dx01 = position->x[0] - position->x[1];
  862.    position->dy01 = position->y[0] - position->y[1];
  863.  
  864.    position->dx20 = position->x[2] - position->x[0];
  865.    position->dy20 = position->y[2] - position->y[0];
  866.  
  867.    position->area = IMUL64(position->dx01, position->dy20) -
  868.          IMUL64(position->dx20, position->dy01);
  869. }
  870.  
  871.  
  872. /**
  873.  * Rotate a triangle, flipping its clockwise direction,
  874.  * Swaps values for xy[0] and xy[1]
  875.  */
  876. static INLINE void
  877. rotate_fixed_position_01( struct fixed_position* position )
  878. {
  879.    int x, y;
  880.  
  881.    x = position->x[1];
  882.    y = position->y[1];
  883.    position->x[1] = position->x[0];
  884.    position->y[1] = position->y[0];
  885.    position->x[0] = x;
  886.    position->y[0] = y;
  887.  
  888.    position->dx01 = -position->dx01;
  889.    position->dy01 = -position->dy01;
  890.    position->dx20 = position->x[2] - position->x[0];
  891.    position->dy20 = position->y[2] - position->y[0];
  892.  
  893.    position->area = -position->area;
  894. }
  895.  
  896.  
  897. /**
  898.  * Rotate a triangle, flipping its clockwise direction,
  899.  * Swaps values for xy[1] and xy[2]
  900.  */
  901. static INLINE void
  902. rotate_fixed_position_12( struct fixed_position* position )
  903. {
  904.    int x, y;
  905.  
  906.    x = position->x[2];
  907.    y = position->y[2];
  908.    position->x[2] = position->x[1];
  909.    position->y[2] = position->y[1];
  910.    position->x[1] = x;
  911.    position->y[1] = y;
  912.  
  913.    x = position->dx01;
  914.    y = position->dy01;
  915.    position->dx01 = -position->dx20;
  916.    position->dy01 = -position->dy20;
  917.    position->dx20 = -x;
  918.    position->dy20 = -y;
  919.  
  920.    position->area = -position->area;
  921. }
  922.  
  923.  
  924. /**
  925.  * Draw triangle if it's CW, cull otherwise.
  926.  */
  927. static void triangle_cw( struct lp_setup_context *setup,
  928.                          const float (*v0)[4],
  929.                          const float (*v1)[4],
  930.                          const float (*v2)[4] )
  931. {
  932.    struct fixed_position position;
  933.  
  934.    calc_fixed_position(setup, &position, v0, v1, v2);
  935.  
  936.    if (position.area < 0) {
  937.       if (setup->flatshade_first) {
  938.          rotate_fixed_position_12(&position);
  939.          retry_triangle_ccw(setup, &position, v0, v2, v1, !setup->ccw_is_frontface);
  940.       } else {
  941.          rotate_fixed_position_01(&position);
  942.          retry_triangle_ccw(setup, &position, v1, v0, v2, !setup->ccw_is_frontface);
  943.       }
  944.    }
  945. }
  946.  
  947.  
  948. static void triangle_ccw( struct lp_setup_context *setup,
  949.                           const float (*v0)[4],
  950.                           const float (*v1)[4],
  951.                           const float (*v2)[4])
  952. {
  953.    struct fixed_position position;
  954.  
  955.    calc_fixed_position(setup, &position, v0, v1, v2);
  956.  
  957.    if (position.area > 0)
  958.       retry_triangle_ccw(setup, &position, v0, v1, v2, setup->ccw_is_frontface);
  959. }
  960.  
  961. /**
  962.  * Draw triangle whether it's CW or CCW.
  963.  */
  964. static void triangle_both( struct lp_setup_context *setup,
  965.                            const float (*v0)[4],
  966.                            const float (*v1)[4],
  967.                            const float (*v2)[4] )
  968. {
  969.    struct fixed_position position;
  970.    struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
  971.  
  972.    if (lp_context->active_statistics_queries &&
  973.        !llvmpipe_rasterization_disabled(lp_context)) {
  974.       lp_context->pipeline_statistics.c_primitives++;
  975.    }
  976.  
  977.    calc_fixed_position(setup, &position, v0, v1, v2);
  978.  
  979.    if (0) {
  980.       assert(!util_is_inf_or_nan(v0[0][0]));
  981.       assert(!util_is_inf_or_nan(v0[0][1]));
  982.       assert(!util_is_inf_or_nan(v1[0][0]));
  983.       assert(!util_is_inf_or_nan(v1[0][1]));
  984.       assert(!util_is_inf_or_nan(v2[0][0]));
  985.       assert(!util_is_inf_or_nan(v2[0][1]));
  986.    }
  987.  
  988.    if (position.area > 0)
  989.       retry_triangle_ccw( setup, &position, v0, v1, v2, setup->ccw_is_frontface );
  990.    else if (position.area < 0) {
  991.       if (setup->flatshade_first) {
  992.          rotate_fixed_position_12( &position );
  993.          retry_triangle_ccw( setup, &position, v0, v2, v1, !setup->ccw_is_frontface );
  994.       } else {
  995.          rotate_fixed_position_01( &position );
  996.          retry_triangle_ccw( setup, &position, v1, v0, v2, !setup->ccw_is_frontface );
  997.       }
  998.    }
  999. }
  1000.  
  1001.  
  1002. static void triangle_nop( struct lp_setup_context *setup,
  1003.                           const float (*v0)[4],
  1004.                           const float (*v1)[4],
  1005.                           const float (*v2)[4] )
  1006. {
  1007. }
  1008.  
  1009.  
  1010. void
  1011. lp_setup_choose_triangle( struct lp_setup_context *setup )
  1012. {
  1013.    switch (setup->cullmode) {
  1014.    case PIPE_FACE_NONE:
  1015.       setup->triangle = triangle_both;
  1016.       break;
  1017.    case PIPE_FACE_BACK:
  1018.       setup->triangle = setup->ccw_is_frontface ? triangle_ccw : triangle_cw;
  1019.       break;
  1020.    case PIPE_FACE_FRONT:
  1021.       setup->triangle = setup->ccw_is_frontface ? triangle_cw : triangle_ccw;
  1022.       break;
  1023.    default:
  1024.       setup->triangle = triangle_nop;
  1025.       break;
  1026.    }
  1027. }
  1028.