diff options
Diffstat (limited to 'src/gallium/drivers')
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.h | 5 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 32 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_line.c | 527 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_tri.c | 33 | 
4 files changed, 225 insertions, 372 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index b4564ef33b..37b4fdc31e 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 a4838d59a5..97919c09d4 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 1566203117..ebf000dd19 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[4].c = 1-bbox.x0; +      line->plane[4].ei = 0; +      line->plane[4].eo = 1; -      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[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; -      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[6].dcdy = 1; +      line->plane[6].c = 1-bbox.y0; +      line->plane[6].ei = 0; +      line->plane[6].eo = 1; -      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[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;     } - -   /* -    * All fields of 'line' are now set.  The remaining code here is -    * concerned with binning. -    */ - -   /* 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) ); -   } -   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 212bb3ab90..0180d95090 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  | 
