Mesa (master): llvmpipe: update line rasterization code to current master

Keith Whitwell keithw at kemper.freedesktop.org
Fri Aug 27 12:14:08 UTC 2010


Module: Mesa
Branch: master
Commit: 3783053fa59fceef59fe0356af5c8dbc095e9adf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3783053fa59fceef59fe0356af5c8dbc095e9adf

Author: Keith Whitwell <keithw at vmware.com>
Date:   Thu Aug 26 20:09:22 2010 +0100

llvmpipe: update line rasterization code to current master

---

 src/gallium/drivers/llvmpipe/lp_rast.h          |    5 +
 src/gallium/drivers/llvmpipe/lp_setup_context.h |   32 +--
 src/gallium/drivers/llvmpipe/lp_setup_line.c    |  531 +++++++++--------------
 src/gallium/drivers/llvmpipe/lp_setup_tri.c     |   33 +-
 4 files changed, 227 insertions(+), 374 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index b4564ef..37b4fdc 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -116,6 +116,11 @@ struct lp_rast_triangle {
    /* inputs for the shader */
    struct lp_rast_shader_inputs inputs;
 
+   /* XXX: temporarily use these additional fields for line
+    * coefficient setup
+    */
+   float dx, dy; 
+
 #ifdef DEBUG
    float v[3][2];
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index a4838d5..97919c0 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -171,26 +171,6 @@ lp_setup_print_vertex(struct lp_setup_context *setup,
                       const char *name,
                       const float (*v)[4]);
 
-/** shared code between lp_setup_line and lp_setup_tri */
-extern lp_rast_cmd lp_rast_tri_tab[]; 
-
-void
-do_triangle_ccw_whole_tile(struct lp_setup_context *setup,
-                           struct lp_scene *scene,
-                           struct lp_rast_triangle *tri,
-                           int x, int y,
-                           boolean opaque,
-                           int *is_blit);
-
-
-void 
-lp_setup_tri_coefficients( struct lp_setup_context *setup,
-                           struct lp_rast_triangle *tri,
-                           float oneoverarea,
-                           const float (*v1)[4],
-                           const float (*v2)[4],
-                           const float (*v3)[4],
-                           boolean frontface);
 
 struct lp_rast_triangle *
 lp_setup_alloc_triangle(struct lp_scene *scene,
@@ -199,14 +179,10 @@ lp_setup_alloc_triangle(struct lp_scene *scene,
                         unsigned *tri_size);
 
 void
-lp_setup_fragcoord_coef(struct lp_setup_context *setup,
-                         struct lp_rast_triangle *tri,
-                         float oneoverarea,
-                         unsigned slot,
-                         const float (*v1)[4],
-                         const float (*v2)[4],
-                         const float (*v3)[4],
-                         unsigned usage_mask);
+lp_setup_bin_triangle( struct lp_setup_context *setup,
+                       struct lp_rast_triangle *tri,
+                       const struct u_rect *bbox,
+                       int nr_planes );
 
 #endif
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index 1566203..ebf000d 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -39,35 +39,6 @@
 #define NUM_CHANNELS 4
 
 
-static const int step_scissor_minx[16] = {
-   0, 1, 0, 1,
-   2, 3, 2, 3,
-   0, 1, 0, 1,
-   2, 3, 2, 3
-};
-
-static const int step_scissor_maxx[16] = {
-    0, -1,  0, -1,
-   -2, -3, -2, -3,
-    0, -1,  0, -1,
-   -2, -3, -2, -3
-};
-
-static const int step_scissor_miny[16] = {
-   0, 0, 1, 1,
-   0, 0, 1, 1,
-   2, 2, 3, 3,
-   2, 2, 3, 3
-};
-
-static const int step_scissor_maxy[16] = {
-    0,  0, -1, -1,
-    0,  0, -1, -1,
-   -2, -2, -3, -3,
-   -2, -2, -3, -3
-};
-
-
 
 /**
  * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
@@ -147,6 +118,40 @@ static void perspective_coef( struct lp_setup_context *setup,
                                dady * (v1[0][1] - setup->pixel_offset)));
 }
 
+static void
+setup_fragcoord_coef( struct lp_setup_context *setup,
+                      struct lp_rast_triangle *tri,
+                      float oneoverarea,
+                      unsigned slot,
+                      const float (*v1)[4],
+                      const float (*v2)[4],
+                      unsigned usage_mask)
+{
+   /*X*/
+   if (usage_mask & TGSI_WRITEMASK_X) {
+      tri->inputs.a0[slot][0] = 0.0;
+      tri->inputs.dadx[slot][0] = 1.0;
+      tri->inputs.dady[slot][0] = 0.0;
+   }
+
+   /*Y*/
+   if (usage_mask & TGSI_WRITEMASK_Y) {
+      tri->inputs.a0[slot][1] = 0.0;
+      tri->inputs.dadx[slot][1] = 0.0;
+      tri->inputs.dady[slot][1] = 1.0;
+   }
+
+   /*Z*/
+   if (usage_mask & TGSI_WRITEMASK_Z) {
+      linear_coef(setup, tri, oneoverarea, slot, v1, v2, 0, 2);
+   }
+
+   /*W*/
+   if (usage_mask & TGSI_WRITEMASK_W) {
+      linear_coef(setup, tri, oneoverarea, slot, v1, v2, 0, 3);
+   }
+}
+
 /**
  * Compute the tri->coef[] array dadx, dady, a0 values.
  */
@@ -209,8 +214,8 @@ static void setup_line_coefficients( struct lp_setup_context *setup,
 
    /* The internal position input is in slot zero:
     */
-   lp_setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v2,
-                            fragcoord_usage_mask);
+   setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2,
+                        fragcoord_usage_mask);
 }
 
 
@@ -248,6 +253,15 @@ static INLINE boolean sign(float x){
 }  
 
 
+/* Used on positive floats only:
+ */
+static INLINE float fracf(float f)
+{
+   return f - floorf(f);
+}
+
+
+
 static void
 lp_setup_line( struct lp_setup_context *setup,
                const float (*v1)[4],
@@ -257,27 +271,26 @@ lp_setup_line( struct lp_setup_context *setup,
    struct lp_rast_triangle *line;
    float oneoverarea;
    float width = MAX2(1.0, setup->line_width);
-   int minx, maxx, miny, maxy;
-   int ix0, ix1, iy0, iy1;
+   struct u_rect bbox;
    unsigned tri_bytes;
    int x[4]; 
    int y[4];
    int i;
    int nr_planes = 4;
-   boolean opaque;
    
    /* linewidth should be interpreted as integer */
    int fixed_width = subpixel_snap(round(width));
 
-   float xdiamond_offset=0;
-   float ydiamond_offset=0;
-   float xdiamond_offset_end=0;
-   float ydiamond_offset_end=0;
+   float x_offset=0;
+   float y_offset=0;
+   float x_offset_end=0;
+   float y_offset_end=0;
       
    float x1diff;
    float y1diff;
    float x2diff;
    float y2diff;
+   float dx, dy;
 
    boolean draw_start;
    boolean draw_end;
@@ -294,32 +307,20 @@ lp_setup_line( struct lp_setup_context *setup,
       nr_planes = 4;
    }
 
-   line = lp_setup_alloc_triangle(scene,
-                                  setup->fs.nr_inputs,
-                                  nr_planes,
-                                  &tri_bytes);
-   if (!line)
-      return;
-
-#ifdef DEBUG
-   line->v[0][0] = v1[0][0];
-   line->v[1][0] = v2[0][0];   
-   line->v[0][1] = v1[0][1];
-   line->v[1][1] = v2[0][1];
-#endif
 
-   line->dx = v1[0][0] - v2[0][0];
-   line->dy = v1[0][1] - v2[0][1];
+   dx = v1[0][0] - v2[0][0];
+   dy = v1[0][1] - v2[0][1];
   
-/* X-MAJOR LINE */
-   if (fabsf(line->dx) >= fabsf(line->dy)) {
+   /* X-MAJOR LINE */
+   if (fabsf(dx) >= fabsf(dy)) {
+      float dydx = dy / dx;
 
       x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
       y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
       x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
       y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;
 
-      if (y2diff==-0.5 && line->dy<0){
+      if (y2diff==-0.5 && dy<0){
          y2diff = 0.5;
       }
       
@@ -329,19 +330,16 @@ lp_setup_line( struct lp_setup_context *setup,
       if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
          draw_start = TRUE;
       }
-      else if (sign(x1diff) == sign(-line->dx)) {
+      else if (sign(x1diff) == sign(-dx)) {
          draw_start = FALSE;
       }
-      else if (sign(-y1diff) != sign(line->dy)) {
+      else if (sign(-y1diff) != sign(dy)) {
          draw_start = TRUE;
       }
       else {
          /* do intersection test */
-         float yintersect = v1[0][1] + x1diff*((float)line->dy/(float)line->dx);
-         if (yintersect < ceil(v1[0][1]) && yintersect > floor(v1[0][1])){
-            draw_start = TRUE;
-         }
-         else draw_start = FALSE;
+         float yintersect = fracf(v1[0][1]) + x1diff * dydx;
+         draw_start = (yintersect < 1.0 && yintersect > 0.0);
       }
 
 
@@ -351,101 +349,95 @@ lp_setup_line( struct lp_setup_context *setup,
       if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
          draw_end = FALSE;
       }
-      else if (sign(x2diff) != sign(-line->dx)) {
+      else if (sign(x2diff) != sign(-dx)) {
          draw_end = FALSE;
       }
-      else if (sign(-y2diff) == sign(line->dy)) {
+      else if (sign(-y2diff) == sign(dy)) {
          draw_end = TRUE;
       }
       else {
          /* do intersection test */
-         float yintersect = v2[0][1] + x2diff*((float)line->dy/(float)line->dx);
-         if (yintersect < ceil(v2[0][1]) && yintersect > floor(v2[0][1])){
-            draw_end = TRUE;
-         }
-         else draw_end = FALSE;
+         float yintersect = fracf(v2[0][1]) + x2diff * dydx;
+         draw_end = (yintersect < 1.0 && yintersect > 0.0);
       }
 
       /* Are we already drawing start/end?
        */
-      will_draw_start = sign(-x1diff) != sign(line->dx);
-      will_draw_end = (sign(x2diff) == sign(-line->dx)) || x2diff==0;
+      will_draw_start = sign(-x1diff) != sign(dx);
+      will_draw_end = (sign(x2diff) == sign(-dx)) || x2diff==0;
 
-      if (line->dx < 0) {
+      if (dx < 0) {
          /* if v2 is to the right of v1, swap pointers */
          const float (*temp)[4] = v1;
          v1 = v2;
          v2 = temp;
-         line->dx = -line->dx;
-         line->dy = -line->dy;
+         dx = -dx;
+         dy = -dy;
          /* Otherwise shift planes appropriately */
          if (will_draw_start != draw_start) {
-            xdiamond_offset_end = - x1diff - 0.5;
-            ydiamond_offset_end = xdiamond_offset_end*(float)line->dy/(float)line->dx;
+            x_offset_end = - x1diff - 0.5;
+            y_offset_end = x_offset_end * dydx;
 
          }
          if (will_draw_end != draw_end) {
-            xdiamond_offset = - x2diff - 0.5;
-            ydiamond_offset = xdiamond_offset*(float)line->dy/(float)line->dx;
+            x_offset = - x2diff - 0.5;
+            y_offset = x_offset * dydx;
          }
 
       }
       else{
          /* Otherwise shift planes appropriately */
          if (will_draw_start != draw_start) {
-            xdiamond_offset = - x1diff + 0.5;
-            ydiamond_offset = xdiamond_offset*(float)line->dy/(float)line->dx;
+            x_offset = - x1diff + 0.5;
+            y_offset = x_offset * dydx;
          }
          if (will_draw_end != draw_end) {
-            xdiamond_offset_end = - x2diff + 0.5;
-            ydiamond_offset_end = xdiamond_offset_end*(float)line->dy/(float)line->dx;
+            x_offset_end = - x2diff + 0.5;
+            y_offset_end = x_offset_end * dydx;
          }
       }
   
       /* x/y positions in fixed point */
-      x[0] = subpixel_snap(v1[0][0] + xdiamond_offset - setup->pixel_offset);
-      x[1] = subpixel_snap(v2[0][0] + xdiamond_offset_end - setup->pixel_offset);
-      x[2] = subpixel_snap(v2[0][0] + xdiamond_offset_end - setup->pixel_offset);
-      x[3] = subpixel_snap(v1[0][0] + xdiamond_offset - setup->pixel_offset);
+      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
+      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
+      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
+      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
       
-      y[0] = subpixel_snap(v1[0][1] + ydiamond_offset - setup->pixel_offset) - fixed_width/2;
-      y[1] = subpixel_snap(v2[0][1] + ydiamond_offset_end - setup->pixel_offset) - fixed_width/2;
-      y[2] = subpixel_snap(v2[0][1] + ydiamond_offset_end - setup->pixel_offset) + fixed_width/2;
-      y[3] = subpixel_snap(v1[0][1] + ydiamond_offset - setup->pixel_offset) + fixed_width/2;
+      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) - fixed_width/2;
+      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) - fixed_width/2;
+      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) + fixed_width/2;
+      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) + fixed_width/2;
       
    }
+   else {
+      const float dxdy = dx / dy;
 
-
-   else{
-/* Y-MAJOR LINE */      
+      /* Y-MAJOR LINE */      
       x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
       y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
       x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
       y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;
 
-      if (x2diff==-0.5 && line->dx<0){
+      if (x2diff==-0.5 && dx<0) {
          x2diff = 0.5;
       }
 
-/* 
- * Diamond exit rule test for starting point 
- */    
+      /* 
+       * Diamond exit rule test for starting point 
+       */    
       if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
          draw_start = TRUE;
       }
-      else if (sign(-y1diff) == sign(line->dy)) {
+      else if (sign(-y1diff) == sign(dy)) {
          draw_start = FALSE;
       }
-      else if (sign(x1diff) != sign(-line->dx)) {
+      else if (sign(x1diff) != sign(-dx)) {
          draw_start = TRUE;
       }
       else {
          /* do intersection test */
-         float xintersect = v1[0][0] + y1diff*((float)line->dx/(float)line->dy);
-         if (xintersect < ceil(v1[0][0]) && xintersect > floor(v1[0][0])){
-            draw_start = TRUE;
-         }
-         else draw_start = FALSE;
+         float xintersect = fracf(v1[0][0]) + y1diff * dxdy;
+         draw_start = (xintersect < 1.0 && xintersect > 0.0);
       }
 
       /* 
@@ -454,82 +446,67 @@ lp_setup_line( struct lp_setup_context *setup,
       if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
          draw_end = FALSE;
       }
-      else if (sign(-y2diff) != sign(line->dy) ) {
+      else if (sign(-y2diff) != sign(dy) ) {
          draw_end = FALSE;
       }
-      else if (sign(x2diff) == sign(-line->dx) ) {
+      else if (sign(x2diff) == sign(-dx) ) {
          draw_end = TRUE;
       }
       else {
          /* do intersection test */
-         float xintersect = v2[0][0] + y2diff*((float)line->dx/(float)line->dy);
-         if (xintersect < ceil(v2[0][0]) && xintersect > floor(v2[0][0])){
-            draw_end = TRUE;
-         }
-         else draw_end = FALSE;
+         float xintersect = fracf(v2[0][0]) + y2diff * dxdy;
+         draw_end = (xintersect < 1.0 && xintersect > 0.0);
       }
 
       /* Are we already drawing start/end?
        */
-      will_draw_start = sign(y1diff) == sign(line->dy);
-      will_draw_end = (sign(-y2diff) == sign(line->dy)) || y2diff==0;
+      will_draw_start = sign(y1diff) == sign(dy);
+      will_draw_end = (sign(-y2diff) == sign(dy)) || y2diff==0;
 
-      if (line->dy > 0) {
+      if (dy > 0) {
          /* if v2 is on top of v1, swap pointers */
          const float (*temp)[4] = v1;
          v1 = v2;
          v2 = temp; 
-         line->dx = -line->dx;
-         line->dy = -line->dy;
+         dx = -dx;
+         dy = -dy;
 
          /* Otherwise shift planes appropriately */
          if (will_draw_start != draw_start) {
-            ydiamond_offset_end = - y1diff + 0.5;
-            xdiamond_offset_end = ydiamond_offset_end*(float)line->dx/(float)line->dy;
+            y_offset_end = - y1diff + 0.5;
+            x_offset_end = y_offset_end * dxdy;
          }
          if (will_draw_end != draw_end) {
-            ydiamond_offset = - y2diff + 0.5;
-            xdiamond_offset = ydiamond_offset*(float)line->dx/(float)line->dy;
+            y_offset = - y2diff + 0.5;
+            x_offset = y_offset * dxdy;
          }
       }
-
-      else{
+      else {
          /* Otherwise shift planes appropriately */
          if (will_draw_start != draw_start) {
-            ydiamond_offset = - y1diff - 0.5;
-            xdiamond_offset = ydiamond_offset*(float)line->dx/(float)line->dy;
+            y_offset = - y1diff - 0.5;
+            x_offset = y_offset * dxdy;
                      
          }
          if (will_draw_end != draw_end) {
-            ydiamond_offset_end = - y2diff - 0.5;
-            xdiamond_offset_end = ydiamond_offset_end*(float)line->dx/(float)line->dy;
+            y_offset_end = - y2diff - 0.5;
+            x_offset_end = y_offset_end * dxdy;
          }
       }
  
       /* x/y positions in fixed point */
-      x[0] = subpixel_snap(v1[0][0] + xdiamond_offset - setup->pixel_offset) - fixed_width/2;
-      x[1] = subpixel_snap(v2[0][0] + xdiamond_offset_end - setup->pixel_offset) - fixed_width/2;
-      x[2] = subpixel_snap(v2[0][0] + xdiamond_offset_end - setup->pixel_offset) + fixed_width/2;
-      x[3] = subpixel_snap(v1[0][0] + xdiamond_offset - setup->pixel_offset) + fixed_width/2;
+      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) - fixed_width/2;
+      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) - fixed_width/2;
+      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) + fixed_width/2;
+      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) + fixed_width/2;
      
-      y[0] = subpixel_snap(v1[0][1] + ydiamond_offset - setup->pixel_offset); 
-      y[1] = subpixel_snap(v2[0][1] + ydiamond_offset_end - setup->pixel_offset);
-      y[2] = subpixel_snap(v2[0][1] + ydiamond_offset_end - setup->pixel_offset);
-      y[3] = subpixel_snap(v1[0][1] + ydiamond_offset - setup->pixel_offset);
+      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset); 
+      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
+      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
+      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset);
    }
 
 
-   /* calculate the deltas */
-   line->plane[0].dcdy = x[0] - x[1];
-   line->plane[1].dcdy = x[1] - x[2];
-   line->plane[2].dcdy = x[2] - x[3];
-   line->plane[3].dcdy = x[3] - x[0];
-
-   line->plane[0].dcdx = y[0] - y[1];
-   line->plane[1].dcdx = y[1] - y[2];
-   line->plane[2].dcdx = y[2] - y[3];
-   line->plane[3].dcdx = y[3] - y[0];
-
 
    LP_COUNT(nr_tris);
 
@@ -543,37 +520,70 @@ lp_setup_line( struct lp_setup_context *setup,
        */
       int adj = (setup->pixel_offset != 0) ? 1 : 0;
 
-      minx = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
-      maxx = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
-      miny = (MIN4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
-      maxy = (MAX4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
+      bbox.x0 = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
+      bbox.x1 = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
+      bbox.y0 = (MIN4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
+      bbox.y1 = (MAX4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
+
+      /* Inclusive coordinates:
+       */
+      bbox.x1--;
+      bbox.y1--;
    }
 
-   if (setup->scissor_test) {
-      minx = MAX2(minx, setup->scissor.current.minx);
-      maxx = MIN2(maxx, setup->scissor.current.maxx);
-      miny = MAX2(miny, setup->scissor.current.miny);
-      maxy = MIN2(maxy, setup->scissor.current.maxy);
+   if (bbox.x1 < bbox.x0 ||
+       bbox.y1 < bbox.y0) {
+      if (0) debug_printf("empty bounding box\n");
+      LP_COUNT(nr_culled_tris);
+      return;
    }
-   else {
-      minx = MAX2(minx, 0);
-      miny = MAX2(miny, 0);
-      maxx = MIN2(maxx, scene->fb.width);
-      maxy = MIN2(maxy, scene->fb.height);
+
+   if (!u_rect_test_intersection(&setup->draw_region, &bbox)) {
+      if (0) debug_printf("offscreen\n");
+      LP_COUNT(nr_culled_tris);
+      return;
    }
 
+   u_rect_find_intersection(&setup->draw_region, &bbox);
 
-   if (miny >= maxy || minx >= maxx) {
-      lp_scene_putback_data( scene, tri_bytes );
+   line = lp_setup_alloc_triangle(scene,
+                                  setup->fs.nr_inputs,
+                                  nr_planes,
+                                  &tri_bytes);
+   if (!line)
       return;
-   }
 
-   oneoverarea = 1.0f / (line->dx * line->dx  + line->dy * line->dy);    
+#ifdef DEBUG
+   line->v[0][0] = v1[0][0];
+   line->v[1][0] = v2[0][0];   
+   line->v[0][1] = v1[0][1];
+   line->v[1][1] = v2[0][1];
+#endif
+
+   line->dx = dx;
+   line->dy = dy;
+
+   /* calculate the deltas */
+   line->plane[0].dcdy = x[0] - x[1];
+   line->plane[1].dcdy = x[1] - x[2];
+   line->plane[2].dcdy = x[2] - x[3];
+   line->plane[3].dcdy = x[3] - x[0];
+
+   line->plane[0].dcdx = y[0] - y[1];
+   line->plane[1].dcdx = y[1] - y[2];
+   line->plane[2].dcdx = y[2] - y[3];
+   line->plane[3].dcdx = y[3] - y[0];
+
+
+   oneoverarea = 1.0f / (dx * dx  + dy * dy);    
 
    /* Setup parameter interpolants:
     */
    setup_line_coefficients( setup, line, oneoverarea, v1, v2); 
 
+   line->inputs.facing = 1.0F;
+   line->inputs.state = setup->fs.stored;
+
    for (i = 0; i < 4; i++) {
       struct lp_rast_plane *plane = &line->plane[i];
 
@@ -628,35 +638,6 @@ lp_setup_line( struct lp_setup_context *setup,
       /* Calculate trivial accept offsets from the above.
        */
       plane->ei = plane->dcdy - plane->dcdx - plane->eo;
-
-      plane->step = line->step[i];
-
-      /* Fill in the inputs.step[][] arrays.
-       * We've manually unrolled some loops here.
-       */
-#define SETUP_STEP(j, x, y) \
-      line->step[i][j] = y * plane->dcdy - x * plane->dcdx                                     
-      
-      SETUP_STEP(0, 0, 0);
-      SETUP_STEP(1, 1, 0);
-      SETUP_STEP(2, 0, 1);
-      SETUP_STEP(3, 1, 1);
-
-      SETUP_STEP(4, 2, 0);
-      SETUP_STEP(5, 3, 0);
-      SETUP_STEP(6, 2, 1);
-      SETUP_STEP(7, 3, 1);
-
-      SETUP_STEP(8, 0, 2);
-      SETUP_STEP(9, 1, 2);
-      SETUP_STEP(10, 0, 3);
-      SETUP_STEP(11, 1, 3);
-
-      SETUP_STEP(12, 2, 2);
-      SETUP_STEP(13, 3, 2);
-      SETUP_STEP(14, 2, 3);
-      SETUP_STEP(15, 3, 3);
-#undef STEP
    }
 
 
@@ -679,154 +660,34 @@ lp_setup_line( struct lp_setup_context *setup,
     * these planes elsewhere.
     */
    if (nr_planes == 8) {
-      line->plane[4].step = step_scissor_maxx;
-      line->plane[4].dcdx = 1;
+      line->plane[4].dcdx = -1;
       line->plane[4].dcdy = 0;
-      line->plane[4].c = maxx;
-      line->plane[4].ei = -1;
-      line->plane[4].eo = 0;
-
-      line->plane[5].step = step_scissor_miny;
-      line->plane[5].dcdx = 0;
-      line->plane[5].dcdy = 1;
-      line->plane[5].c = 1-miny;
-      line->plane[5].ei = 0;
-      line->plane[5].eo = 1;
-
-      line->plane[6].step = step_scissor_maxy;
-      line->plane[6].dcdx = 0;
-      line->plane[6].dcdy = -1;
-      line->plane[6].c = maxy;
-      line->plane[6].ei = -1;
-      line->plane[6].eo = 0;
-
-      line->plane[7].step = step_scissor_minx;
-      line->plane[7].dcdx = -1;
-      line->plane[7].dcdy = 0;
-      line->plane[7].c = 1-minx;
-      line->plane[7].ei = 0;
-      line->plane[7].eo = 1;
-   }
-
+      line->plane[4].c = 1-bbox.x0;
+      line->plane[4].ei = 0;
+      line->plane[4].eo = 1;
 
-   /*
-    * All fields of 'line' are now set.  The remaining code here is
-    * concerned with binning.
-    */
+      line->plane[5].dcdx = 1;
+      line->plane[5].dcdy = 0;
+      line->plane[5].c = bbox.x1+1;
+      line->plane[5].ei = -1;
+      line->plane[5].eo = 0;
 
-   /* Convert to tile coordinates, and inclusive ranges:
-    */
-   ix0 = minx / TILE_SIZE;
-   iy0 = miny / TILE_SIZE;
-   ix1 = (maxx-1) / TILE_SIZE;
-   iy1 = (maxy-1) / TILE_SIZE;
-
-   /*
-    * Clamp to framebuffer size
-    */
-   assert(ix0 == MAX2(ix0, 0));
-   assert(iy0 == MAX2(iy0, 0));
-   assert(ix1 == MIN2(ix1, scene->tiles_x - 1));
-   assert(iy1 == MIN2(iy1, scene->tiles_y - 1));
-
-   /* Determine which tile(s) intersect the triangle's bounding box
-    */
-   if (iy0 == iy1 && ix0 == ix1)
-   {
-      /* Triangle is contained in a single tile:
-       */
-      lp_scene_bin_command( scene, ix0, iy0,
-                            lp_rast_tri_tab[nr_planes], 
-                            lp_rast_arg_triangle(line, (1<<nr_planes)-1) );
+      line->plane[6].dcdx = 0;
+      line->plane[6].dcdy = 1;
+      line->plane[6].c = 1-bbox.y0;
+      line->plane[6].ei = 0;
+      line->plane[6].eo = 1;
+
+      line->plane[7].dcdx = 0;
+      line->plane[7].dcdy = -1;
+      line->plane[7].c = bbox.y1+1;
+      line->plane[7].ei = -1;
+      line->plane[7].eo = 0;
    }
-   else
-   {
-      int c[8];
-      int ei[8];
-      int eo[8];
-      int xstep[8];
-      int ystep[8];
-      int x, y;
-      int is_blit = -1; /* undetermined */
-      
-      for (i = 0; i < nr_planes; i++) {
-         c[i] = (line->plane[i].c + 
-                 line->plane[i].dcdy * iy0 * TILE_SIZE - 
-                 line->plane[i].dcdx * ix0 * TILE_SIZE);
-
-         ei[i] = line->plane[i].ei << TILE_ORDER;
-         eo[i] = line->plane[i].eo << TILE_ORDER;
-         xstep[i] = -(line->plane[i].dcdx << TILE_ORDER);
-         ystep[i] = line->plane[i].dcdy << TILE_ORDER;
-      }
-
 
-
-      /* Test tile-sized blocks against the triangle.
-       * Discard blocks fully outside the tri.  If the block is fully
-       * contained inside the tri, bin an lp_rast_shade_tile command.
-       * Else, bin a lp_rast_triangle command.
-       */
-      for (y = iy0; y <= iy1; y++)
-      {
-         boolean in = FALSE;  /* are we inside the triangle? */
-         int cx[8];
-
-         for (i = 0; i < nr_planes; i++)
-            cx[i] = c[i];
-
-         for (x = ix0; x <= ix1; x++)
-         {
-            int out = 0;
-            int partial = 0;
-
-            for (i = 0; i < nr_planes; i++) {
-               int planeout = cx[i] + eo[i];
-               int planepartial = cx[i] + ei[i] - 1;
-               out |= (planeout >> 31);
-               partial |= (planepartial >> 31) & (1<<i);      
-            }
-            if (out) {
-               /* do nothing */
-               if (in)
-                  break;  /* exiting triangle, all done with this row */
-               LP_COUNT(nr_empty_64);
-            }
-            else if (partial) {
-               /* Not trivially accepted by at least one plane - 
-                * rasterize/shade partial tile
-                */
-               int count = util_bitcount(partial);
-               in = TRUE;
-               lp_scene_bin_command( scene, x, y,
-                                     lp_rast_tri_tab[count], 
-                                     lp_rast_arg_triangle(line, partial) );
-
-               LP_COUNT(nr_partially_covered_64);
-            }
-            else {
-               /* triangle covers the whole tile- shade whole tile */
-               LP_COUNT(nr_fully_covered_64);
-               in = TRUE;
-               /* leverages on existing code in lp_setup_tri.c */ 
-               do_triangle_ccw_whole_tile(setup, scene, line, x, y,
-                                          opaque, &is_blit);
-            }
-
-            /* Iterate cx values across the region:
-             */
-            for (i = 0; i < nr_planes; i++)
-               cx[i] += xstep[i];
-         }
-      
-         /* Iterate c values down the region:
-          */
-         for (i = 0; i < nr_planes; i++)
-            c[i] += ystep[i];
-      }
-   }
+   lp_setup_bin_triangle(setup, line, &bbox, nr_planes);
 }
-
+   
 
 void lp_setup_choose_line( struct lp_setup_context *setup ) 
 { 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 212bb3a..0180d95 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -184,9 +184,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
 		const float (*v2)[4],
 		boolean frontfacing )
 {
-
    struct lp_scene *scene = lp_setup_get_current_scene(setup);
-   struct lp_fragment_shader_variant *variant = setup->fs.current.variant;
    struct lp_rast_triangle *tri;
    int x[3];
    int y[3];
@@ -196,7 +194,6 @@ do_triangle_ccw(struct lp_setup_context *setup,
    struct lp_tri_info info;
    int area;
    struct u_rect bbox;
-   int ix0, ix1, iy0, iy1;
    unsigned tri_bytes;
    int i;
    int nr_planes = 3;
@@ -423,6 +420,20 @@ do_triangle_ccw(struct lp_setup_context *setup,
       tri->plane[6].eo = 0;
    }
 
+   lp_setup_bin_triangle( setup, tri, &bbox, nr_planes );
+}
+
+
+void
+lp_setup_bin_triangle( struct lp_setup_context *setup,
+                       struct lp_rast_triangle *tri,
+                       const struct u_rect *bbox,
+                       int nr_planes )
+{
+   struct lp_scene *scene = setup->scene;
+   struct lp_fragment_shader_variant *variant = setup->fs.current.variant;
+   int ix0, ix1, iy0, iy1;
+   int i;
 
    /*
     * All fields of 'tri' are now set.  The remaining code here is
@@ -432,10 +443,10 @@ do_triangle_ccw(struct lp_setup_context *setup,
    /* Convert to tile coordinates, and inclusive ranges:
     */
    if (nr_planes == 3) {
-      int ix0 = bbox.x0 / 16;
-      int iy0 = bbox.y0 / 16;
-      int ix1 = bbox.x1 / 16;
-      int iy1 = bbox.y1 / 16;
+      int ix0 = bbox->x0 / 16;
+      int iy0 = bbox->y0 / 16;
+      int ix1 = bbox->x1 / 16;
+      int iy1 = bbox->y1 / 16;
       
       if (iy0 == iy1 && ix0 == ix1)
       {
@@ -451,10 +462,10 @@ do_triangle_ccw(struct lp_setup_context *setup,
       }
    }
 
-   ix0 = bbox.x0 / TILE_SIZE;
-   iy0 = bbox.y0 / TILE_SIZE;
-   ix1 = bbox.x1 / TILE_SIZE;
-   iy1 = bbox.y1 / TILE_SIZE;
+   ix0 = bbox->x0 / TILE_SIZE;
+   iy0 = bbox->y0 / TILE_SIZE;
+   ix1 = bbox->x1 / TILE_SIZE;
+   iy1 = bbox->y1 / TILE_SIZE;
 
    /*
     * Clamp to framebuffer size




More information about the mesa-commit mailing list