diff options
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 11 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_line.c | 20 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_point.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_tri.c | 41 |
4 files changed, 43 insertions, 31 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 97146912704..4b55fd922c8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -215,10 +215,11 @@ lp_setup_alloc_triangle(struct lp_scene *scene, unsigned *tri_size); boolean -lp_setup_bin_triangle( struct lp_setup_context *setup, - struct lp_rast_triangle *tri, - const struct u_rect *bbox, - int nr_planes, - unsigned scissor_index ); +lp_setup_bin_triangle(struct lp_setup_context *setup, + struct lp_rast_triangle *tri, + const struct u_rect *bboxorig, + const struct u_rect *bbox, + int nr_planes, + unsigned scissor_index); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index 018130c3192..d0bac5efb99 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -288,7 +288,9 @@ try_setup_line( struct lp_setup_context *setup, struct lp_rast_plane *plane; struct lp_line_info info; float width = MAX2(1.0, setup->line_width); - struct u_rect bbox; + const struct u_rect *scissor; + struct u_rect bbox, bboxpos; + boolean s_planes[4]; unsigned tri_bytes; int x[4]; int y[4]; @@ -579,10 +581,12 @@ try_setup_line( struct lp_setup_context *setup, return TRUE; } + bboxpos = bbox; + /* Can safely discard negative regions: */ - bbox.x0 = MAX2(bbox.x0, 0); - bbox.y0 = MAX2(bbox.y0, 0); + bboxpos.x0 = MAX2(bboxpos.x0, 0); + bboxpos.y0 = MAX2(bboxpos.y0, 0); nr_planes = 4; /* @@ -591,8 +595,8 @@ try_setup_line( struct lp_setup_context *setup, */ if (setup->scissor_test) { /* why not just use draw_regions */ - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, &setup->scissors[viewport_index]); + scissor = &setup->scissors[viewport_index]; + scissor_planes_needed(s_planes, &bboxpos, scissor); nr_planes += s_planes[0] + s_planes[1] + s_planes[2] + s_planes[3]; } @@ -718,11 +722,7 @@ try_setup_line( struct lp_setup_context *setup, * (easier to evaluate) to ordinary planes.) */ if (nr_planes > 4) { - /* why not just use draw_regions */ - const struct u_rect *scissor = &setup->scissors[viewport_index]; struct lp_rast_plane *plane_s = &plane[4]; - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, scissor); if (s_planes[0]) { plane_s->dcdx = -1 << 8; @@ -755,7 +755,7 @@ try_setup_line( struct lp_setup_context *setup, assert(plane_s == &plane[nr_planes]); } - return lp_setup_bin_triangle(setup, line, &bbox, nr_planes, viewport_index); + return lp_setup_bin_triangle(setup, line, &bbox, &bboxpos, nr_planes, viewport_index); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index ddb6f0e73b0..8cb6b83f916 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -513,7 +513,7 @@ try_setup_point( struct lp_setup_context *setup, plane[3].eo = 0; } - return lp_setup_bin_triangle(setup, point, &bbox, nr_planes, viewport_index); + return lp_setup_bin_triangle(setup, point, &bbox, &bbox, nr_planes, viewport_index); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 324e93841f7..39755d6b581 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -273,7 +273,9 @@ do_triangle_ccw(struct lp_setup_context *setup, const struct lp_setup_variant_key *key = &setup->setup.variant->key; struct lp_rast_triangle *tri; struct lp_rast_plane *plane; - struct u_rect bbox; + const struct u_rect *scissor; + struct u_rect bbox, bboxpos; + boolean s_planes[4]; unsigned tri_bytes; int nr_planes = 3; unsigned viewport_index = 0; @@ -332,12 +334,14 @@ do_triangle_ccw(struct lp_setup_context *setup, return TRUE; } + bboxpos = bbox; + /* Can safely discard negative regions, but need to keep hold of * information about when the triangle extends past screen * boundaries. See trimmed_box in lp_setup_bin_triangle(). */ - bbox.x0 = MAX2(bbox.x0, 0); - bbox.y0 = MAX2(bbox.y0, 0); + bboxpos.x0 = MAX2(bboxpos.x0, 0); + bboxpos.y0 = MAX2(bboxpos.y0, 0); nr_planes = 3; /* @@ -346,8 +350,8 @@ do_triangle_ccw(struct lp_setup_context *setup, */ if (setup->scissor_test) { /* why not just use draw_regions */ - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, &setup->scissors[viewport_index]); + scissor = &setup->scissors[viewport_index]; + scissor_planes_needed(s_planes, &bboxpos, scissor); nr_planes += s_planes[0] + s_planes[1] + s_planes[2] + s_planes[3]; } @@ -680,10 +684,7 @@ do_triangle_ccw(struct lp_setup_context *setup, */ if (nr_planes > 3) { /* why not just use draw_regions */ - const struct u_rect *scissor = &setup->scissors[viewport_index]; struct lp_rast_plane *plane_s = &plane[3]; - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, scissor); if (s_planes[0]) { plane_s->dcdx = -1 << 8; @@ -716,7 +717,7 @@ do_triangle_ccw(struct lp_setup_context *setup, assert(plane_s == &plane[nr_planes]); } - return lp_setup_bin_triangle(setup, tri, &bbox, nr_planes, viewport_index); + return lp_setup_bin_triangle(setup, tri, &bbox, &bboxpos, nr_planes, viewport_index); } /* @@ -747,11 +748,12 @@ floor_pot(uint32_t n) boolean -lp_setup_bin_triangle( struct lp_setup_context *setup, - struct lp_rast_triangle *tri, - const struct u_rect *bbox, - int nr_planes, - unsigned viewport_index ) +lp_setup_bin_triangle(struct lp_setup_context *setup, + struct lp_rast_triangle *tri, + const struct u_rect *bboxorig, + const struct u_rect *bbox, + int nr_planes, + unsigned viewport_index) { struct lp_scene *scene = setup->scene; struct u_rect trimmed_box = *bbox; @@ -767,7 +769,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int max_sz = ((bbox->x1 - (bbox->x0 & ~3)) | (bbox->y1 - (bbox->y0 & ~3))); int sz = floor_pot(max_sz); - boolean use_32bits = max_sz <= MAX_FIXED_LENGTH32; + + /* + * NOTE: It is important to use the original bounding box + * which might contain negative values here, because if the + * plane math may overflow or not with the 32bit rasterization + * functions depends on the original extent of the triangle. + */ + int max_szorig = ((bboxorig->x1 - (bboxorig->x0 & ~3)) | + (bboxorig->y1 - (bboxorig->y0 & ~3))); + boolean use_32bits = max_szorig <= MAX_FIXED_LENGTH32; /* Now apply scissor, etc to the bounding box. Could do this * earlier, but it confuses the logic for tri-16 and would force |