Home | History | Annotate | Download | only in llvmpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
      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 TUNGSTEN GRAPHICS 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 lines
     30  */
     31 
     32 #include "util/u_math.h"
     33 #include "util/u_memory.h"
     34 #include "lp_perf.h"
     35 #include "lp_setup_context.h"
     36 #include "lp_rast.h"
     37 #include "lp_state_fs.h"
     38 #include "lp_state_setup.h"
     39 
     40 #define NUM_CHANNELS 4
     41 
     42 struct lp_line_info {
     43 
     44    float dx;
     45    float dy;
     46    float oneoverarea;
     47 
     48    const float (*v1)[4];
     49    const float (*v2)[4];
     50 
     51    float (*a0)[4];
     52    float (*dadx)[4];
     53    float (*dady)[4];
     54 };
     55 
     56 
     57 /**
     58  * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
     59  */
     60 static void constant_coef( struct lp_setup_context *setup,
     61                            struct lp_line_info *info,
     62                            unsigned slot,
     63                            const float value,
     64                            unsigned i )
     65 {
     66    info->a0[slot][i] = value;
     67    info->dadx[slot][i] = 0.0f;
     68    info->dady[slot][i] = 0.0f;
     69 }
     70 
     71 
     72 /**
     73  * Compute a0, dadx and dady for a linearly interpolated coefficient,
     74  * for a triangle.
     75  */
     76 static void linear_coef( struct lp_setup_context *setup,
     77                          struct lp_line_info *info,
     78                          unsigned slot,
     79                          unsigned vert_attr,
     80                          unsigned i)
     81 {
     82    float a1 = info->v1[vert_attr][i];
     83    float a2 = info->v2[vert_attr][i];
     84 
     85    float da21 = a1 - a2;
     86    float dadx = da21 * info->dx * info->oneoverarea;
     87    float dady = da21 * info->dy * info->oneoverarea;
     88 
     89    info->dadx[slot][i] = dadx;
     90    info->dady[slot][i] = dady;
     91 
     92    info->a0[slot][i] = (a1 -
     93                               (dadx * (info->v1[0][0] - setup->pixel_offset) +
     94                                dady * (info->v1[0][1] - setup->pixel_offset)));
     95 }
     96 
     97 
     98 /**
     99  * Compute a0, dadx and dady for a perspective-corrected interpolant,
    100  * for a triangle.
    101  * We basically multiply the vertex value by 1/w before computing
    102  * the plane coefficients (a0, dadx, dady).
    103  * Later, when we compute the value at a particular fragment position we'll
    104  * divide the interpolated value by the interpolated W at that fragment.
    105  */
    106 static void perspective_coef( struct lp_setup_context *setup,
    107                               struct lp_line_info *info,
    108                               unsigned slot,
    109                               unsigned vert_attr,
    110                               unsigned i)
    111 {
    112    /* premultiply by 1/w  (v[0][3] is always 1/w):
    113     */
    114    float a1 = info->v1[vert_attr][i] * info->v1[0][3];
    115    float a2 = info->v2[vert_attr][i] * info->v2[0][3];
    116 
    117    float da21 = a1 - a2;
    118    float dadx = da21 * info->dx * info->oneoverarea;
    119    float dady = da21 * info->dy * info->oneoverarea;
    120 
    121    info->dadx[slot][i] = dadx;
    122    info->dady[slot][i] = dady;
    123 
    124    info->a0[slot][i] = (a1 -
    125                         (dadx * (info->v1[0][0] - setup->pixel_offset) +
    126                          dady * (info->v1[0][1] - setup->pixel_offset)));
    127 }
    128 
    129 static void
    130 setup_fragcoord_coef( struct lp_setup_context *setup,
    131                       struct lp_line_info *info,
    132                       unsigned slot,
    133                       unsigned usage_mask)
    134 {
    135    /*X*/
    136    if (usage_mask & TGSI_WRITEMASK_X) {
    137       info->a0[slot][0] = 0.0;
    138       info->dadx[slot][0] = 1.0;
    139       info->dady[slot][0] = 0.0;
    140    }
    141 
    142    /*Y*/
    143    if (usage_mask & TGSI_WRITEMASK_Y) {
    144       info->a0[slot][1] = 0.0;
    145       info->dadx[slot][1] = 0.0;
    146       info->dady[slot][1] = 1.0;
    147    }
    148 
    149    /*Z*/
    150    if (usage_mask & TGSI_WRITEMASK_Z) {
    151       linear_coef(setup, info, slot, 0, 2);
    152    }
    153 
    154    /*W*/
    155    if (usage_mask & TGSI_WRITEMASK_W) {
    156       linear_coef(setup, info, slot, 0, 3);
    157    }
    158 }
    159 
    160 /**
    161  * Compute the tri->coef[] array dadx, dady, a0 values.
    162  */
    163 static void setup_line_coefficients( struct lp_setup_context *setup,
    164                                      struct lp_line_info *info)
    165 {
    166    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
    167    unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
    168    unsigned slot;
    169 
    170    /* setup interpolation for all the remaining attributes:
    171     */
    172    for (slot = 0; slot < key->num_inputs; slot++) {
    173       unsigned vert_attr = key->inputs[slot].src_index;
    174       unsigned usage_mask = key->inputs[slot].usage_mask;
    175       unsigned i;
    176 
    177       switch (key->inputs[slot].interp) {
    178       case LP_INTERP_CONSTANT:
    179          if (key->flatshade_first) {
    180             for (i = 0; i < NUM_CHANNELS; i++)
    181                if (usage_mask & (1 << i))
    182                   constant_coef(setup, info, slot+1, info->v1[vert_attr][i], i);
    183          }
    184          else {
    185             for (i = 0; i < NUM_CHANNELS; i++)
    186                if (usage_mask & (1 << i))
    187                   constant_coef(setup, info, slot+1, info->v2[vert_attr][i], i);
    188          }
    189          break;
    190 
    191       case LP_INTERP_LINEAR:
    192          for (i = 0; i < NUM_CHANNELS; i++)
    193             if (usage_mask & (1 << i))
    194                linear_coef(setup, info, slot+1, vert_attr, i);
    195          break;
    196 
    197       case LP_INTERP_PERSPECTIVE:
    198          for (i = 0; i < NUM_CHANNELS; i++)
    199             if (usage_mask & (1 << i))
    200                perspective_coef(setup, info, slot+1, vert_attr, i);
    201          fragcoord_usage_mask |= TGSI_WRITEMASK_W;
    202          break;
    203 
    204       case LP_INTERP_POSITION:
    205          /*
    206           * The generated pixel interpolators will pick up the coeffs from
    207           * slot 0, so all need to ensure that the usage mask is covers all
    208           * usages.
    209           */
    210          fragcoord_usage_mask |= usage_mask;
    211          break;
    212 
    213       case LP_INTERP_FACING:
    214          for (i = 0; i < NUM_CHANNELS; i++)
    215             if (usage_mask & (1 << i))
    216                constant_coef(setup, info, slot+1, 1.0, i);
    217          break;
    218 
    219       default:
    220          assert(0);
    221       }
    222    }
    223 
    224    /* The internal position input is in slot zero:
    225     */
    226    setup_fragcoord_coef(setup, info, 0,
    227                         fragcoord_usage_mask);
    228 }
    229 
    230 
    231 
    232 static INLINE int subpixel_snap( float a )
    233 {
    234    return util_iround(FIXED_ONE * a);
    235 }
    236 
    237 
    238 /**
    239  * Print line vertex attribs (for debug).
    240  */
    241 static void
    242 print_line(struct lp_setup_context *setup,
    243            const float (*v1)[4],
    244            const float (*v2)[4])
    245 {
    246    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
    247    uint i;
    248 
    249    debug_printf("llvmpipe line\n");
    250    for (i = 0; i < 1 + key->num_inputs; i++) {
    251       debug_printf("  v1[%d]:  %f %f %f %f\n", i,
    252                    v1[i][0], v1[i][1], v1[i][2], v1[i][3]);
    253    }
    254    for (i = 0; i < 1 + key->num_inputs; i++) {
    255       debug_printf("  v2[%d]:  %f %f %f %f\n", i,
    256                    v2[i][0], v2[i][1], v2[i][2], v2[i][3]);
    257    }
    258 }
    259 
    260 
    261 static INLINE boolean sign(float x){
    262    return x >= 0;
    263 }
    264 
    265 
    266 /* Used on positive floats only:
    267  */
    268 static INLINE float fracf(float f)
    269 {
    270    return f - floorf(f);
    271 }
    272 
    273 
    274 
    275 static boolean
    276 try_setup_line( struct lp_setup_context *setup,
    277                const float (*v1)[4],
    278                const float (*v2)[4])
    279 {
    280    struct lp_scene *scene = setup->scene;
    281    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
    282    struct lp_rast_triangle *line;
    283    struct lp_rast_plane *plane;
    284    struct lp_line_info info;
    285    float width = MAX2(1.0, setup->line_width);
    286    struct u_rect bbox;
    287    unsigned tri_bytes;
    288    int x[4];
    289    int y[4];
    290    int i;
    291    int nr_planes = 4;
    292 
    293    /* linewidth should be interpreted as integer */
    294    int fixed_width = util_iround(width) * FIXED_ONE;
    295 
    296    float x_offset=0;
    297    float y_offset=0;
    298    float x_offset_end=0;
    299    float y_offset_end=0;
    300 
    301    float x1diff;
    302    float y1diff;
    303    float x2diff;
    304    float y2diff;
    305    float dx, dy;
    306    float area;
    307 
    308    boolean draw_start;
    309    boolean draw_end;
    310    boolean will_draw_start;
    311    boolean will_draw_end;
    312 
    313    if (0)
    314       print_line(setup, v1, v2);
    315 
    316    if (setup->scissor_test) {
    317       nr_planes = 8;
    318    }
    319    else {
    320       nr_planes = 4;
    321    }
    322 
    323 
    324    dx = v1[0][0] - v2[0][0];
    325    dy = v1[0][1] - v2[0][1];
    326    area = (dx * dx  + dy * dy);
    327    if (area == 0) {
    328       LP_COUNT(nr_culled_tris);
    329       return TRUE;
    330    }
    331 
    332    info.oneoverarea = 1.0f / area;
    333    info.dx = dx;
    334    info.dy = dy;
    335    info.v1 = v1;
    336    info.v2 = v2;
    337 
    338 
    339    /* X-MAJOR LINE */
    340    if (fabsf(dx) >= fabsf(dy)) {
    341       float dydx = dy / dx;
    342 
    343       x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
    344       y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
    345       x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
    346       y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;
    347 
    348       if (y2diff==-0.5 && dy<0){
    349          y2diff = 0.5;
    350       }
    351 
    352       /*
    353        * Diamond exit rule test for starting point
    354        */
    355       if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
    356          draw_start = TRUE;
    357       }
    358       else if (sign(x1diff) == sign(-dx)) {
    359          draw_start = FALSE;
    360       }
    361       else if (sign(-y1diff) != sign(dy)) {
    362          draw_start = TRUE;
    363       }
    364       else {
    365          /* do intersection test */
    366          float yintersect = fracf(v1[0][1]) + x1diff * dydx;
    367          draw_start = (yintersect < 1.0 && yintersect > 0.0);
    368       }
    369 
    370 
    371       /*
    372        * Diamond exit rule test for ending point
    373        */
    374       if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
    375          draw_end = FALSE;
    376       }
    377       else if (sign(x2diff) != sign(-dx)) {
    378          draw_end = FALSE;
    379       }
    380       else if (sign(-y2diff) == sign(dy)) {
    381          draw_end = TRUE;
    382       }
    383       else {
    384          /* do intersection test */
    385          float yintersect = fracf(v2[0][1]) + x2diff * dydx;
    386          draw_end = (yintersect < 1.0 && yintersect > 0.0);
    387       }
    388 
    389       /* Are we already drawing start/end?
    390        */
    391       will_draw_start = sign(-x1diff) != sign(dx);
    392       will_draw_end = (sign(x2diff) == sign(-dx)) || x2diff==0;
    393 
    394       if (dx < 0) {
    395          /* if v2 is to the right of v1, swap pointers */
    396          const float (*temp)[4] = v1;
    397          v1 = v2;
    398          v2 = temp;
    399          dx = -dx;
    400          dy = -dy;
    401          /* Otherwise shift planes appropriately */
    402          if (will_draw_start != draw_start) {
    403             x_offset_end = - x1diff - 0.5;
    404             y_offset_end = x_offset_end * dydx;
    405 
    406          }
    407          if (will_draw_end != draw_end) {
    408             x_offset = - x2diff - 0.5;
    409             y_offset = x_offset * dydx;
    410          }
    411 
    412       }
    413       else{
    414          /* Otherwise shift planes appropriately */
    415          if (will_draw_start != draw_start) {
    416             x_offset = - x1diff + 0.5;
    417             y_offset = x_offset * dydx;
    418          }
    419          if (will_draw_end != draw_end) {
    420             x_offset_end = - x2diff + 0.5;
    421             y_offset_end = x_offset_end * dydx;
    422          }
    423       }
    424 
    425       /* x/y positions in fixed point */
    426       x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
    427       x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
    428       x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
    429       x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
    430 
    431       y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) - fixed_width/2;
    432       y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) - fixed_width/2;
    433       y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) + fixed_width/2;
    434       y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) + fixed_width/2;
    435 
    436    }
    437    else {
    438       const float dxdy = dx / dy;
    439 
    440       /* Y-MAJOR LINE */
    441       x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
    442       y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
    443       x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
    444       y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;
    445 
    446       if (x2diff==-0.5 && dx<0) {
    447          x2diff = 0.5;
    448       }
    449 
    450       /*
    451        * Diamond exit rule test for starting point
    452        */
    453       if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
    454          draw_start = TRUE;
    455       }
    456       else if (sign(-y1diff) == sign(dy)) {
    457          draw_start = FALSE;
    458       }
    459       else if (sign(x1diff) != sign(-dx)) {
    460          draw_start = TRUE;
    461       }
    462       else {
    463          /* do intersection test */
    464          float xintersect = fracf(v1[0][0]) + y1diff * dxdy;
    465          draw_start = (xintersect < 1.0 && xintersect > 0.0);
    466       }
    467 
    468       /*
    469        * Diamond exit rule test for ending point
    470        */
    471       if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
    472          draw_end = FALSE;
    473       }
    474       else if (sign(-y2diff) != sign(dy) ) {
    475          draw_end = FALSE;
    476       }
    477       else if (sign(x2diff) == sign(-dx) ) {
    478          draw_end = TRUE;
    479       }
    480       else {
    481          /* do intersection test */
    482          float xintersect = fracf(v2[0][0]) + y2diff * dxdy;
    483          draw_end = (xintersect < 1.0 && xintersect >= 0.0);
    484       }
    485 
    486       /* Are we already drawing start/end?
    487        */
    488       will_draw_start = sign(y1diff) == sign(dy);
    489       will_draw_end = (sign(-y2diff) == sign(dy)) || y2diff==0;
    490 
    491       if (dy > 0) {
    492          /* if v2 is on top of v1, swap pointers */
    493          const float (*temp)[4] = v1;
    494          v1 = v2;
    495          v2 = temp;
    496          dx = -dx;
    497          dy = -dy;
    498 
    499          /* Otherwise shift planes appropriately */
    500          if (will_draw_start != draw_start) {
    501             y_offset_end = - y1diff + 0.5;
    502             x_offset_end = y_offset_end * dxdy;
    503          }
    504          if (will_draw_end != draw_end) {
    505             y_offset = - y2diff + 0.5;
    506             x_offset = y_offset * dxdy;
    507          }
    508       }
    509       else {
    510          /* Otherwise shift planes appropriately */
    511          if (will_draw_start != draw_start) {
    512             y_offset = - y1diff - 0.5;
    513             x_offset = y_offset * dxdy;
    514 
    515          }
    516          if (will_draw_end != draw_end) {
    517             y_offset_end = - y2diff - 0.5;
    518             x_offset_end = y_offset_end * dxdy;
    519          }
    520       }
    521 
    522       /* x/y positions in fixed point */
    523       x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) - fixed_width/2;
    524       x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) - fixed_width/2;
    525       x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) + fixed_width/2;
    526       x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) + fixed_width/2;
    527 
    528       y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset);
    529       y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
    530       y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
    531       y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset);
    532    }
    533 
    534 
    535 
    536    LP_COUNT(nr_tris);
    537 
    538 
    539    /* Bounding rectangle (in pixels) */
    540    {
    541       /* Yes this is necessary to accurately calculate bounding boxes
    542        * with the two fill-conventions we support.  GL (normally) ends
    543        * up needing a bottom-left fill convention, which requires
    544        * slightly different rounding.
    545        */
    546       int adj = (setup->pixel_offset != 0) ? 1 : 0;
    547 
    548       bbox.x0 = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
    549       bbox.x1 = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
    550       bbox.y0 = (MIN4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
    551       bbox.y1 = (MAX4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
    552 
    553       /* Inclusive coordinates:
    554        */
    555       bbox.x1--;
    556       bbox.y1--;
    557    }
    558 
    559    if (bbox.x1 < bbox.x0 ||
    560        bbox.y1 < bbox.y0) {
    561       if (0) debug_printf("empty bounding box\n");
    562       LP_COUNT(nr_culled_tris);
    563       return TRUE;
    564    }
    565 
    566    if (!u_rect_test_intersection(&setup->draw_region, &bbox)) {
    567       if (0) debug_printf("offscreen\n");
    568       LP_COUNT(nr_culled_tris);
    569       return TRUE;
    570    }
    571 
    572    /* Can safely discard negative regions:
    573     */
    574    bbox.x0 = MAX2(bbox.x0, 0);
    575    bbox.y0 = MAX2(bbox.y0, 0);
    576 
    577    line = lp_setup_alloc_triangle(scene,
    578                                   key->num_inputs,
    579                                   nr_planes,
    580                                   &tri_bytes);
    581    if (!line)
    582       return FALSE;
    583 
    584 #ifdef DEBUG
    585    line->v[0][0] = v1[0][0];
    586    line->v[1][0] = v2[0][0];
    587    line->v[0][1] = v1[0][1];
    588    line->v[1][1] = v2[0][1];
    589 #endif
    590 
    591    /* calculate the deltas */
    592    plane = GET_PLANES(line);
    593    plane[0].dcdy = x[0] - x[1];
    594    plane[1].dcdy = x[1] - x[2];
    595    plane[2].dcdy = x[2] - x[3];
    596    plane[3].dcdy = x[3] - x[0];
    597 
    598    plane[0].dcdx = y[0] - y[1];
    599    plane[1].dcdx = y[1] - y[2];
    600    plane[2].dcdx = y[2] - y[3];
    601    plane[3].dcdx = y[3] - y[0];
    602 
    603 
    604    /* Setup parameter interpolants:
    605     */
    606    info.a0 = GET_A0(&line->inputs);
    607    info.dadx = GET_DADX(&line->inputs);
    608    info.dady = GET_DADY(&line->inputs);
    609    setup_line_coefficients(setup, &info);
    610 
    611    line->inputs.frontfacing = TRUE;
    612    line->inputs.disable = FALSE;
    613    line->inputs.opaque = FALSE;
    614 
    615    for (i = 0; i < 4; i++) {
    616 
    617       /* half-edge constants, will be interated over the whole render
    618        * target.
    619        */
    620       plane[i].c = plane[i].dcdx * x[i] - plane[i].dcdy * y[i];
    621 
    622 
    623       /* correct for top-left vs. bottom-left fill convention.
    624        *
    625        * note that we're overloading gl_rasterization_rules to mean
    626        * both (0.5,0.5) pixel centers *and* bottom-left filling
    627        * convention.
    628        *
    629        * GL actually has a top-left filling convention, but GL's
    630        * notion of "top" differs from gallium's...
    631        *
    632        * Also, sometimes (in FBO cases) GL will render upside down
    633        * to its usual method, in which case it will probably want
    634        * to use the opposite, top-left convention.
    635        */
    636       if (plane[i].dcdx < 0) {
    637          /* both fill conventions want this - adjust for left edges */
    638          plane[i].c++;
    639       }
    640       else if (plane[i].dcdx == 0) {
    641          if (setup->pixel_offset == 0) {
    642             /* correct for top-left fill convention:
    643              */
    644             if (plane[i].dcdy > 0) plane[i].c++;
    645          }
    646          else {
    647             /* correct for bottom-left fill convention:
    648              */
    649             if (plane[i].dcdy < 0) plane[i].c++;
    650          }
    651       }
    652 
    653       plane[i].dcdx *= FIXED_ONE;
    654       plane[i].dcdy *= FIXED_ONE;
    655 
    656       /* find trivial reject offsets for each edge for a single-pixel
    657        * sized block.  These will be scaled up at each recursive level to
    658        * match the active blocksize.  Scaling in this way works best if
    659        * the blocks are square.
    660        */
    661       plane[i].eo = 0;
    662       if (plane[i].dcdx < 0) plane[i].eo -= plane[i].dcdx;
    663       if (plane[i].dcdy > 0) plane[i].eo += plane[i].dcdy;
    664    }
    665 
    666 
    667    /*
    668     * When rasterizing scissored tris, use the intersection of the
    669     * triangle bounding box and the scissor rect to generate the
    670     * scissor planes.
    671     *
    672     * This permits us to cut off the triangle "tails" that are present
    673     * in the intermediate recursive levels caused when two of the
    674     * triangles edges don't diverge quickly enough to trivially reject
    675     * exterior blocks from the triangle.
    676     *
    677     * It's not really clear if it's worth worrying about these tails,
    678     * but since we generate the planes for each scissored tri, it's
    679     * free to trim them in this case.
    680     *
    681     * Note that otherwise, the scissor planes only vary in 'C' value,
    682     * and even then only on state-changes.  Could alternatively store
    683     * these planes elsewhere.
    684     */
    685    if (nr_planes == 8) {
    686       const struct u_rect *scissor = &setup->scissor;
    687 
    688       plane[4].dcdx = -1;
    689       plane[4].dcdy = 0;
    690       plane[4].c = 1-scissor->x0;
    691       plane[4].eo = 1;
    692 
    693       plane[5].dcdx = 1;
    694       plane[5].dcdy = 0;
    695       plane[5].c = scissor->x1+1;
    696       plane[5].eo = 0;
    697 
    698       plane[6].dcdx = 0;
    699       plane[6].dcdy = 1;
    700       plane[6].c = 1-scissor->y0;
    701       plane[6].eo = 1;
    702 
    703       plane[7].dcdx = 0;
    704       plane[7].dcdy = -1;
    705       plane[7].c = scissor->y1+1;
    706       plane[7].eo = 0;
    707    }
    708 
    709    return lp_setup_bin_triangle(setup, line, &bbox, nr_planes);
    710 }
    711 
    712 
    713 static void lp_setup_line( struct lp_setup_context *setup,
    714                            const float (*v0)[4],
    715                            const float (*v1)[4] )
    716 {
    717    if (!try_setup_line( setup, v0, v1 ))
    718    {
    719       if (!lp_setup_flush_and_restart(setup))
    720          return;
    721 
    722       if (!try_setup_line( setup, v0, v1 ))
    723          return;
    724    }
    725 }
    726 
    727 
    728 void lp_setup_choose_line( struct lp_setup_context *setup )
    729 {
    730    setup->line = lp_setup_line;
    731 }
    732 
    733 
    734