From 4465efc3bf8d755a9afb7a4bb5382e2f5bf113e1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 21 Sep 2011 12:06:17 -0600 Subject: [PATCH] draw: add support for guard-band clipping --- .../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 + .../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 958ed20dc84..1ca152911eb 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 f8196bb476f..b8f8623ee5d 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 5523e44563b..9a7bf361393 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 594ef440092..ef772660f71 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 5fbb4242915..9a45845521a 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 b72fd612451..27420f06798 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 2e3afb22c48..ac839682331 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 769409cfd67..a8d65fd5d7b 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 ad29c1b6425..3bf1886194a 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; -- 2.30.2