Unify handling of userplanes and regular planes to simplify
authorZack Rusin <zack@tungstengraphics.com>
Wed, 3 Oct 2007 14:08:45 +0000 (10:08 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Wed, 3 Oct 2007 14:33:38 +0000 (10:33 -0400)
the clipping code.
(really done by Keith)

src/mesa/pipe/draw/draw_clip.c
src/mesa/pipe/draw/draw_context.c
src/mesa/pipe/draw/draw_private.h
src/mesa/pipe/draw/draw_vertex_shader.c

index a505146..4e1483f 100644 (file)
 #endif
 
 
-/** bitmask for the first view-frustum clip planes */
-#define VIEWPLANE_MASK ((1 << 6) - 1)
-
-/** bitmask for the user-defined clip planes */
-#define USERPLANE_MASK (((1 << PIPE_MAX_CLIP_PLANES) - 1) << 6)
-
-
 
 struct clipper {
    struct draw_stage stage;      /**< base class */
@@ -335,10 +328,6 @@ do_clip_line( struct draw_stage *stage,
       const float dp0 = dot4( pos0, plane );
       const float dp1 = dot4( pos1, plane );
 
-      /* need this to handle user-clip planes properly */
-      if (dp0 < 0.0F && dp1 < 0.0F)
-         return;
-
       if (dp1 < 0.0F) {
         float t = dp1 / (dp1 - dp0);
          t1 = MAX2(t1, t);
@@ -392,21 +381,8 @@ static void
 clip_point( struct draw_stage *stage, 
            struct prim_header *header )
 {
-   if (header->v[0]->clipmask == 0) {
+   if (header->v[0]->clipmask == 0) 
       stage->next->point( stage->next, header );
-   }
-   else if (header->v[0]->clipmask & USERPLANE_MASK) {
-      /* test against user clip planes now */
-      const struct clipper *clipper = clipper_stage( stage );
-      uint i;
-      for (i = 6; i < stage->draw->nr_planes; i++) {
-         float dot = dot4(clipper->plane[i], header->v[0]->clip);
-         if (dot < 0.0F)
-            return; /* clipped! */
-      }
-      /* not clipped */
-      stage->next->point( stage->next, header );
-   }
 }
 
 
@@ -421,22 +397,8 @@ clip_line( struct draw_stage *stage,
       /* no clipping needed */
       stage->next->line( stage->next, header );
    }
-   else if (((header->v[0]->clipmask &
-              header->v[1]->clipmask &
-              VIEWPLANE_MASK) == 0) ||
-            (clipmask & USERPLANE_MASK)) {
-      /* About the above predicate: the clipmask bits for the view volume
-       * exactly indicate whether the coordinate is inside or outside each
-       * frustum plane.  However, the bits for user-defined planes are set
-       * if the plane is enabled, and does not really indicate if the
-       * coordinate is inside or outside the user-defined plane.
-       *
-       * To change this (so that the user-plane bits really indicate
-       * inside/outside) we'd have to compute the dot products earlier
-       * in the draw_prim.c code (see compute_clipmask()).
-       * We will probably do that when we have support for user clip coord
-       * in vertex shaders...
-       */
+   else if ((header->v[0]->clipmask &
+             header->v[1]->clipmask) == 0) {
       do_clip_line(stage, header, clipmask);
    }
    /* else, totally clipped */
@@ -455,11 +417,9 @@ clip_tri( struct draw_stage *stage,
       /* no clipping needed */
       stage->next->tri( stage->next, header );
    }
-   else if (((header->v[0]->clipmask & 
-              header->v[1]->clipmask & 
-              header->v[2]->clipmask &
-              VIEWPLANE_MASK) == 0) ||
-            (clipmask & USERPLANE_MASK)) {
+   else if ((header->v[0]->clipmask & 
+             header->v[1]->clipmask & 
+             header->v[2]->clipmask) == 0) {
       do_clip_tri(stage, header, clipmask);
    }
 }
index 3fb667a..44e770f 100644 (file)
@@ -145,8 +145,6 @@ void draw_set_clip_state( struct draw_context *draw,
    assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
    memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
    draw->nr_planes = 6 + clip->nr;
-   /* bitmask of the enabled user-defined clip planes */
-   draw->user_clipmask = ((1 << clip->nr) - 1) << 6;
 }
 
 
index a54fef4..ff38925 100644 (file)
@@ -177,7 +177,6 @@ struct draw_context
     */
    float plane[12][4];
    unsigned nr_planes;
-   unsigned user_clipmask;
 
    /** Describes the layout of post-transformation vertices */
    struct vertex_info vertex_info;
index 6e80368..d17496a 100644 (file)
 
 #include "pipe/tgsi/exec/tgsi_core.h"
 
+
+static INLINE float dot4(const float *a, const float *b)
+{
+   float result = (a[0]*b[0] +
+                   a[1]*b[1] +
+                   a[2]*b[2] +
+                   a[3]*b[3]);
+
+   return result;
+}
+
 static INLINE unsigned
-compute_clipmask(float cx, float cy, float cz, float cw)
+compute_clipmask(const float *clip, const float (*plane)[4], unsigned nr)
 {
    unsigned mask = 0;
+   unsigned i;
 
-   if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
-   if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
-   if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
-   if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
-   if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
-   if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+   for (i = 0; i < nr; i++) {
+      if (dot4(clip, plane[i]) < 0) 
+         mask |= (1<<i);
+   }
 
    return mask;
 }
@@ -127,13 +137,18 @@ run_vertex_program(struct draw_context *draw,
       unsigned slot;
       float x, y, z, w;
 
-      /* Handle attr[0] (position) specially: */
+      /* Handle attr[0] (position) specially:
+       *
+       * XXX: Computing the clipmask should be done in the vertex
+       * program as a set of DP4 instructions appended to the
+       * user-provided code.
+       */
       x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
       y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
       z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
       w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
 
-      vOut[j]->clipmask = compute_clipmask(x, y, z, w) | draw->user_clipmask;
+      vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
       vOut[j]->edgeflag = 1;
 
       /* divide by w */