i965/fs: Swap if/else conditions in SEL peephole.
[mesa.git] / src / gallium / auxiliary / draw / draw_pipe_clip.c
index b0794583e96868da9bde753314c78196cd544e16..d8b56de4d2ff576a545c672637a10f6f7e1e7cc4 100644 (file)
@@ -588,7 +588,12 @@ do_clip_line( struct draw_stage *stage,
 
    if (v0->clipmask) {
       interp( clipper, stage->tmp[0], t0, v0, v1, viewport_index );
-      copy_flat(stage, stage->tmp[0], v0);
+      if (stage->draw->rasterizer->flatshade_first) {
+         copy_flat(stage, stage->tmp[0], v0);  /* copy v0 color to tmp[0] */
+      }
+      else {
+         copy_flat(stage, stage->tmp[0], v1);  /* copy v1 color to tmp[0] */
+      }
       newprim.v[0] = stage->tmp[0];
    }
    else {
@@ -597,6 +602,12 @@ do_clip_line( struct draw_stage *stage,
 
    if (v1->clipmask) {
       interp( clipper, stage->tmp[1], t1, v1, v0, viewport_index );
+      if (stage->draw->rasterizer->flatshade_first) {
+         copy_flat(stage, stage->tmp[1], v0);  /* copy v0 color to tmp[1] */
+      }
+      else {
+         copy_flat(stage, stage->tmp[1], v1);  /* copy v1 color to tmp[1] */
+      }
       newprim.v[1] = stage->tmp[1];
    }
    else {
@@ -615,28 +626,46 @@ clip_point( struct draw_stage *stage,
       stage->next->point( stage->next, header );
 }
 
+
 /*
  * Clip points but ignore the first 4 (xy) clip planes.
- * (This is necessary because we don't generate a different shader variant
- * just for points hence xy clip bits are still generated. This is not really
- * optimal because of the extra calculations both in generating clip masks
- * and executing the clip stage but it gets the job done.)
+ * (Because the generated clip mask is completely unaffacted by guard band,
+ * we still need to manually evaluate the x/y planes if they are outside
+ * the guard band and not just outside the vp.)
  */
 static void
-clip_point_no_xy( struct draw_stage *stage,
-                  struct prim_header *header )
+clip_point_guard_xy( struct draw_stage *stage,
+                     struct prim_header *header )
 {
-   if ((header->v[0]->clipmask & 0xfffffff0) == 0)
-      stage->next->point( stage->next, header );
+   unsigned clipmask = header->v[0]->clipmask;
+   if ((clipmask & 0xffffffff) == 0)
+      stage->next->point(stage->next, header);
+   else if ((clipmask & 0xfffffff0) == 0) {
+      while (clipmask) {
+         const unsigned plane_idx = ffs(clipmask)-1;
+         clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
+         /* TODO: this should really do proper guardband clipping,
+          * currently just throw out infs/nans.
+          * Also note that vertices with negative w values MUST be tossed
+          * out (not sure if proper guardband clipping would do this
+          * automatically). These would usually be captured by depth clip
+          * too but this can be disabled.
+          */
+         if (header->v[0]->clip[3] <= 0.0f ||
+             util_is_inf_or_nan(header->v[0]->clip[0]) ||
+             util_is_inf_or_nan(header->v[0]->clip[1]))
+            return;
+      }
+      stage->next->point(stage->next, header);
+   }
 }
 
 
-
 static void
 clip_first_point( struct draw_stage *stage,
                   struct prim_header *header )
 {
-   stage->point = stage->draw->clip_points_xy ? clip_point : clip_point_no_xy;
+   stage->point = stage->draw->guard_band_points_xy ? clip_point_guard_xy : clip_point;
    stage->point(stage, header);
 }
 
@@ -662,7 +691,7 @@ clip_line( struct draw_stage *stage,
 
 static void
 clip_tri( struct draw_stage *stage,
-         struct prim_header *header )
+          struct prim_header *header )
 {
    unsigned clipmask = (header->v[0]->clipmask | 
                         header->v[1]->clipmask |