diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index a64c152cf83..49da41f0e5e 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -183,6 +183,22 @@ lp_rast_arg_triangle( const struct lp_rast_triangle *triangle, return arg; } +/** + * Build argument for a contained triangle. + * + * All planes are enabled, so instead of the plane mask we pass the upper + * left coordinates of the a block that fully encloses the triangle. + */ +static INLINE union lp_rast_cmd_arg +lp_rast_arg_triangle_contained( const struct lp_rast_triangle *triangle, + unsigned x, unsigned y) +{ + union lp_rast_cmd_arg arg; + arg.triangle.tri = triangle; + arg.triangle.plane_mask = x | (y << 8); + return arg; +} + static INLINE union lp_rast_cmd_arg lp_rast_arg_state( const struct lp_rast_state *state ) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 1737d1dbacf..b50c354fa9b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -595,23 +595,10 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int iy0 = bbox->y0 / TILE_SIZE; unsigned px = bbox->x0 & 63 & ~3; unsigned py = bbox->y0 & 63 & ~3; - unsigned mask; assert(iy0 == bbox->y1 / TILE_SIZE && ix0 == bbox->x1 / TILE_SIZE); - if (4 <= sz && sz < 16) { - /* - * 16x16 block is only 4x4 aligned, and can exceed the tile dimensions - * if the triangle is 16 pixels in one dimension but 4 in the other. - * So budge the 16x16 back inside the tile. - */ - px = MIN2(px, TILE_SIZE - 16); - py = MIN2(py, TILE_SIZE - 16); - } - - mask = px | (py << 8); - if (nr_planes == 3) { if (sz < 4) { @@ -622,29 +609,43 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, return lp_scene_bin_cmd_with_state( scene, ix0, iy0, setup->fs.stored, LP_RAST_OP_TRIANGLE_3_4, - lp_rast_arg_triangle(tri, mask) ); + lp_rast_arg_triangle_contained(tri, px, py) ); } if (sz < 16) { /* Triangle is contained in a single 16x16 block: */ + + /* + * The 16x16 block is only 4x4 aligned, and can exceed the tile + * dimensions if the triangle is 16 pixels in one dimension but 4 + * in the other. So budge the 16x16 back inside the tile. + */ + px = MIN2(px, TILE_SIZE - 16); + py = MIN2(py, TILE_SIZE - 16); + assert(px + 16 <= TILE_SIZE); assert(py + 16 <= TILE_SIZE); + return lp_scene_bin_cmd_with_state( scene, ix0, iy0, setup->fs.stored, LP_RAST_OP_TRIANGLE_3_16, - lp_rast_arg_triangle(tri, mask) ); + lp_rast_arg_triangle_contained(tri, px, py) ); } } else if (nr_planes == 4 && sz < 16) { + px = MIN2(px, TILE_SIZE - 16); + py = MIN2(py, TILE_SIZE - 16); + assert(px + 16 <= TILE_SIZE); assert(py + 16 <= TILE_SIZE); + return lp_scene_bin_cmd_with_state(scene, ix0, iy0, setup->fs.stored, LP_RAST_OP_TRIANGLE_4_16, - lp_rast_arg_triangle(tri, mask) ); + lp_rast_arg_triangle_contained(tri, px, py)); }