Mesa (master): llvmpipe: allow tri_3_16 at any 4-aligned location within a tile

Keith Whitwell keithw at kemper.freedesktop.org
Sun Sep 12 14:08:00 UTC 2010


Module: Mesa
Branch: master
Commit: 4b56e86e67d281b1c57f1f5e6b1a686d0dcd6ebb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4b56e86e67d281b1c57f1f5e6b1a686d0dcd6ebb

Author: Keith Whitwell <keithw at vmware.com>
Date:   Tue Sep  7 23:10:11 2010 +0100

llvmpipe: allow tri_3_16 at any 4-aligned location within a tile

Doesn't require 16-alignment, so catch more cases.

---

 src/gallium/drivers/llvmpipe/lp_setup_tri.c |   77 +++++++++++++++++---------
 1 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 72c0a9c..d4ef8f4 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -439,6 +439,32 @@ do_triangle_ccw(struct lp_setup_context *setup,
    return lp_setup_bin_triangle( setup, tri, &bbox, nr_planes );
 }
 
+/*
+ * __fls: find last set bit in word
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#if defined(PIPE_ARCH_X86)
+static inline unsigned fls(unsigned word)
+{
+        asm("bsr %1,%0"
+            : "=r" (word)
+            : "rm" (word));
+        return word;
+}
+#else
+static inline unsigned fls(unsigned n)
+{
+    n |= (n >>  1);
+    n |= (n >>  2);
+    n |= (n >>  4);
+    n |= (n >>  8);
+    n |= (n >> 16);
+    return n - (n >> 1);
+}
+#endif
+
 
 boolean
 lp_setup_bin_triangle( struct lp_setup_context *setup,
@@ -447,52 +473,44 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
                        int nr_planes )
 {
    struct lp_scene *scene = setup->scene;
-   int ix0, ix1, iy0, iy1;
    int i;
 
-   /*
-    * All fields of 'tri' are now set.  The remaining code here is
-    * concerned with binning.
+   /* What is the largest power-of-two boundary this triangle crosses:
     */
+   int dx = 1 << fls((bbox->x0 ^ bbox->x1) |
+		     (bbox->y0 ^ bbox->y1));
 
-   /* Convert to tile coordinates, and inclusive ranges:
+   /* The largest dimension of the rasterized area of the triangle
+    * (aligned to a 4x4 grid), rounded up to the next power of two:
     */
+   int sz = 1 << fls((bbox->x1 - (bbox->x0 & ~3)) |
+		     (bbox->y1 - (bbox->y0 & ~3)));
+
    if (nr_planes == 3) {
-      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)
+      if (sz < 16 && dx < 64)
       {
+	 int mask = (bbox->x0 & 63 & ~3) | ((bbox->y0 & 63 & ~3) << 8);
 
 	 /* Triangle is contained in a single 16x16 block:
 	  */
-	 int mask = (ix0 & 3) | ((iy0 & 3) << 4);
-
-	 return lp_scene_bin_command( scene, ix0/4, iy0/4,
+	 return lp_scene_bin_command( scene,
+				      bbox->x0/64, bbox->y0/64,
                                       LP_RAST_OP_TRIANGLE_3_16,
                                       lp_rast_arg_triangle(tri, mask) );
       }
    }
 
-   ix0 = bbox->x0 / TILE_SIZE;
-   iy0 = bbox->y0 / TILE_SIZE;
-   ix1 = bbox->x1 / TILE_SIZE;
-   iy1 = bbox->y1 / 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)
+   if (dx < TILE_SIZE)
    {
+      int ix0 = bbox->x0 / TILE_SIZE;
+      int iy0 = bbox->y0 / TILE_SIZE;
+
+      assert(iy0 == bbox->y1 / TILE_SIZE &&
+	     ix0 == bbox->x1 / TILE_SIZE);
+
       /* Triangle is contained in a single tile:
        */
       return lp_scene_bin_command( scene, ix0, iy0,
@@ -507,6 +525,11 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
       int xstep[7];
       int ystep[7];
       int x, y;
+
+      int ix0 = bbox->x0 / TILE_SIZE;
+      int iy0 = bbox->y0 / TILE_SIZE;
+      int ix1 = bbox->x1 / TILE_SIZE;
+      int iy1 = bbox->y1 / TILE_SIZE;
       
       for (i = 0; i < nr_planes; i++) {
          c[i] = (tri->plane[i].c + 




More information about the mesa-commit mailing list