Mesa (master): draw: add support for guard-band clipping

Brian Paul brianp at kemper.freedesktop.org
Thu Sep 22 14:45:12 UTC 2011


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

Author: Brian Paul <brianp at vmware.com>
Date:   Wed Sep 21 12:06:17 2011 -0600

draw: add support for guard-band clipping

---

 src/gallium/auxiliary/draw/draw_cliptest_tmp.h     |   11 ++++++-
 src/gallium/auxiliary/draw/draw_context.c          |    6 +++-
 src/gallium/auxiliary/draw/draw_context.h          |    3 +-
 src/gallium/auxiliary/draw/draw_private.h          |    2 +
 src/gallium/auxiliary/draw/draw_pt.h               |    1 +
 .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c  |    1 +
 .../draw/draw_pt_fetch_shade_pipeline_llvm.c       |    1 +
 src/gallium/auxiliary/draw/draw_pt_post_vs.c       |   31 ++++++++++++++++++-
 src/gallium/drivers/svga/svga_swtnl_draw.c         |    2 +-
 9 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index 958ed20..1ca1529 100644
--- a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -47,7 +47,8 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
   
       initialize_vertex_header(out);
 
-      if (flags & (DO_CLIP_XY | DO_CLIP_FULL_Z | DO_CLIP_HALF_Z | DO_CLIP_USER)) {
+      if (flags & (DO_CLIP_XY | DO_CLIP_XY_GUARD_BAND |
+                   DO_CLIP_FULL_Z | DO_CLIP_HALF_Z | DO_CLIP_USER)) {
          out->clip[0] = position[0];
          out->clip[1] = position[1];
          out->clip[2] = position[2];
@@ -55,7 +56,13 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
 
          /* Do the hardwired planes first:
           */
-         if (flags & DO_CLIP_XY) {
+         if (flags & DO_CLIP_XY_GUARD_BAND) {
+            if (-0.50 * position[0] + position[3] < 0) mask |= (1<<0);
+            if ( 0.50 * position[0] + position[3] < 0) mask |= (1<<1);
+            if (-0.50 * position[1] + position[3] < 0) mask |= (1<<2);
+            if ( 0.50 * position[1] + position[3] < 0) mask |= (1<<3);
+         }
+         else if (flags & DO_CLIP_XY) {
             if (-position[0] + position[3] < 0) mask |= (1<<0);
             if ( position[0] + position[3] < 0) mask |= (1<<1);
             if (-position[1] + position[3] < 0) mask |= (1<<2);
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index f8196bb..b8f8623 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -220,6 +220,8 @@ void draw_set_mrd(struct draw_context *draw, double mrd)
 static void update_clip_flags( struct draw_context *draw )
 {
    draw->clip_xy = !draw->driver.bypass_clip_xy;
+   draw->guard_band_xy = (!draw->driver.bypass_clip_xy &&
+                          draw->driver.guard_band_xy);
    draw->clip_z = (!draw->driver.bypass_clip_z &&
                    !draw->depth_clamp);
    draw->clip_user = (draw->nr_planes > 6);
@@ -251,12 +253,14 @@ void draw_set_rasterizer_state( struct draw_context *draw,
  */
 void draw_set_driver_clipping( struct draw_context *draw,
                                boolean bypass_clip_xy,
-                               boolean bypass_clip_z )
+                               boolean bypass_clip_z,
+                               boolean guard_band_xy)
 {
    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
 
    draw->driver.bypass_clip_xy = bypass_clip_xy;
    draw->driver.bypass_clip_z = bypass_clip_z;
+   draw->driver.guard_band_xy = guard_band_xy;
    update_clip_flags(draw);
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 5523e44..9a7bf36 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -230,7 +230,8 @@ void draw_set_render( struct draw_context *draw,
 
 void draw_set_driver_clipping( struct draw_context *draw,
                                boolean bypass_clip_xy,
-                               boolean bypass_clip_z );
+                               boolean bypass_clip_z,
+                               boolean guard_band_xy);
 
 void draw_set_force_passthrough( struct draw_context *draw, 
                                  boolean enable );
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 594ef44..ef77266 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -189,6 +189,7 @@ struct draw_context
    struct {
       boolean bypass_clip_xy;
       boolean bypass_clip_z;
+      boolean guard_band_xy;
    } driver;
 
    boolean flushing;         /**< debugging/sanity */
@@ -200,6 +201,7 @@ struct draw_context
    boolean clip_xy;
    boolean clip_z;
    boolean clip_user;
+   boolean guard_band_xy;
 
    boolean force_passthrough; /**< never clip or shade */
 
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 5fbb424..9a45845 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -224,6 +224,7 @@ void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean clip_xy,
 			      boolean clip_z,
 			      boolean clip_user,
+                              boolean guard_band,
 			      boolean bypass_viewport,
 			      boolean opengl,
 			      boolean need_edgeflags );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index b72fd61..27420f0 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -103,6 +103,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
 			    draw->clip_xy,
 			    draw->clip_z,
 			    draw->clip_user,
+                            draw->guard_band_xy,
 			    draw->identity_viewport,
 			    (boolean)draw->rasterizer->gl_rasterization_rules,
 			    (draw->vs.edgeflag_output ? TRUE : FALSE) );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 2e3afb2..ac83968 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -110,6 +110,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
 			    draw->clip_xy,
 			    draw->clip_z,
 			    draw->clip_user,
+                            draw->guard_band_xy,
 			    draw->identity_viewport,
 			    (boolean)draw->rasterizer->gl_rasterization_rules,
 			    (draw->vs.edgeflag_output ? TRUE : FALSE) );
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 769409c..a8d65fd 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -39,6 +39,7 @@
 #define DO_CLIP_USER         0x8
 #define DO_VIEWPORT          0x10
 #define DO_EDGEFLAG          0x20
+#define DO_CLIP_XY_GUARD_BAND 0x40
 
 
 struct pt_post_vs {
@@ -80,6 +81,10 @@ dot4(const float *a, const float *b)
 #define TAG(x) x##_xy_halfz_viewport
 #include "draw_cliptest_tmp.h"
 
+#define FLAGS (DO_CLIP_XY_GUARD_BAND | DO_CLIP_HALF_Z | DO_VIEWPORT)
+#define TAG(x) x##_xy_gb_halfz_viewport
+#include "draw_cliptest_tmp.h"
+
 #define FLAGS (DO_CLIP_FULL_Z | DO_VIEWPORT)
 #define TAG(x) x##_fullz_viewport
 #include "draw_cliptest_tmp.h"
@@ -120,15 +125,33 @@ void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean clip_xy,
 			      boolean clip_z,
                               boolean clip_user,
+                              boolean guard_band,
 			      boolean bypass_viewport,
 			      boolean opengl,
 			      boolean need_edgeflags )
 {
    pvs->flags = 0;
 
-   if (clip_xy)
+   /* This combination not currently tested/in use:
+    */
+   if (opengl)
+      guard_band = FALSE;
+
+   if (clip_xy && !guard_band) {
       pvs->flags |= DO_CLIP_XY;
-   
+      ASSIGN_4V( pvs->draw->plane[0], -1,  0,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[1],  1,  0,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[2],  0, -1,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[3],  0,  1,  0, 1 );
+   }
+   else if (clip_xy && guard_band) {
+      pvs->flags |= DO_CLIP_XY_GUARD_BAND;
+      ASSIGN_4V( pvs->draw->plane[0], -0.5,  0,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[1],  0.5,  0,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[2],  0, -0.5,  0, 1 );
+      ASSIGN_4V( pvs->draw->plane[3],  0,  0.5,  0, 1 );
+   }
+
    if (clip_z && opengl) {
       pvs->flags |= DO_CLIP_FULL_Z;
       ASSIGN_4V( pvs->draw->plane[4],  0,  0,  1, 1 );
@@ -163,6 +186,10 @@ void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
       pvs->run = do_cliptest_xy_halfz_viewport;
       break;
 
+   case DO_CLIP_XY_GUARD_BAND | DO_CLIP_HALF_Z | DO_VIEWPORT:
+      pvs->run = do_cliptest_xy_gb_halfz_viewport;
+      break;
+
    case DO_CLIP_FULL_Z | DO_VIEWPORT:
       pvs->run = do_cliptest_fullz_viewport;
       break;
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index ad29c1b..3bf1886 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -156,7 +156,7 @@ boolean svga_init_swtnl( struct svga_context *svga )
    draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
 
    if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE))
-      draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE);
+      draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE);
 
    return TRUE;
 




More information about the mesa-commit mailing list