llvmpipe: avoid generating tri_16 for tris which extend past tile bounds
authorKeith Whitwell <keithw@vmware.com>
Tue, 2 Nov 2010 14:20:20 +0000 (14:20 +0000)
committerKeith Whitwell <keithw@vmware.com>
Tue, 2 Nov 2010 16:48:10 +0000 (16:48 +0000)
Don't trim triangle bounding box to scissor/draw-region until after
the logic for emitting tri_16.  Don't generate tri_16 commands for
triangles with untrimmed bounding boxes outside the current tile.

This is important as the tri-16 itself can extend past tile bounds and
we don't want to add code to it to check against tile bounds (slow) or
restrict it to locations within a tile (pessimistic).

src/gallium/drivers/llvmpipe/lp_setup_line.c
src/gallium/drivers/llvmpipe/lp_setup_tri.c

index 827413bb33ecdb9114c73234c8c8ff6ec3da7b57..29c231714e186a5d44a152a8042631d44bcc7a53 100644 (file)
@@ -569,7 +569,10 @@ try_setup_line( struct lp_setup_context *setup,
       return TRUE;
    }
 
       return TRUE;
    }
 
-   u_rect_find_intersection(&setup->draw_region, &bbox);
+   /* Can safely discard negative regions:
+    */
+   bbox.x0 = MAX2(bbox.x0, 0);
+   bbox.y0 = MAX2(bbox.y0, 0);
 
    line = lp_setup_alloc_triangle(scene,
                                   key->num_inputs,
 
    line = lp_setup_alloc_triangle(scene,
                                   key->num_inputs,
@@ -680,24 +683,26 @@ try_setup_line( struct lp_setup_context *setup,
     * these planes elsewhere.
     */
    if (nr_planes == 8) {
     * these planes elsewhere.
     */
    if (nr_planes == 8) {
+      const struct u_rect *scissor = &setup->scissor;
+
       plane[4].dcdx = -1;
       plane[4].dcdy = 0;
       plane[4].dcdx = -1;
       plane[4].dcdy = 0;
-      plane[4].c = 1-bbox.x0;
+      plane[4].c = 1-scissor->x0;
       plane[4].eo = 1;
 
       plane[5].dcdx = 1;
       plane[5].dcdy = 0;
       plane[4].eo = 1;
 
       plane[5].dcdx = 1;
       plane[5].dcdy = 0;
-      plane[5].c = bbox.x1+1;
+      plane[5].c = scissor->x1+1;
       plane[5].eo = 0;
 
       plane[6].dcdx = 0;
       plane[6].dcdy = 1;
       plane[5].eo = 0;
 
       plane[6].dcdx = 0;
       plane[6].dcdy = 1;
-      plane[6].c = 1-bbox.y0;
+      plane[6].c = 1-scissor->y0;
       plane[6].eo = 1;
 
       plane[7].dcdx = 0;
       plane[7].dcdy = -1;
       plane[6].eo = 1;
 
       plane[7].dcdx = 0;
       plane[7].dcdy = -1;
-      plane[7].c = bbox.y1+1;
+      plane[7].c = scissor->y1+1;
       plane[7].eo = 0;
    }
 
       plane[7].eo = 0;
    }
 
index 4ab0b72a5748d5b821eb28e8c90f0539ee3e2531..11dfe63931294494d611c5039fb4ef27d014423e 100644 (file)
@@ -295,7 +295,12 @@ do_triangle_ccw(struct lp_setup_context *setup,
       return TRUE;
    }
 
       return TRUE;
    }
 
-   u_rect_find_intersection(&setup->draw_region, &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);
 
    tri = lp_setup_alloc_triangle(scene,
                                  key->num_inputs,
 
    tri = lp_setup_alloc_triangle(scene,
                                  key->num_inputs,
@@ -501,24 +506,26 @@ do_triangle_ccw(struct lp_setup_context *setup,
     * these planes elsewhere.
     */
    if (nr_planes == 7) {
     * these planes elsewhere.
     */
    if (nr_planes == 7) {
+      const struct u_rect *scissor = &setup->scissor;
+
       plane[3].dcdx = -1;
       plane[3].dcdy = 0;
       plane[3].dcdx = -1;
       plane[3].dcdy = 0;
-      plane[3].c = 1-bbox.x0;
+      plane[3].c = 1-scissor->x0;
       plane[3].eo = 1;
 
       plane[4].dcdx = 1;
       plane[4].dcdy = 0;
       plane[3].eo = 1;
 
       plane[4].dcdx = 1;
       plane[4].dcdy = 0;
-      plane[4].c = bbox.x1+1;
+      plane[4].c = scissor->x1+1;
       plane[4].eo = 0;
 
       plane[5].dcdx = 0;
       plane[5].dcdy = 1;
       plane[4].eo = 0;
 
       plane[5].dcdx = 0;
       plane[5].dcdy = 1;
-      plane[5].c = 1-bbox.y0;
+      plane[5].c = 1-scissor->y0;
       plane[5].eo = 1;
 
       plane[6].dcdx = 0;
       plane[6].dcdy = -1;
       plane[5].eo = 1;
 
       plane[6].dcdx = 0;
       plane[6].dcdy = -1;
-      plane[6].c = bbox.y1+1;
+      plane[6].c = scissor->y1+1;
       plane[6].eo = 0;
    }
 
       plane[6].eo = 0;
    }
 
@@ -559,6 +566,7 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
                        int nr_planes )
 {
    struct lp_scene *scene = setup->scene;
                        int nr_planes )
 {
    struct lp_scene *scene = setup->scene;
+   struct u_rect trimmed_box = *bbox;   
    int i;
 
    /* What is the largest power-of-two boundary this triangle crosses:
    int i;
 
    /* What is the largest power-of-two boundary this triangle crosses:
@@ -572,6 +580,13 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
    int sz = floor_pot((bbox->x1 - (bbox->x0 & ~3)) |
                      (bbox->y1 - (bbox->y0 & ~3)));
 
    int sz = floor_pot((bbox->x1 - (bbox->x0 & ~3)) |
                      (bbox->y1 - (bbox->y0 & ~3)));
 
+   /* Now apply scissor, etc to the bounding box.  Could do this
+    * earlier, but it confuses the logic for tri-16 and would force
+    * the rasterizer to also respect scissor, etc, just for the rare
+    * cases where a small triangle extends beyond the scissor.
+    */
+   u_rect_find_intersection(&setup->draw_region, &trimmed_box);
+
    /* Determine which tile(s) intersect the triangle's bounding box
     */
    if (dx < TILE_SIZE)
    /* Determine which tile(s) intersect the triangle's bounding box
     */
    if (dx < TILE_SIZE)
@@ -626,15 +641,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
       struct lp_rast_plane *plane = GET_PLANES(tri);
       int c[MAX_PLANES];
       int ei[MAX_PLANES];
       struct lp_rast_plane *plane = GET_PLANES(tri);
       int c[MAX_PLANES];
       int ei[MAX_PLANES];
+
       int eo[MAX_PLANES];
       int xstep[MAX_PLANES];
       int ystep[MAX_PLANES];
       int x, y;
 
       int eo[MAX_PLANES];
       int xstep[MAX_PLANES];
       int ystep[MAX_PLANES];
       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;
+      int ix0 = trimmed_box.x0 / TILE_SIZE;
+      int iy0 = trimmed_box.y0 / TILE_SIZE;
+      int ix1 = trimmed_box.x1 / TILE_SIZE;
+      int iy1 = trimmed_box.y1 / TILE_SIZE;
       
       for (i = 0; i < nr_planes; i++) {
          c[i] = (plane[i].c + 
       
       for (i = 0; i < nr_planes; i++) {
          c[i] = (plane[i].c +