summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2011-10-05 13:27:08 +0100
committerJosé Fonseca <[email protected]>2011-10-05 18:07:05 +0100
commite2072a1046039403d814613553e7b3b563d43dfc (patch)
tree6b3eaca75fd515731540860e73c4f33da1329aa6 /src/gallium/drivers/llvmpipe
parentc620087432b2055aa9301f19f8b6444080698c90 (diff)
llvmpipe: Fix the 4 planes (lines) case properly.
The previous change was not effective for lines, because there is no 4 planes 4x4 block rasterization path: it is handled by the 16x16 block case too, and the 16x16 block was not being budged as it should. This fixes assertion failures on line rasterization.
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c33
2 files changed, 33 insertions, 16 deletions
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));
}