The check-in message should probably be "draw: clipdistance support (v1)", not "softpipe".

On 01/10/2012 06:55 AM, Dave Airlie wrote:
From: Dave Airlie<airl...@redhat.com>

Add support for using the clipdistance instead of clip plane.

Passes all piglit clipdistance tests.

Signed-off-by: Dave Airlie<airl...@redhat.com>
---
  src/gallium/auxiliary/draw/draw_cliptest_tmp.h |   25 ++++++++++++++--
  src/gallium/auxiliary/draw/draw_context.c      |    6 ++++
  src/gallium/auxiliary/draw/draw_pipe_clip.c    |   36 ++++++++++++++++++------
  src/gallium/auxiliary/draw/draw_private.h      |    5 ++-
  src/gallium/auxiliary/draw/draw_pt_post_vs.c   |    4 +-
  src/gallium/auxiliary/draw/draw_vs.c           |    7 ++++
  src/gallium/auxiliary/draw/draw_vs.h           |    2 +-
  7 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h 
b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index 7dba49b..438d2d8 100644
--- a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -36,12 +36,19 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
     /* const */ float (*plane)[4] = pvs->draw->plane;
     const unsigned pos = draw_current_shader_position_output(pvs->draw);
     const unsigned cv = draw_current_shader_clipvertex_output(pvs->draw);
+   unsigned cd[2];
     const unsigned ef = pvs->draw->vs.edgeflag_output;
     const unsigned ucp_enable = pvs->draw->rasterizer->clip_plane_enable;
     const unsigned flags = (FLAGS);
     unsigned need_pipeline = 0;
     unsigned j;
     unsigned i;
+   bool have_cd = false;
+   cd[0] = draw_current_shader_clipdistance_output(pvs->draw, 0);
+   cd[1] = draw_current_shader_clipdistance_output(pvs->draw, 1);
+
+   if (cd[0] != pos || cd[1] != pos)
+     have_cd = true;

     for (j = 0; j<  info->count; j++) {
        float *position = out->data[pos];
@@ -89,14 +96,26 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,

           if (flags&  DO_CLIP_USER) {
              unsigned ucp_mask = ucp_enable;
-
+            int num_clipdistance = 
pvs->draw->vs.vertex_shader->info.num_clipdistance;
              while (ucp_mask) {
                 unsigned plane_idx = ffs(ucp_mask)-1;
+               float clipval;
                 ucp_mask&= ~(1<<  plane_idx);
                 plane_idx += 6;

-               if (dot4(clipvertex, plane[plane_idx])<  0) {
-                  mask |= 1<<  plane_idx;

Could you add some comments on the following code? Maybe it's just me, but I think it's a bit hard to follow.


+               if (have_cd&&  num_clipdistance) {
+                  i = plane_idx - 6;
+                  out->have_clipdist = 1;
+                  if (i<  4)
+                     clipval = out->data[cd[0]][i];
+                  else
+                     clipval = out->data[cd[1]][i-4];
+                  if (clipval<  0)
+                     mask |= (1<<  plane_idx);
+               } else {
+                  if (dot4(clipvertex, plane[plane_idx])<  0) {
+                     mask |= 1<<  plane_idx;
+                  }
                 }
              }
           }
diff --git a/src/gallium/auxiliary/draw/draw_context.c 
b/src/gallium/auxiliary/draw/draw_context.c
index 6d7075e..7e554dc 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -701,6 +701,12 @@ draw_current_shader_clipvertex_output(const struct 
draw_context *draw)
     return draw->vs.clipvertex_output;
  }

+uint
+draw_current_shader_clipdistance_output(const struct draw_context *draw, int 
index)
+{
+   return draw->vs.clipdistance_output[index];
+}
+
  /**
   * Return a pointer/handle for a driver/CSO rasterizer object which
   * disabled culling, stippling, unfilled tris, etc.
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c 
b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index fbc8f67..265b755 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -119,13 +119,17 @@ static void interp( const struct clip_stage *clip,
     const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
     const unsigned pos_attr = 
draw_current_shader_position_output(clip->stage.draw);
     const unsigned clip_attr = 
draw_current_shader_clipvertex_output(clip->stage.draw);
+   unsigned clip_dist[2];
     unsigned j;

+   clip_dist[0] = draw_current_shader_clipdistance_output(clip->stage.draw, 0);
+   clip_dist[1] = draw_current_shader_clipdistance_output(clip->stage.draw, 1);
+
     /* Vertex header.
      */
     dst->clipmask = 0;
     dst->edgeflag = 0;        /* will get overwritten later */
-   dst->pad = 0;
+   dst->have_clipdist = in->have_clipdist;
     dst->vertex_id = UNDEFINED_VERTEX_ID;

     /* Interpolate the clip-space coords.
@@ -241,6 +245,23 @@ dot4(const float *a, const float *b)
             a[3] * b[3]);
  }



Comments on this function would be helpful too. And we're still using INLINE in the gallium code.


+static inline float getclipdist(const struct clip_stage *clipper,
+                                struct vertex_header *vert,
+                                int plane_idx)
+{
+   const float *plane;
+   float dp;
+   if (vert->have_clipdist&&  plane_idx>= 6) {
+      int _idx = plane_idx - 6;
+      int cdi = _idx>= 4;
+      int vidx = cdi ? _idx - 4 : _idx;
+      dp = 
vert->data[draw_current_shader_clipdistance_output(clipper->stage.draw, 
cdi)][vidx];
+   } else {
+      plane = clipper->plane[plane_idx];
+      dp = dot4(vert->clip, plane);
+   }
+   return dp;
+}

  /* Clip a triangle against the viewport and user clip planes.
   */
@@ -281,12 +302,12 @@ do_clip_tri( struct draw_stage *stage,
     while (clipmask&&  n>= 3) {
        const unsigned plane_idx = ffs(clipmask)-1;
        const boolean is_user_clip_plane = plane_idx>= 6;
-      const float *plane = clipper->plane[plane_idx];
        struct vertex_header *vert_prev = inlist[0];
        boolean *edge_prev =&inEdges[0];
-      float dp_prev = dot4( vert_prev->clip, plane );
+      float dp_prev;
        unsigned outcount = 0;

+      dp_prev = getclipdist(clipper, vert_prev, plane_idx);
        clipmask&= ~(1<<plane_idx);

        assert(n<  MAX_CLIPPED_VERTICES);
@@ -299,7 +320,7 @@ do_clip_tri( struct draw_stage *stage,
         struct vertex_header *vert = inlist[i];
           boolean *edge =&inEdges[i];

-        float dp = dot4( vert->clip, plane );
+         float dp = getclipdist(clipper, vert, plane_idx);

         if (!IS_NEGATIVE(dp_prev)) {
              assert(outcount<  MAX_CLIPPED_VERTICES);
@@ -421,17 +442,14 @@ do_clip_line( struct draw_stage *stage,
     const struct clip_stage *clipper = clip_stage( stage );
     struct vertex_header *v0 = header->v[0];
     struct vertex_header *v1 = header->v[1];
-   const float *pos0 = v0->clip;
-   const float *pos1 = v1->clip;
     float t0 = 0.0F;
     float t1 = 0.0F;
     struct prim_header newprim;

     while (clipmask) {
        const unsigned plane_idx = ffs(clipmask)-1;
-      const float *plane = clipper->plane[plane_idx];
-      const float dp0 = dot4( pos0, plane );
-      const float dp1 = dot4( pos1, plane );
+      const float dp0 = getclipdist(clipper, v0, plane_idx);
+      const float dp1 = getclipdist(clipper, v1, plane_idx);

        if (dp1<  0.0F) {
         float t = dp1 / (dp1 - dp0);
diff --git a/src/gallium/auxiliary/draw/draw_private.h 
b/src/gallium/auxiliary/draw/draw_private.h
index aa9b602..31beb4b 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -72,7 +72,7 @@ struct tgsi_sampler;
  struct vertex_header {
     unsigned clipmask:DRAW_TOTAL_CLIP_PLANES;
     unsigned edgeflag:1;
-   unsigned pad:1;
+   unsigned have_clipdist:1;
     unsigned vertex_id:16;

     float clip[4];
@@ -232,7 +232,7 @@ struct draw_context
        uint position_output;
        uint edgeflag_output;
        uint clipvertex_output;
-
+      uint clipdistance_output[2];
        /** TGSI program interpreter runtime state */
        struct tgsi_exec_machine *machine;

@@ -381,6 +381,7 @@ void draw_gs_destroy( struct draw_context *draw );
  uint draw_current_shader_outputs(const struct draw_context *draw);
  uint draw_current_shader_position_output(const struct draw_context *draw);
  uint draw_current_shader_clipvertex_output(const struct draw_context *draw);
+uint draw_current_shader_clipdistance_output(const struct draw_context *draw, 
int index);
  int draw_alloc_extra_vertex_attrib(struct draw_context *draw,
                                     uint semantic_name, uint semantic_index);
  void draw_remove_extra_vertex_attribs(struct draw_context *draw);
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c 
b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index a8d65fd..a83bb59 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -31,7 +31,7 @@
  #include "draw/draw_context.h"
  #include "draw/draw_private.h"
  #include "draw/draw_pt.h"
-
+#include "draw/draw_vs.h"

  #define DO_CLIP_XY           0x1
  #define DO_CLIP_FULL_Z       0x2
@@ -56,7 +56,7 @@ initialize_vertex_header(struct vertex_header *header)
  {
     header->clipmask = 0;
     header->edgeflag = 1;
-   header->pad = 0;
+   header->have_clipdist = 0;
     header->vertex_id = UNDEFINED_VERTEX_ID;
  }

diff --git a/src/gallium/auxiliary/draw/draw_vs.c 
b/src/gallium/auxiliary/draw/draw_vs.c
index 150653c..56c4f88 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -132,6 +132,11 @@ draw_create_vertex_shader(struct draw_context *draw,
                    vs->info.output_semantic_index[i] == 0) {
              found_clipvertex = TRUE;
              vs->clipvertex_output = i;
+         } else if (vs->info.output_semantic_name[i] == 
TGSI_SEMANTIC_CLIPDIST) {
+            if (vs->info.output_semantic_index[i] == 0)
+               vs->clipdistance_output[0] = i;
+            else
+               vs->clipdistance_output[1] = i;
           }
        }
        if (!found_clipvertex)
@@ -156,6 +161,8 @@ draw_bind_vertex_shader(struct draw_context *draw,
        draw->vs.position_output = dvs->position_output;
        draw->vs.edgeflag_output = dvs->edgeflag_output;
        draw->vs.clipvertex_output = dvs->clipvertex_output;
+      draw->vs.clipdistance_output[0] = dvs->clipdistance_output[0];
+      draw->vs.clipdistance_output[1] = dvs->clipdistance_output[1];
        dvs->prepare( dvs, draw );
     }
     else {
diff --git a/src/gallium/auxiliary/draw/draw_vs.h 
b/src/gallium/auxiliary/draw/draw_vs.h
index a3b90fa..8a44091 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -112,7 +112,7 @@ struct draw_vertex_shader {
     unsigned position_output;
     unsigned edgeflag_output;
     unsigned clipvertex_output;
-
+   unsigned clipdistance_output[2];
     /* Extracted from shader:
      */
     const float (*immediates)[4];

The rest of the series looks OK, AFAICT.

-Brian

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to