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