Looks good to me.

-Brian


Ian Romanick wrote:
> From: Ian Romanick <ian.d.roman...@intel.com>
> 
> Once the clipping distance is calculated and stored per vertex, the
> distances can be re-used when clipping is actually performed.  This
> doesn't have any immediate benefit, but it paves the way for
> implementing gl_ClipDistance in vertex shaders and result.clip[] in
> vertex programs.
> 
> This has not produces any oglconform regressions on my G31 system
> which uses software TNL.
> 
> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com>
> ---
>  src/mesa/tnl/t_context.h    |    1 +
>  src/mesa/tnl/t_vb_cliptmp.h |  103 ++++++++++++++++++++++++++++++++++++------
>  src/mesa/tnl/t_vb_program.c |   15 ++++++
>  src/mesa/tnl/t_vb_vertex.c  |   31 ++++++++++++-
>  4 files changed, 132 insertions(+), 18 deletions(-)
> 
> diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
> index 6137c2d..ca4edcf 100644
> --- a/src/mesa/tnl/t_context.h
> +++ b/src/mesa/tnl/t_context.h
> @@ -207,6 +207,7 @@ struct vertex_buffer
>     GLvector4f  *EyePtr;                                /* _TNL_BIT_POS */
>     GLvector4f  *ClipPtr;                       /* _TNL_BIT_POS */
>     GLvector4f  *NdcPtr;                         /* _TNL_BIT_POS */
> +   GLfloat     *ClipDistancePtr[MAX_CLIP_PLANES]; /* _TNL_BIT_POS */
>     GLubyte     ClipOrMask;                     /* _TNL_BIT_POS */
>     GLubyte     ClipAndMask;                    /* _TNL_BIT_POS */
>     GLubyte     *ClipMask;                      /* _TNL_BIT_POS */
> diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h
> index 618b8b3..0d2183a 100644
> --- a/src/mesa/tnl/t_vb_cliptmp.h
> +++ b/src/mesa/tnl/t_vb_cliptmp.h
> @@ -80,6 +80,58 @@ do {                                                       
>           \
>  } while (0)
> 
> 
> +#define POLY_USERCLIP(PLANE)                                           \
> +do {                                                                   \
> +   if (mask & CLIP_USER_BIT) {                                         \
> +      GLuint idxPrev = inlist[0];                                      \
> +      GLfloat dpPrev = VB->ClipDistancePtr[PLANE][idxPrev];            \
> +      GLuint outcount = 0;                                             \
> +      GLuint i;                                                              
>   \
> +                                                                       \
> +      inlist[n] = inlist[0]; /* prevent rotation of vertices */              
>   \
> +      for (i = 1; i <= n; i++) {                                       \
> +        GLuint idx = inlist[i];                                        \
> +        GLfloat dp = VB->ClipDistancePtr[PLANE][idx];                  \
> +                                                                       \
> +        if (!IS_NEGATIVE(dpPrev)) {                                    \
> +           outlist[outcount++] = idxPrev;                              \
> +        }                                                              \
> +                                                                       \
> +        if (DIFFERENT_SIGNS(dp, dpPrev)) {                             \
> +           if (IS_NEGATIVE(dp)) {                                      \
> +              /* Going out of bounds.  Avoid division by zero as we    \
> +               * know dp != dpPrev from DIFFERENT_SIGNS, above.        \
> +               */                                                      \
> +              GLfloat t = dp / (dp - dpPrev);                          \
> +               INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \
> +              interp( ctx, t, newvert, idx, idxPrev, GL_TRUE );        \
> +           } else {                                                    \
> +              /* Coming back in.                                       \
> +               */                                                      \
> +              GLfloat t = dpPrev / (dpPrev - dp);                      \
> +               INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \
> +              interp( ctx, t, newvert, idxPrev, idx, GL_FALSE );       \
> +           }                                                           \
> +            outlist[outcount++] = newvert++;                           \
> +        }                                                              \
> +                                                                       \
> +        idxPrev = idx;                                                 \
> +        dpPrev = dp;                                                   \
> +      }                                                                      
>   \
> +                                                                       \
> +      if (outcount < 3)                                                      
>   \
> +        return;                                                        \
> +                                                                       \
> +      {                                                                      
>   \
> +        GLuint *tmp = inlist;                                          \
> +        inlist = outlist;                                              \
> +        outlist = tmp;                                                 \
> +        n = outcount;                                                  \
> +      }                                                                      
>   \
> +   }                                                                   \
> +} while (0)
> +
> +
>  #define LINE_CLIP(PLANE_BIT, A, B, C, D )                              \
>  do {                                                                   \
>     if (mask & PLANE_BIT) {                                             \
> @@ -111,6 +163,37 @@ do {                                                     
>                   \
>  } while (0)
> 
> 
> +#define LINE_USERCLIP(PLANE)                                           \
> +do {                                                                   \
> +   if (mask & CLIP_USER_BIT) {                                         \
> +      const GLfloat dp0 = VB->ClipDistancePtr[PLANE][v0];              \
> +      const GLfloat dp1 = VB->ClipDistancePtr[PLANE][v1];              \
> +      const GLboolean neg_dp0 = IS_NEGATIVE(dp0);                      \
> +      const GLboolean neg_dp1 = IS_NEGATIVE(dp1);                      \
> +                                                                       \
> +      /* For regular clipping, we know from the clipmask that one      \
> +       * (or both) of these must be negative (otherwise we wouldn't    \
> +       * be here).                                                     \
> +       * For userclip, there is only a single bit for all active       \
> +       * planes, so we can end up here when there is nothing to do,    \
> +       * hence the second IS_NEGATIVE() test:                          \
> +       */                                                              \
> +      if (neg_dp0 && neg_dp1)                                          \
> +         return; /* both vertices outside clip plane: discard */       \
> +                                                                       \
> +      if (neg_dp1) {                                                   \
> +        GLfloat t = dp1 / (dp1 - dp0);                                 \
> +        if (t > t1) t1 = t;                                            \
> +      } else if (neg_dp0) {                                            \
> +        GLfloat t = dp0 / (dp0 - dp1);                                 \
> +        if (t > t0) t0 = t;                                            \
> +      }                                                                      
>   \
> +      if (t0 + t1 >= 1.0)                                              \
> +        return; /* discard */                                          \
> +   }                                                                   \
> +} while (0)
> +
> +
> 
>  /* Clip a line against the viewport and user clip planes.
>   */
> @@ -139,11 +222,7 @@ TAG(clip_line)( GLcontext *ctx, GLuint v0, GLuint v1, 
> GLubyte mask )
>     if (mask & CLIP_USER_BIT) {
>        for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
>          if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
> -            const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
> -            const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
> -            const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
> -            const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
> -           LINE_CLIP( CLIP_USER_BIT, a, b, c, d );
> +           LINE_USERCLIP(p);
>          }
>        }
>     }
> @@ -228,11 +307,7 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, 
> GLuint v2, GLubyte mask )
>     if (mask & CLIP_USER_BIT) {
>        for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
>           if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
> -            const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
> -            const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
> -            const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
> -            const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
> -            POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
> +            POLY_USERCLIP(p);
>           }
>        }
>     }
> @@ -291,11 +366,7 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, 
> GLuint v2, GLuint v3,
>     if (mask & CLIP_USER_BIT) {
>        for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
>          if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
> -            const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
> -            const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
> -            const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
> -            const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
> -           POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
> +           POLY_USERCLIP(p);
>          }
>        }
>     }
> @@ -317,4 +388,6 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, 
> GLuint v2, GLuint v3,
>  #undef SIZE
>  #undef TAG
>  #undef POLY_CLIP
> +#undef POLY_USERCLIP
>  #undef LINE_CLIP
> +#undef LINE_USERCLIP
> diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
> index c10a276..5fb83c2 100644
> --- a/src/mesa/tnl/t_vb_program.c
> +++ b/src/mesa/tnl/t_vb_program.c
> @@ -66,6 +66,7 @@ struct vp_stage_data {
>     GLvector4f results[VERT_RESULT_MAX];
> 
>     GLvector4f ndcCoords;              /**< normalized device coords */
> +   GLfloat *clipdistance[MAX_CLIP_PLANES];
>     GLubyte *clipmask;                 /**< clip flags */
>     GLubyte ormask, andmask;           /**< for clipping */
>  };
> @@ -77,6 +78,7 @@ struct vp_stage_data {
>  static void
>  userclip( GLcontext *ctx,
>            GLvector4f *clip,
> +          GLfloat *clipdistance[MAX_CLIP_PLANES],
>            GLubyte *clipmask,
>            GLubyte *clipormask,
>            GLubyte *clipandmask )
> @@ -105,6 +107,8 @@ userclip( GLcontext *ctx,
>                clipmask[i] |= CLIP_USER_BIT;
>             }
> 
> +           clipdistance[p][i] = dp;
> +
>             STRIDE_F(coord, stride);
>          }
> 
> @@ -164,6 +168,7 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data 
> *store)
>        ctx->VertexProgram.Current->IsPositionInvariant)) {
>        userclip( ctx,
>                 VB->ClipPtr,
> +               store->clipdistance,
>                 store->clipmask,
>                 &store->ormask,
>                 &store->andmask );
> @@ -171,6 +176,9 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data 
> *store)
>        if (store->andmask) {
>          return GL_FALSE;
>        }
> +
> +      memcpy(VB->ClipDistancePtr, store->clipdistance,
> +            sizeof(store->clipdistance));
>     }
> 
>     VB->ClipAndMask = store->andmask;
> @@ -514,6 +522,10 @@ init_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage)
>     _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
>     store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
> 
> +   for (i = 0; i < MAX_CLIP_PLANES; i++)
> +      store->clipdistance[i] =
> +        (GLfloat *) ALIGN_MALLOC(sizeof(GLfloat) * size, 32);
> +
>     return GL_TRUE;
>  }
> 
> @@ -537,6 +549,9 @@ dtr(struct tnl_pipeline_stage *stage)
>        _mesa_vector4f_free( &store->ndcCoords );
>        ALIGN_FREE( store->clipmask );
> 
> +      for (i = 0; i < MAX_CLIP_PLANES; i++)
> +        ALIGN_FREE(store->clipdistance[i]);
> +
>        FREE( store );
>        stage->privatePtr = NULL;
>     }
> diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
> index 4734754..2a61ff1 100644
> --- a/src/mesa/tnl/t_vb_vertex.c
> +++ b/src/mesa/tnl/t_vb_vertex.c
> @@ -44,6 +44,7 @@ struct vertex_stage_data {
>     GLvector4f eye;
>     GLvector4f clip;
>     GLvector4f proj;
> +   GLfloat *clipdistance[MAX_CLIP_PLANES];
>     GLubyte *clipmask;
>     GLubyte ormask;
>     GLubyte andmask;
> @@ -56,11 +57,12 @@ struct vertex_stage_data {
> 
>  /* This function implements cliptesting for user-defined clip planes.
>   * The clipping of primitives to these planes is implemented in
> - * t_render_clip.h.
> + * t_vp_cliptmp.h.
>   */
>  #define USER_CLIPTEST(NAME, SZ)                                        \
>  static void NAME( GLcontext *ctx,                              \
>                   GLvector4f *clip,                             \
> +                 GLfloat *clipdistances[MAX_CLIP_PLANES],      \
>                   GLubyte *clipmask,                            \
>                   GLubyte *clipormask,                          \
>                   GLubyte *clipandmask )                        \
> @@ -88,6 +90,8 @@ static void NAME( GLcontext *ctx,                           
>   \
>                clipmask[i] |= CLIP_USER_BIT;                    \
>             }                                                   \
>                                                                 \
> +           clipdistances[p][i] = dp;                           \
> +                                                               \
>             STRIDE_F(coord, stride);                            \
>          }                                                      \
>                                                                 \
> @@ -107,8 +111,9 @@ USER_CLIPTEST(userclip3, 3)
>  USER_CLIPTEST(userclip4, 4)
> 
>  static void (*(usercliptab[5]))( GLcontext *,
> -                                GLvector4f *, GLubyte *,
> -                                GLubyte *, GLubyte * ) =
> +                                GLvector4f *,
> +                                GLfloat *[MAX_CLIP_PLANES],
> +                                GLubyte *, GLubyte *, GLubyte * ) =
>  {
>     NULL,
>     NULL,
> @@ -214,12 +219,16 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
>     if (ctx->Transform.ClipPlanesEnabled) {
>        usercliptab[VB->ClipPtr->size]( ctx,
>                                       VB->ClipPtr,
> +                                     store->clipdistance,
>                                       store->clipmask,
>                                       &store->ormask,
>                                       &store->andmask );
> 
>        if (store->andmask)
>          return GL_FALSE;
> +
> +      memcpy(VB->ClipDistancePtr, store->clipdistance,
> +            sizeof(store->clipdistance));
>     }
> 
>     VB->ClipAndMask = store->andmask;
> @@ -236,6 +245,7 @@ static GLboolean init_vertex_stage( GLcontext *ctx,
>     struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
>     struct vertex_stage_data *store;
>     GLuint size = VB->Size;
> +   unsigned i;
> 
>     stage->privatePtr = CALLOC(sizeof(*store));
>     store = VERTEX_STAGE_DATA(stage);
> @@ -247,8 +257,17 @@ static GLboolean init_vertex_stage( GLcontext *ctx,
>     _mesa_vector4f_alloc( &store->proj, 0, size, 32 );
> 
>     store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
> +   for (i = 0; i < MAX_CLIP_PLANES; i++)
> +      store->clipdistance[i] =
> +        (GLfloat *) ALIGN_MALLOC(sizeof(GLfloat) * size, 32);
> 
>     if (!store->clipmask ||
> +       !store->clipdistance[0] ||
> +       !store->clipdistance[1] ||
> +       !store->clipdistance[2] ||
> +       !store->clipdistance[3] ||
> +       !store->clipdistance[4] ||
> +       !store->clipdistance[5] ||
>         !store->eye.data ||
>         !store->clip.data ||
>         !store->proj.data)
> @@ -262,10 +281,16 @@ static void dtr( struct tnl_pipeline_stage *stage )
>     struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage);
> 
>     if (store) {
> +      unsigned i;
> +
>        _mesa_vector4f_free( &store->eye );
>        _mesa_vector4f_free( &store->clip );
>        _mesa_vector4f_free( &store->proj );
>        ALIGN_FREE( store->clipmask );
> +
> +      for (i = 0; i < MAX_CLIP_PLANES; i++)
> +        ALIGN_FREE(store->clipdistance[i]);
> +
>        FREE(store);
>        stage->privatePtr = NULL;
>        stage->run = init_vertex_stage;
> --
> 1.6.4.3
> 
> 
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry(R) Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your
> developing skills, take BlackBerry mobile applications to market and stay
> ahead of the curve. Join us from November 9 - 12, 2009. Register now!
> http://p.sf.net/sfu/devconference
> _______________________________________________
> Mesa3d-dev mailing list
> Mesa3d-dev@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mesa3d-dev
> .
> 


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to