[Mesa-dev] [PATCH 4/4] softpipe: clipdistance support (v1)
Brian Paul
brianp at vmware.com
Tue Jan 10 07:53:00 PST 2012
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<airlied at redhat.com>
>
> Add support for using the clipdistance instead of clip plane.
>
> Passes all piglit clipdistance tests.
>
> Signed-off-by: Dave Airlie<airlied at 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
More information about the mesa-dev
mailing list