From: Keith Whitwell Date: Thu, 26 Aug 2010 19:09:22 +0000 (+0100) Subject: llvmpipe: update line rasterization code to current master X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3783053fa59fceef59fe0356af5c8dbc095e9adf;p=mesa.git llvmpipe: update line rasterization code to current master --- diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index b4564ef33bd..37b4fdc31e8 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 a4838d59a5c..97919c09d4e 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 15662031178..ebf000dd19e 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<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<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