llvmpipe: Fix the 4 planes (lines) case properly.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 5 Oct 2011 12:27:08 +0000 (13:27 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 5 Oct 2011 17:07:05 +0000 (18:07 +0100)
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.

src/gallium/drivers/llvmpipe/lp_rast.h
src/gallium/drivers/llvmpipe/lp_setup_tri.c

index a64c152cf8317164292e7eee36475a8f444bcb6e..49da41f0e5e2d789721c062eb4edfedfb871e633 100644 (file)
@@ -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 )
 {
index 1737d1dbacf301260a3ba104383c3423d44c7d52..b50c354fa9bffb0223f12b9f8152f8e03a2a6dfb 100644 (file)
@@ -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));
       }