summaryrefslogtreecommitdiff
path: root/src/mesa/tnl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl')
-rw-r--r--src/mesa/tnl/t_array_import.c14
-rw-r--r--src/mesa/tnl/t_context.c7
-rw-r--r--src/mesa/tnl/t_context.h17
-rw-r--r--src/mesa/tnl/t_imm_api.c2
-rw-r--r--src/mesa/tnl/t_imm_exec.c13
-rw-r--r--src/mesa/tnl/t_pipeline.h8
-rw-r--r--src/mesa/tnl/t_vb_cliptmp.h558
-rw-r--r--src/mesa/tnl/t_vb_render.c416
-rw-r--r--src/mesa/tnl/t_vb_rendertmp.h86
9 files changed, 454 insertions, 667 deletions
diff --git a/src/mesa/tnl/t_array_import.c b/src/mesa/tnl/t_array_import.c
index fc2c3d1944..008cc23c64 100644
--- a/src/mesa/tnl/t_array_import.c
+++ b/src/mesa/tnl/t_array_import.c
@@ -1,4 +1,4 @@
-/* $Id: t_array_import.c,v 1.3 2000/12/28 22:11:05 keithw Exp $ */
+/* $Id: t_array_import.c,v 1.4 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -301,11 +301,6 @@ static void _tnl_upgrade_client_data( GLcontext *ctx,
_tnl_import_texcoord( ctx, i, writeable, stride );
}
- if ((required & VERT_EDGE) && (VB->EdgeFlagPtr->flags & flags)) {
- ASSERT(VB->EdgeFlagPtr == &inputs->EdgeFlag);
- _tnl_import_edgeflag( ctx, writeable, stride );
- }
-
VB->importable_data &= ~required;
}
@@ -386,11 +381,8 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
}
if (inputs & VERT_EDGE) {
- if (imports & VERT_EDGE) {
- _tnl_import_edgeflag( ctx, 0, 0 );
- tmp->EdgeFlag.count = VB->Count;
- }
- VB->EdgeFlagPtr = &tmp->EdgeFlag;
+ _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
+ VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
}
if (inputs & VERT_SPEC_RGB) {
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index 5b879d8a83..7d04210eb6 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -1,4 +1,4 @@
-/* $Id: t_context.c,v 1.7 2000/12/26 05:09:32 keithw Exp $ */
+/* $Id: t_context.c,v 1.8 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -69,6 +69,9 @@ install_driver_callbacks( GLcontext *ctx )
ctx->Driver.MakeCurrent = _tnl_MakeCurrent;
ctx->Driver.BeginCallList = _tnl_BeginCallList;
ctx->Driver.EndCallList = _tnl_EndCallList;
+
+ ctx->Driver.RenderTabElts = _tnl_render_tab_elts;
+ ctx->Driver.RenderTabVerts = _tnl_render_tab_verts;
}
@@ -111,7 +114,7 @@ _tnl_CreateContext( GLcontext *ctx )
/* Set a few default values in the driver struct.
*/
install_driver_callbacks(ctx);
- ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT|FLUSH_STORED_VERTICES;
+ ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index 62d260681c..8e3952a412 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -1,4 +1,4 @@
-/* $Id: t_context.h,v 1.8 2000/12/27 22:30:29 keithw Exp $ */
+/* $Id: t_context.h,v 1.9 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -226,6 +226,12 @@ struct vertex_arrays
typedef struct gl_material GLmaterial;
+typedef void (*interp_func)( GLcontext *ctx,
+ GLfloat t, GLuint dst, GLuint in, GLuint out,
+ GLboolean force_boundary );
+
+typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
+
/* Contains the current state of a running pipeline.
*/
typedef struct vertex_buffer
@@ -251,7 +257,7 @@ typedef struct vertex_buffer
GLubyte *ClipMask; /* VERT_CLIP (4) */
GLvector3f *NormalPtr; /* VERT_NORM */
GLfloat *NormalLengthPtr; /* VERT_NORM (optional) */
- GLvector1ub *EdgeFlagPtr; /* VERT_EDGE */
+ GLboolean *EdgeFlag; /* VERT_EDGE */
GLvector4f *TexCoordPtr[MAX_TEXTURE_UNITS]; /* VERT_TEX_0..n */
GLvector1ui *IndexPtr[2]; /* VERT_INDEX */
GLvector4ub *ColorPtr[2]; /* VERT_RGBA */
@@ -276,9 +282,10 @@ typedef struct vertex_buffer
*/
GLuint LastClipped;
- void *interpfunc;
- /* Two pieces of private data from _tnl_render_stage that have no
- * business being in this struct.
+ interp_func interpfunc;
+ copy_pv_func copypvfunc;
+ /* Private data from _tnl_render_stage that has no business being
+ * in this struct.
*/
} TNLvertexbuffer;
diff --git a/src/mesa/tnl/t_imm_api.c b/src/mesa/tnl/t_imm_api.c
index 528f101661..aeca38dd4f 100644
--- a/src/mesa/tnl/t_imm_api.c
+++ b/src/mesa/tnl/t_imm_api.c
@@ -292,7 +292,7 @@ _tnl_end( GLcontext *ctx )
IM->FlushElt = 0;
}
- ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
+/* ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; */
}
IM->BeginState = state;
diff --git a/src/mesa/tnl/t_imm_exec.c b/src/mesa/tnl/t_imm_exec.c
index 1549fa53af..4bdce0d18d 100644
--- a/src/mesa/tnl/t_imm_exec.c
+++ b/src/mesa/tnl/t_imm_exec.c
@@ -1,4 +1,4 @@
-/* $Id: t_imm_exec.c,v 1.4 2000/12/28 22:11:05 keithw Exp $ */
+/* $Id: t_imm_exec.c,v 1.5 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -198,7 +198,7 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
VB->NormalPtr = 0;
VB->NormalLengthPtr = 0;
VB->FogCoordPtr = 0;
- VB->EdgeFlagPtr = 0;
+ VB->EdgeFlag = 0;
VB->IndexPtr[0] = 0;
VB->IndexPtr[1] = 0;
VB->ColorPtr[0] = 0;
@@ -259,10 +259,7 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
}
if (inputs & VERT_EDGE) {
- tmp->EdgeFlag.data = IM->EdgeFlag + start;
- tmp->EdgeFlag.start = IM->EdgeFlag + start;
- tmp->EdgeFlag.count = count;
- VB->EdgeFlagPtr = &tmp->EdgeFlag;
+ VB->EdgeFlag = IM->EdgeFlag + start;
}
if (inputs & VERT_RGBA) {
@@ -451,8 +448,8 @@ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM )
*/
_tnl_copy_immediate_vertices( ctx, IM );
-/* if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) */
-/* ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; */
+ if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
+ ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
}
diff --git a/src/mesa/tnl/t_pipeline.h b/src/mesa/tnl/t_pipeline.h
index 9d433bde0a..3f64eb8ed9 100644
--- a/src/mesa/tnl/t_pipeline.h
+++ b/src/mesa/tnl/t_pipeline.h
@@ -1,4 +1,4 @@
-/* $Id: t_pipeline.h,v 1.4 2000/12/26 05:09:33 keithw Exp $ */
+/* $Id: t_pipeline.h,v 1.5 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -62,4 +62,10 @@ extern const struct gl_pipeline_stage _tnl_render_stage;
*/
extern const struct gl_pipeline_stage *_tnl_default_pipeline[];
+
+/* Convenience routines provided by t_vb_render.c:
+ */
+extern render_func _tnl_render_tab_elts[];
+extern render_func _tnl_render_tab_verts[];
+
#endif
diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h
index 1aeb014e15..5957f4960c 100644
--- a/src/mesa/tnl/t_vb_cliptmp.h
+++ b/src/mesa/tnl/t_vb_cliptmp.h
@@ -1,4 +1,4 @@
-/* $Id: t_vb_cliptmp.h,v 1.4 2000/12/28 22:11:05 keithw Exp $ */
+/* $Id: t_vb_cliptmp.h,v 1.5 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -28,340 +28,45 @@
*/
-#define INSIDE( J ) !NEGATIVE(J)
-#define OUTSIDE( J ) NEGATIVE(J)
+#define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D
-
-
-
-static GLuint TAG(userclip_line)( GLcontext *ctx,
- GLuint *i, GLuint *j,
- interp_func interp )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLfloat (*coord)[4] = VB->ClipPtr->data;
- GLuint ii = *i;
- GLuint jj = *j;
- GLuint p;
-
- for (p=0;p<MAX_CLIP_PLANES;p++) {
- if (ctx->Transform.ClipEnabled[p]) {
- GLfloat a = ctx->Transform._ClipUserPlane[p][0];
- GLfloat b = ctx->Transform._ClipUserPlane[p][1];
- GLfloat c = ctx->Transform._ClipUserPlane[p][2];
- GLfloat d = ctx->Transform._ClipUserPlane[p][3];
-
- GLfloat dpI = d*W(ii) + c*Z(ii) + b*Y(ii) + a*X(ii);
- GLfloat dpJ = d*W(jj) + c*Z(jj) + b*Y(jj) + a*X(jj);
-
- GLuint flagI = OUTSIDE( dpI );
- GLuint flagJ = OUTSIDE( dpJ );
-
- if (flagI ^ flagJ) {
- if (flagJ) {
- GLfloat t = dpI / (dpI - dpJ);
- VB->ClipMask[jj] |= CLIP_USER_BIT;
- jj = interp( ctx, t, ii, jj, GL_FALSE );
- VB->ClipMask[jj] = 0;
- } else {
- GLfloat t = dpJ / (dpJ - dpI);
- VB->ClipMask[ii] |= CLIP_USER_BIT;
- ii = interp( ctx, t, jj, ii, GL_FALSE );
- VB->ClipMask[ii] = 0;
- }
- }
- else if (flagI)
- return 0;
- }
- }
-
- *i = ii;
- *j = jj;
- return 1;
-}
-
-
-static GLuint TAG(userclip_polygon)( GLcontext *ctx,
- GLuint n,
- GLuint vlist[],
- interp_func interp )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLfloat (*coord)[4] = VB->ClipPtr->data;
- GLuint vlist2[MAX_CLIPPED_VERTICES];
- GLuint *inlist = vlist, *outlist = vlist2;
- GLubyte *clipmask = VB->ClipMask;
- GLuint p;
-
-#define CLIP_DOTPROD(xx) d*W(xx) + c*Z(xx) + b*Y(xx) + a*X(xx)
-
- /* Can be speeded up to if vertex_stage actually saves the
- * UserClipMask, and if it is used in this loop (after computing a
- * UserClipOrMask).
- */
- for (p=0;p<MAX_CLIP_PLANES;p++) {
- if (ctx->Transform.ClipEnabled[p]) {
- register float a = ctx->Transform._ClipUserPlane[p][0];
- register float b = ctx->Transform._ClipUserPlane[p][1];
- register float c = ctx->Transform._ClipUserPlane[p][2];
- register float d = ctx->Transform._ClipUserPlane[p][3];
-
- /* initialize prev to be last in the input list */
- GLuint idxPrev = inlist[n-1];
- GLfloat dpPrev = CLIP_DOTPROD(idxPrev);
- GLuint outcount = 0;
- GLuint i;
-
- for (i = 0 ; i < n ; i++) {
- GLuint idx = inlist[i];
- GLfloat dp = CLIP_DOTPROD(idx);
-
- if (!NEGATIVE(dpPrev)) {
- outlist[outcount++] = idxPrev;
- clipmask[idxPrev] &= ~CLIP_USER_BIT;
- } else {
- clipmask[idxPrev] |= CLIP_USER_BIT;
- }
-
-
- if (DIFFERENT_SIGNS(dp, dpPrev)) {
- GLuint newvert;
- if (NEGATIVE(dp)) {
- /* Going out of bounds. Avoid division by zero as we
- * know dp != dpPrev from DIFFERENT_SIGNS, above.
- */
- GLfloat t = dp / (dp - dpPrev);
- newvert = interp( ctx, t, idx, idxPrev, GL_TRUE );
- } else {
- /* Coming back in.
- */
- GLfloat t = dpPrev / (dpPrev - dp);
- newvert = interp( ctx, t, idxPrev, idx, GL_FALSE );
- }
- clipmask[newvert] = 0;
- outlist[outcount++] = newvert;
- }
-
- idxPrev = idx;
- dpPrev = dp;
- }
-
- if (outcount < 3)
- return 0;
-
- {
- GLuint *tmp;
- tmp = inlist;
- inlist = outlist;
- outlist = tmp;
- n = outcount;
- }
- } /* if */
- } /* for p */
-
- if (inlist!=vlist) {
- GLuint i;
- for (i = 0 ; i < n ; i++)
- vlist[i] = inlist[i];
- }
-
- return n;
-}
-
-
-/* This now calls the user clip functions if required.
- */
-static void TAG(viewclip_line)( GLcontext *ctx,
- GLuint i, GLuint j,
- GLubyte mask )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- interp_func interp = (interp_func) VB->interpfunc;
- GLfloat (*coord)[4] = VB->ClipPtr->data;
- GLuint ii = i, jj = j;
- GLuint vlist[2];
- GLuint n;
-
- VB->LastClipped = VB->FirstClipped;
-
-/*
- * We use 6 instances of this code to clip against the 6 planes.
- */
-#define GENERAL_CLIP \
- if (mask & PLANE) { \
- GLfloat dpI = CLIP_DOTPROD( ii ); \
- GLfloat dpJ = CLIP_DOTPROD( jj ); \
- \
- if (DIFFERENT_SIGNS(dpI, dpJ)) { \
- if (NEGATIVE(dpJ)) { \
- GLfloat t = dpI / (dpI - dpJ); \
- VB->ClipMask[jj] |= PLANE; \
- jj = interp( ctx, t, ii, jj, GL_FALSE ); \
- VB->ClipMask[jj] = 0; \
- } else { \
- GLfloat t = dpJ / (dpJ - dpI); \
- VB->ClipMask[ii] |= PLANE; \
- ii = interp( ctx, t, jj, ii, GL_FALSE ); \
- VB->ClipMask[ii] = 0; \
- } \
- } \
- else if (NEGATIVE(dpI)) \
- return; \
- }
-
-#undef CLIP_DOTPROD
-#define PLANE CLIP_RIGHT_BIT
-#define CLIP_DOTPROD(K) (- X(K) + W(K))
-
- GENERAL_CLIP
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#define PLANE CLIP_LEFT_BIT
-#define CLIP_DOTPROD(K) (X(K) + W(K))
-
- GENERAL_CLIP
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#define PLANE CLIP_TOP_BIT
-#define CLIP_DOTPROD(K) (- Y(K) + W(K))
-
- GENERAL_CLIP
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#define PLANE CLIP_BOTTOM_BIT
-#define CLIP_DOTPROD(K) (Y(K) + W(K))
-
- GENERAL_CLIP
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#define PLANE CLIP_FAR_BIT
-#define CLIP_DOTPROD(K) (- Z(K) + W(K))
-
- if (SIZE >= 3) {
- GENERAL_CLIP
- }
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#define PLANE CLIP_NEAR_BIT
-#define CLIP_DOTPROD(K) (Z(K) + W(K))
-
- if (SIZE >=3 ) {
- GENERAL_CLIP
- }
-
-#undef CLIP_DOTPROD
-#undef PLANE
-#undef GENERAL_CLIP
-
-
- if (mask & CLIP_USER_BIT) {
- if ( TAG(userclip_line)( ctx, &ii, &jj, interp ) == 0 )
- return;
- }
-
- vlist[0] = ii;
- vlist[1] = jj;
- n = 2;
-
- /* If necessary, project new vertices.
- */
- {
- GLuint i, j;
- GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
- GLuint start = VB->FirstClipped;
-
- for (i = 0; i < n; i++) {
- j = vlist[i];
- if (j >= start) {
- if (SIZE == 4 && W(j) != 0.0F) {
- GLfloat wInv = 1.0F / W(j);
- proj[j][0] = X(j) * wInv;
- proj[j][1] = Y(j) * wInv;
- proj[j][2] = Z(j) * wInv;
- proj[j][3] = wInv;
- } else {
- proj[j][0] = X(j);
- proj[j][1] = Y(j);
- proj[j][2] = Z(j);
- proj[j][3] = W(j);
- }
- }
- }
- }
-
- if (ctx->Driver.BuildProjectedVertices)
- ctx->Driver.BuildProjectedVertices(ctx,
- VB->FirstClipped,
- VB->LastClipped,
- ~0);
-
-
- /* Render the new line.
- */
- ctx->Driver.LineFunc( ctx, ii, jj, j );
-}
-
-/* We now clip polygon triangles individually. This is necessary to
- * avoid artifacts dependent on where the boundary of the VB falls
- * within the polygon. As a result, there is an upper bound on the
- * number of vertices which may be created, and the test against VB_SIZE
- * is redundant.
- */
-static void TAG(viewclip_polygon)( GLcontext *ctx,
- GLuint n, GLuint vlist[], GLuint pv,
- GLubyte mask )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- interp_func interp = (interp_func) VB->interpfunc;
- GLfloat (*coord)[4] = VB->ClipPtr->data;
- GLuint vlist2[MAX_CLIPPED_VERTICES];
- GLuint *inlist = vlist, *outlist = vlist2;
- GLuint i;
- GLubyte *clipmask = VB->ClipMask;
-
- VB->LastClipped = VB->FirstClipped;
-
- if (mask & CLIP_ALL_BITS) {
-
-#define GENERAL_CLIP \
+#define POLY_CLIP( PLANE, A, B, C, D ) \
+do { \
if (mask & PLANE) { \
- GLuint idxPrev = inlist[n-1]; \
- GLfloat dpPrev = CLIP_DOTPROD(idxPrev); \
+ GLuint idxPrev = inlist[0]; \
+ GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \
GLuint outcount = 0; \
GLuint i; \
- \
- mask &= ~PLANE; \
- \
- for (i = 0; i < n; i++) { \
+ \
+ inlist[n] = inlist[0]; /* prevent rotation of vertices */ \
+ for (i = 1; i <= n; i++) { \
GLuint idx = inlist[i]; \
- GLfloat dp = CLIP_DOTPROD(idx); \
+ GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \
\
+ clipmask[idxPrev] |= PLANE; \
if (!NEGATIVE(dpPrev)) { \
outlist[outcount++] = idxPrev; \
clipmask[idxPrev] &= ~PLANE; \
} \
\
if (DIFFERENT_SIGNS(dp, dpPrev)) { \
- GLuint newvert; \
+ GLuint newvert = VB->LastClipped++; \
+ VB->ClipMask[newvert] = 0; \
+ outlist[outcount++] = newvert; \
if (NEGATIVE(dp)) { \
/* Going out of bounds. Avoid division by zero as we \
* know dp != dpPrev from DIFFERENT_SIGNS, above. \
*/ \
GLfloat t = dp / (dp - dpPrev); \
- newvert = interp( ctx, t, idx, idxPrev, GL_TRUE ); \
- } else { \
+ LINTERP_SZ( t, coord, newvert, idx, idxPrev, SIZE ); \
+ interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \
+ } else { \
/* Coming back in. \
*/ \
GLfloat t = dpPrev / (dpPrev - dp); \
- newvert = interp( ctx, t, idxPrev, idx, GL_FALSE ); \
+ LINTERP_SZ( t, coord, newvert, idxPrev, idx, SIZE ); \
+ interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \
} \
- clipmask[newvert] = mask; \
- outlist[outcount++] = newvert; \
} \
\
idxPrev = idx; \
@@ -377,125 +82,184 @@ static void TAG(viewclip_polygon)( GLcontext *ctx,
outlist = tmp; \
n = outcount; \
} \
- }
-
-
-#define PLANE CLIP_RIGHT_BIT
-#define CLIP_DOTPROD(K) (- X(K) + W(K))
-
- GENERAL_CLIP
-
-#undef CLIP_DOTPROD
-#undef PLANE
-
-
-#define PLANE CLIP_LEFT_BIT
-#define CLIP_DOTPROD(K) (X(K) + W(K))
-
- GENERAL_CLIP
+ } \
+} while (0)
+
+
+#define LINE_CLIP(PLANE, A, B, C, D ) \
+do { \
+ if (mask & PLANE) { \
+ GLfloat dpI = CLIP_DOTPROD( ii, A, B, C, D ); \
+ GLfloat dpJ = CLIP_DOTPROD( jj, A, B, C, D ); \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLuint newvert = VB->LastClipped++; \
+ VB->ClipMask[newvert] = 0; \
+ if (NEGATIVE(dpJ)) { \
+ GLfloat t = dpI / (dpI - dpJ); \
+ VB->ClipMask[jj] |= PLANE; \
+ LINTERP_SZ( t, coord, newvert, ii, jj, SIZE ); \
+ interp( ctx, t, newvert, ii, jj, GL_FALSE ); \
+ jj = newvert; \
+ } else { \
+ GLfloat t = dpJ / (dpJ - dpI); \
+ VB->ClipMask[ii] |= PLANE; \
+ LINTERP_SZ( t, coord, newvert, jj, ii, SIZE ); \
+ interp( ctx, t, newvert, jj, ii, GL_FALSE ); \
+ ii = newvert; \
+ } \
+ } \
+ else if (NEGATIVE(dpI)) \
+ return; \
+ } \
+} while (0)
+
+
+/* Project if necessary.
+ */
+static void TAG(build_proj_verts)( GLcontext *ctx )
+{
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ GLfloat (*coord)[4] = VB->ClipPtr->data;
+ GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
+ GLuint last = VB->LastClipped;
+ GLuint i;
-#undef CLIP_DOTPROD
-#undef PLANE
+ for (i = VB->FirstClipped; i < last; i++) {
+ if (VB->ClipMask[i] == 0) {
+ if (SIZE == 4 && W(i) != 0.0F) {
+ GLfloat wInv = 1.0F / W(i);
+ proj[i][0] = X(i) * wInv;
+ proj[i][1] = Y(i) * wInv;
+ proj[i][2] = Z(i) * wInv;
+ proj[i][3] = wInv;
+ } else {
+ proj[i][0] = X(i);
+ proj[i][1] = Y(i);
+ proj[i][2] = Z(i);
+ proj[i][3] = W(i);
+ }
+ }
+ }
-#define PLANE CLIP_TOP_BIT
-#define CLIP_DOTPROD(K) (- Y(K) + W(K))
+ ctx->Driver.BuildProjectedVertices(ctx,
+ VB->FirstClipped,
+ VB->LastClipped,
+ ~0);
+}
- GENERAL_CLIP
+/* Clip a line against the viewport and user clip planes.
+ */
+static void TAG(clip_line)( GLcontext *ctx,
+ GLuint i, GLuint j,
+ GLubyte mask )
+{
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ interp_func interp = (interp_func) VB->interpfunc;
+ GLfloat (*coord)[4] = VB->ClipPtr->data;
+ GLuint ii = i, jj = j, p;
-#undef CLIP_DOTPROD
-#undef PLANE
+ VB->LastClipped = VB->FirstClipped;
-#define PLANE CLIP_BOTTOM_BIT
-#define CLIP_DOTPROD(K) (Y(K) + W(K))
+ if (mask & 0x3f) {
+ LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
+ LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
+ LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
+ LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
+ LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
+ LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
+ }
- GENERAL_CLIP
+ if (mask & CLIP_USER_BIT) {
+ for (p=0;p<MAX_CLIP_PLANES;p++) {
+ if (ctx->Transform.ClipEnabled[p]) {
+ GLfloat a = ctx->Transform._ClipUserPlane[p][0];
+ GLfloat b = ctx->Transform._ClipUserPlane[p][1];
+ GLfloat c = ctx->Transform._ClipUserPlane[p][2];
+ GLfloat d = ctx->Transform._ClipUserPlane[p][3];
+ LINE_CLIP( CLIP_USER_BIT, a, b, c, d );
+ }
+ }
+ }
-#undef CLIP_DOTPROD
-#undef PLANE
+ TAG(build_proj_verts)( ctx );
-#define PLANE CLIP_FAR_BIT
-#define CLIP_DOTPROD(K) (- Z(K) + W(K))
+ if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
+ VB->copypvfunc( ctx, jj, j );
- if (SIZE >= 3) {
- GENERAL_CLIP
- }
+ /* Render the new line.
+ */
+ ctx->Driver.LineFunc( ctx, ii, jj );
-#undef CLIP_DOTPROD
-#undef PLANE
+}
-#define PLANE CLIP_NEAR_BIT
-#define CLIP_DOTPROD(K) (Z(K) + W(K))
- if (SIZE >=3 ) {
- GENERAL_CLIP
- }
+/* Clip a triangle or quad against the viewport and user clip planes.
+ */
+static void TAG(clip_polygon)( GLcontext *ctx,
+ GLuint n, GLuint vlist[],
+ GLubyte mask )
+{
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ interp_func interp = (interp_func) VB->interpfunc;
+ GLfloat (*coord)[4] = VB->ClipPtr->data;
+ GLuint pv = vlist[0];
+ GLuint vlist2[MAX_CLIPPED_VERTICES];
+ GLuint *inlist = vlist, *outlist = vlist2;
+ GLuint p;
+ GLubyte *clipmask = VB->ClipMask;
-#undef CLIP_DOTPROD
-#undef PLANE
-#undef GENERAL_CLIP
+ VB->LastClipped = VB->FirstClipped;
- if (inlist != vlist)
- for (i = 0 ; i < n ; i++)
- vlist[i] = inlist[i];
+ if (mask & 0x3f) {
+ POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
+ POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
+ POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
+ POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
+ POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
+ POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
}
- /* Clip against user clipping planes in clip space.
- */
if (mask & CLIP_USER_BIT) {
- n = TAG(userclip_polygon)( ctx, n, vlist, interp );
- if (n < 3) return;
+ for (p=0;p<MAX_CLIP_PLANES;p++) {
+ if (ctx->Transform.ClipEnabled[p]) {
+ GLfloat a = ctx->Transform._ClipUserPlane[p][0];
+ GLfloat b = ctx->Transform._ClipUserPlane[p][1];
+ GLfloat c = ctx->Transform._ClipUserPlane[p][2];
+ GLfloat d = ctx->Transform._ClipUserPlane[p][3];
+ POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
+ }
+ }
}
- /* Project if necessary.
- */
- {
- GLuint i;
- GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
- GLuint first = VB->FirstClipped;
-
- for (i = 0; i < n; i++) {
- GLuint j = vlist[i];
- if (j >= first) {
- if (SIZE == 4 && W(j) != 0.0F) {
- GLfloat wInv = 1.0F / W(j);
- proj[j][0] = X(j) * wInv;
- proj[j][1] = Y(j) * wInv;
- proj[j][2] = Z(j) * wInv;
- proj[j][3] = wInv;
- } else {
- proj[j][0] = X(j);
- proj[j][1] = Y(j);
- proj[j][2] = Z(j);
- proj[j][3] = W(j);
- }
- }
+ if (ctx->_TriangleCaps & DD_FLATSHADE) {
+ if (pv != inlist[0]) {
+ ASSERT( inlist[0] >= VB->FirstClipped );
+ VB->copypvfunc( ctx, inlist[0], pv );
}
}
- if (ctx->Driver.BuildProjectedVertices)
- ctx->Driver.BuildProjectedVertices(ctx,
- VB->FirstClipped,
- VB->LastClipped,
- ~0);
+ TAG(build_proj_verts)( ctx );
/* Render the new vertices as an unclipped polygon.
- * Argh - need to pass in pv...
*/
{
GLuint *tmp = VB->Elts;
- VB->Elts = vlist;
- render_poly_pv_raw_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END, pv );
+ VB->Elts = inlist;
+ ctx->Driver.RenderTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
VB->Elts = tmp;
}
}
+
+
#undef W
#undef Z
#undef Y
#undef X
#undef SIZE
#undef TAG
-#undef INSIDE
-#undef OUTSIDE
+#undef POLY_CLIP
+#undef LINE_CLIP
diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c
index b3fef23501..2616d294d3 100644
--- a/src/mesa/tnl/t_vb_render.c
+++ b/src/mesa/tnl/t_vb_render.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_render.c,v 1.5 2001/01/03 15:59:31 brianp Exp $ */
+/* $Id: t_vb_render.c,v 1.6 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -22,6 +22,9 @@
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ * Keith Whitwell <keithw@valinux.com>
*/
@@ -33,11 +36,16 @@
* and triangle rasterizers via the function pointers:
*
* context->Driver.BuildProjectedVertices()
+ *
* context->Driver.PointsFunc()
* context->Driver.LineFunc()
* context->Driver.TriangleFunc()
* context->Driver.QuadFunc()
*
+ * context->Driver.RenderTabVerts[]
+ * context->Driver.RenderTabElts[]
+ *
+ * None of these may be null.
*/
@@ -55,9 +63,6 @@
#include "t_pipeline.h"
-typedef GLuint (*interp_func)( GLcontext *ctx,
- GLfloat t, GLuint in, GLuint out,
- GLboolean force_boundary );
typedef void (*clip_line_func)( GLcontext *ctx,
GLuint i, GLuint j,
@@ -65,13 +70,8 @@ typedef void (*clip_line_func)( GLcontext *ctx,
typedef void (*clip_poly_func)( GLcontext *ctx,
GLuint n, GLuint vlist[],
- GLuint pv, GLubyte mask );
-
+ GLubyte mask );
-typedef void (*render_func)( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags );
@@ -79,33 +79,19 @@ struct render_stage_data {
/* Clipping functions for current state.
*/
- interp_func interp; /* Clip interpolation function */
- GLuint _ClipInputs; /* Inputs referenced by interpfunc */
-
+ interp_func interp; /* Clip interpolation function */
+ copy_pv_func copypv; /* Flatshade fixup function */
+ GLuint _ClipInputs; /* Inputs referenced by interpfunc */
};
#define RENDER_STAGE_DATA(stage) ((struct render_stage_data *)stage->private)
-static void render_poly_pv_raw_elts( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags,
- GLuint pv );
/**********************************************************************/
/* Interpolate between pairs of vertices */
/**********************************************************************/
-#define INTERP_RGBA 0x1
-#define INTERP_TEX 0x2
-#define INTERP_INDEX 0x4
-#define INTERP_SPEC 0x8
-#define INTERP_FOG 0x10
-#define INTERP_EDGE 0x20
-#define MAX_INTERP 0x40
-
-
#define LINTERP_SZ( t, vec, to, a, b, sz ) \
do { \
switch (sz) { \
@@ -146,8 +132,50 @@ do { \
-static interp_func interp_tab[0x80];
+#define INTERP_RGBA 0x1
+#define INTERP_TEX 0x2
+#define INTERP_INDEX 0x4
+#define INTERP_SPEC 0x8
+#define INTERP_FOG 0x10
+#define INTERP_EDGE 0x20
+#define MAX_INTERP 0x40
+
+static interp_func interp_tab[MAX_INTERP];
+static copy_pv_func copy_tab[MAX_INTERP];
+
+
+#define IND (0)
+#define NAME interp_none
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_FOG)
+#define NAME interp_FOG
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_TEX)
+#define NAME interp_TEX
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_FOG|INTERP_TEX)
+#define NAME interp_FOG_TEX
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_EDGE)
+#define NAME interp_EDGE
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_FOG|INTERP_EDGE)
+#define NAME interp_FOG_EDGE
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_TEX|INTERP_EDGE)
+#define NAME interp_TEX_EDGE
+#include "t_vb_interptmp.h"
+
+#define IND (INTERP_FOG|INTERP_TEX|INTERP_EDGE)
+#define NAME interp_FOG_TEX_EDGE
+#include "t_vb_interptmp.h"
#define IND (INTERP_RGBA)
#define NAME interp_RGBA
@@ -246,15 +274,34 @@ static interp_func interp_tab[0x80];
#include "t_vb_interptmp.h"
+#define IND (INTERP_RGBA)
+#define NAME copy_RGBA
+#include "t_vb_flattmp.h"
+
+#define IND (INTERP_RGBA|INTERP_SPEC)
+#define NAME copy_RGBA_SPEC
+#include "t_vb_flattmp.h"
+
+#define IND (INTERP_INDEX)
+#define NAME copy_INDEX
+#include "t_vb_flattmp.h"
+
+
+
-static GLuint interp_invalid( GLcontext *ctx,
- GLfloat t,
- GLuint in, GLuint out,
- GLboolean boundary )
+static void interp_invalid( GLcontext *ctx,
+ GLfloat t,
+ GLuint dst, GLuint in, GLuint out,
+ GLboolean boundary )
{
(void)(ctx && t && in && out && boundary);
fprintf(stderr, "Invalid interpolation function in t_vbrender.c\n");
- return in;
+}
+
+static void copy_invalid( GLcontext *ctx, GLuint dst, GLuint src )
+{
+ (void)(ctx && dst && src);
+ fprintf(stderr, "Invalid copy function in t_vbrender.c\n");
}
@@ -266,8 +313,19 @@ static void interp_init( void )
* the non-implemented combinations are reachable, but this gives
* some safety from crashes.
*/
- for (i = 0 ; i < Elements(interp_tab) ; i++)
+ for (i = 0 ; i < Elements(interp_tab) ; i++) {
interp_tab[i] = interp_invalid;
+ copy_tab[i] = copy_invalid;
+ }
+
+ interp_tab[0] = interp_none;
+ interp_tab[INTERP_FOG] = interp_FOG;
+ interp_tab[INTERP_TEX] = interp_TEX;
+ interp_tab[INTERP_FOG|INTERP_TEX] = interp_FOG_TEX;
+ interp_tab[INTERP_EDGE] = interp_EDGE;
+ interp_tab[INTERP_FOG|INTERP_EDGE] = interp_FOG_EDGE;
+ interp_tab[INTERP_TEX|INTERP_EDGE] = interp_TEX_EDGE;
+ interp_tab[INTERP_FOG|INTERP_TEX|INTERP_EDGE] = interp_FOG_TEX_EDGE;
interp_tab[INTERP_RGBA] = interp_RGBA;
interp_tab[INTERP_RGBA|INTERP_SPEC] = interp_RGBA_SPEC;
@@ -276,7 +334,8 @@ static void interp_init( void )
interp_tab[INTERP_RGBA|INTERP_TEX] = interp_RGBA_TEX;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX] = interp_RGBA_SPEC_TEX;
interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX] = interp_RGBA_FOG_TEX;
- interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX] = interp_RGBA_SPEC_FOG_TEX;
+ interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX] =
+ interp_RGBA_SPEC_FOG_TEX;
interp_tab[INTERP_INDEX] = interp_INDEX;
interp_tab[INTERP_FOG|INTERP_INDEX] = interp_FOG_INDEX;
interp_tab[INTERP_TEX|INTERP_INDEX] = interp_TEX_INDEX;
@@ -284,15 +343,26 @@ static void interp_init( void )
interp_tab[INTERP_RGBA|INTERP_EDGE] = interp_RGBA_EDGE;
interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_EDGE] = interp_RGBA_SPEC_EDGE;
interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_EDGE] = interp_RGBA_FOG_EDGE;
- interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE] = interp_RGBA_SPEC_FOG_EDGE;
+ interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE] =
+ interp_RGBA_SPEC_FOG_EDGE;
interp_tab[INTERP_RGBA|INTERP_TEX|INTERP_EDGE] = interp_RGBA_TEX_EDGE;
- interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE] = interp_RGBA_SPEC_TEX_EDGE;
- interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE] = interp_RGBA_FOG_TEX_EDGE;
- interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE] = interp_RGBA_SPEC_FOG_TEX_EDGE;
+ interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE] =
+ interp_RGBA_SPEC_TEX_EDGE;
+ interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE] =
+ interp_RGBA_FOG_TEX_EDGE;
+ interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE] =
+ interp_RGBA_SPEC_FOG_TEX_EDGE;
interp_tab[INTERP_INDEX|INTERP_EDGE] = interp_INDEX_EDGE;
interp_tab[INTERP_FOG|INTERP_INDEX|INTERP_EDGE] = interp_FOG_INDEX_EDGE;
interp_tab[INTERP_TEX|INTERP_INDEX|INTERP_EDGE] = interp_TEX_INDEX_EDGE;
- interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE] = interp_FOG_TEX_INDEX_EDGE;
+ interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE] =
+ interp_FOG_TEX_INDEX_EDGE;
+
+
+ copy_tab[INTERP_RGBA] = copy_RGBA;
+ copy_tab[INTERP_RGBA|INTERP_SPEC] = copy_RGBA_SPEC;
+ copy_tab[INTERP_INDEX] = copy_INDEX;
+
}
@@ -301,12 +371,15 @@ static void interp_init( void )
/**********************************************************************/
-#if 0
-#define NEGATIVE(x) ((*(int *)&x)<0)
-#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#if defined(USE_IEEE)
+#define NEGATIVE(x) ((*(GLuint *)&x) & (1<<31))
+#define DIFFERENT_SIGNS(x,y) (((*(GLuint *)&x)^(*(GLuint *)&y)) & (1<<31))
#else
#define NEGATIVE(x) (x < 0)
-#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
+/* Could just use (x*y<0) except for the flatshading requirements.
+ * Maybe there's a better way?
+ */
#endif
#define W(i) coord[i][3]
@@ -336,176 +409,151 @@ static void interp_init( void )
static clip_poly_func clip_poly_tab[5] = {
0,
0,
- viewclip_polygon_2,
- viewclip_polygon_3,
- viewclip_polygon_4
+ clip_polygon_2,
+ clip_polygon_3,
+ clip_polygon_4
};
static clip_line_func clip_line_tab[5] = {
0,
0,
- viewclip_line_2,
- viewclip_line_3,
- viewclip_line_4
+ clip_line_2,
+ clip_line_3,
+ clip_line_4
};
-
/**********************************************************************/
-/* Clip and render single primitives */
-/**********************************************************************/
-
-
-
-static INLINE void draw_line(GLcontext *ctx, GLuint v1, GLuint v2 )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLubyte c1 = VB->ClipMask[v1], c2 = VB->ClipMask[v2];
- GLubyte ormask = c1|c2;
- if (!ormask)
- ctx->Driver.LineFunc( ctx, v1, v2, v2 );
- else if (!(c1 & c2 & 0x3f))
- clip_line_tab[VB->ClipPtr->size]( ctx, v1, v2, ormask );
-}
-
-static INLINE void draw_triangle(GLcontext *ctx,
- GLuint v1, GLuint v2, GLuint v3,
- GLuint pv )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLubyte c1 = VB->ClipMask[v1], c2 = VB->ClipMask[v2], c3 = VB->ClipMask[v3];
- GLubyte ormask = c1|c2|c3;
- if (!ormask)
- ctx->Driver.TriangleFunc( ctx, v1, v2, v3, pv );
- else if (!(c1 & c2 & c3 & 0x3f)) {
- GLuint vlist[MAX_CLIPPED_VERTICES];
- ASSIGN_3V(vlist, v1, v2, v3 );
- clip_poly_tab[VB->ClipPtr->size]( ctx, 3, vlist, pv, ormask );
- }
-}
-
-
-static INLINE void draw_quad( GLcontext *ctx,
- GLuint v1, GLuint v2, GLuint v3,
- GLuint v4, GLuint pv )
-{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLubyte c1 = VB->ClipMask[v1], c2 = VB->ClipMask[v2];
- GLubyte c3 = VB->ClipMask[v3], c4 = VB->ClipMask[v4];
- GLubyte ormask = c1|c2|c3|c4;
- if (!ormask)
- ctx->Driver.QuadFunc( ctx, v1, v2, v3, v4, pv );
- else if (!(c1 & c2 & c3 & c4 & 0x3f)) {
- GLuint vlist[MAX_CLIPPED_VERTICES];
- ASSIGN_4V(vlist, v1, v2, v3, v4 );
- clip_poly_tab[VB->ClipPtr->size]( ctx, 4, vlist, pv, ormask );
- }
-}
-
-
-/**********************************************************************/
-/* Clip and render whole begin/end objects */
+/* Clip and render whole begin/end objects */
/**********************************************************************/
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
-#define EDGEFLAG_GET(idx) VB->EdgeFlagPtr->data[idx]
-#define EDGEFLAG_SET(idx, val) VB->EdgeFlagPtr->data[idx] = val
+#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
+#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
-/* Vertices, no clipping.
+/* Vertices, with the possibility of clipping.
*/
#define RENDER_POINTS( start, count ) \
- ctx->Driver.PointsFunc( ctx, start, count-1 )
+ ctx->Driver.PointsFunc( ctx, start, count )
-#define RENDER_LINE( i1, i ) \
- ctx->Driver.LineFunc( ctx, i1, i, i )
+#define RENDER_LINE( v1, v2 ) \
+do { \
+ GLubyte c1 = mask[v1], c2 = mask[v2]; \
+ GLubyte ormask = c1|c2; \
+ if (!ormask) \
+ LineFunc( ctx, v1, v2 ); \
+ else if (!(c1 & c2 & 0x3f)) \
+ clip_line_tab[sz]( ctx, v1, v2, ormask ); \
+} while (0)
-#define RENDER_TRI( i2, i1, i, pv, parity ) \
+#define RENDER_TRI( v1, v2, v3 ) \
do { \
- if (parity) \
- ctx->Driver.TriangleFunc( ctx, i1, i2, i, pv ); \
- else \
- ctx->Driver.TriangleFunc( ctx, i2, i1, i, pv ); \
+ GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \
+ GLubyte ormask = c1|c2|c3; \
+ if (!ormask) \
+ TriangleFunc( ctx, v1, v2, v3 ); \
+ else if (!(c1 & c2 & c3 & 0x3f)) { \
+ GLuint vlist[MAX_CLIPPED_VERTICES]; \
+ ASSIGN_3V(vlist, v3, v1, v2 ); \
+ clip_poly_tab[sz]( ctx, 3, vlist, ormask ); \
+ } \
} while (0)
-#define RENDER_QUAD( i3, i2, i1, i, pv ) \
- ctx->Driver.QuadFunc( ctx, i3, i2, i1, i, pv );
-
-#define TAG(x) x##_raw
+#define RENDER_QUAD( v1, v2, v3, v4 ) \
+do { \
+ GLubyte c1 = mask[v1], c2 = mask[v2]; \
+ GLubyte c3 = mask[v3], c4 = mask[v4]; \
+ GLubyte ormask = c1|c2|c3|c4; \
+ if (!ormask) \
+ QuadFunc( ctx, v1, v2, v3, v4 ); \
+ else if (!(c1 & c2 & c3 & c4 & 0x3f)) { \
+ GLuint vlist[MAX_CLIPPED_VERTICES]; \
+ ASSIGN_4V(vlist, v4, v1, v2, v3 ); \
+ clip_poly_tab[sz]( ctx, 4, vlist, ormask ); \
+ } \
+} while (0)
-#define LOCAL_VARS \
- struct vertex_buffer *VB = &(TNL_CONTEXT(ctx)->vb); \
- (void) VB;
+#define LOCAL_VARS \
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; \
+ const GLuint * const elt = VB->Elts; \
+ const GLubyte *mask = VB->ClipMask; \
+ const GLuint sz = VB->ClipPtr->size; \
+ const line_func LineFunc = ctx->Driver.LineFunc; \
+ const triangle_func TriangleFunc = ctx->Driver.TriangleFunc; \
+ const quad_func QuadFunc = ctx->Driver.QuadFunc; \
+ (void) (LineFunc && TriangleFunc && QuadFunc); \
+ (void) elt; (void) mask; (void) sz;
+
+#define TAG(x) clip_##x##_verts
#define RESET_STIPPLE ctx->Driver.ResetLineStipple( ctx )
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE;
#define PRESERVE_VB_DEFS
#include "t_vb_rendertmp.h"
-/* Elts, no clipping.
+
+/* Elts, with the possibility of clipping.
*/
#undef ELT
#undef TAG
-#undef LOCAL_VARS
-#define TAG(x) x##_raw_elts
#define ELT(x) elt[x]
-#define LOCAL_VARS \
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; \
- const GLuint * const elt = VB->Elts; \
- (void) elt;
+#define TAG(x) clip_##x##_elts
#include "t_vb_rendertmp.h"
+/**********************************************************************/
+/* Render whole begin/end objects */
+/**********************************************************************/
+#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
+#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
+#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
-/* Vertices, with the possibility of clipping.
+
+/* Vertices, no clipping.
*/
-#define RENDER_POINTS( start, count ) \
- ctx->Driver.PointsFunc( ctx, start, count-1 )
+#define RENDER_POINTS( start, count ) \
+ ctx->Driver.PointsFunc( ctx, start, count )
-#define RENDER_LINE( i1, i ) \
- draw_line( ctx, i1, i )
+#define RENDER_LINE( v1, v2 ) \
+ LineFunc( ctx, v1, v2 )
-#define RENDER_TRI( i2, i1, i, pv, parity) \
-do { \
- GLuint e2=i2, e1=i1; \
- if (parity) { GLuint t=e2; e2=e1; e1=t; } \
- draw_triangle(ctx,e2,e1,i,pv); \
-} while (0)
+#define RENDER_TRI( v1, v2, v3 ) \
+ TriangleFunc( ctx, v1, v2, v3 )
-#define RENDER_QUAD( i3, i2, i1, i, pv) \
- draw_quad(ctx,i3,i2,i1,i,pv)
+#define RENDER_QUAD( v1, v2, v3, v4 ) \
+ QuadFunc( ctx, v1, v2, v3, v4 )
+#define TAG(x) _tnl_##x##_verts
#define LOCAL_VARS \
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; \
- (void)VB;
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; \
+ const GLuint * const elt = VB->Elts; \
+ const line_func LineFunc = ctx->Driver.LineFunc; \
+ const triangle_func TriangleFunc = ctx->Driver.TriangleFunc; \
+ const quad_func QuadFunc = ctx->Driver.QuadFunc; \
+ (void) (LineFunc && TriangleFunc && QuadFunc); \
+ (void) elt;
-#define TAG(x) x##_clipped
#define RESET_STIPPLE ctx->Driver.ResetLineStipple( ctx )
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE;
+#define RENDER_TAB_QUALIFIER
#define PRESERVE_VB_DEFS
#include "t_vb_rendertmp.h"
-
-/* Elts, with the possibility of clipping.
+/* Elts, no clipping.
*/
#undef ELT
-#undef TAG
-#undef LOCAL_VARS
+#define TAG(x) _tnl_##x##_elts
#define ELT(x) elt[x]
-#define LOCAL_VARS \
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; \
- const GLuint * const elt = VB->Elts; \
- (void) elt;
-#define TAG(x) x##_clipped_elts
-
#include "t_vb_rendertmp.h"
+
/**********************************************************************/
/* Clip and render whole vertex buffers */
/**********************************************************************/
@@ -520,40 +568,29 @@ static GLboolean run_render( GLcontext *ctx,
render_func *tab;
GLint pass = 0;
-/* return GL_FALSE; */
+ VB->interpfunc = RENDER_STAGE_DATA(stage)->interp;
+ VB->copypvfunc = RENDER_STAGE_DATA(stage)->copypv;
- VB->interpfunc = (void *)RENDER_STAGE_DATA(stage)->interp;
+ /* Allow the drivers to lock before projected verts are built so
+ * that window coordinates are guarenteed not to change before
+ * rendering.
+ */
+ if (ctx->Driver.RenderStart)
+ ctx->Driver.RenderStart( ctx );
- if (new_inputs) {
- GLuint importable = new_inputs & VB->importable_data;
- GLuint interested = 0;
-
- if (VB->ClipOrMask)
- interested = ~0;
-
- if (ctx->_TriangleCaps & DD_TRI_UNFILLED)
- interested |= VERT_EDGE;
-
- importable &= interested;
-
- if (importable)
- VB->import_data( ctx, importable, VEC_NOT_WRITEABLE|VEC_BAD_STRIDE);
-
- if (ctx->Driver.BuildProjectedVertices)
- ctx->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs);
- }
+ if (VB->ClipOrMask) {
+ tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
- /* Rendering is considered a side-effect, and must be repeated each
- * time the stage is run, even if no inputs have changed.
- */
- if (VB->Elts) {
- tab = VB->ClipOrMask ? render_tab_clipped_elts : render_tab_raw_elts;
- } else {
- tab = VB->ClipOrMask ? render_tab_clipped : render_tab_raw;
+ if (new_inputs & VB->importable_data)
+ VB->import_data( ctx,
+ new_inputs & VB->importable_data,
+ VEC_NOT_WRITEABLE|VEC_BAD_STRIDE);
}
+ else {
+ tab = VB->Elts ? ctx->Driver.RenderTabElts : ctx->Driver.RenderTabVerts;
+ }
- if (ctx->Driver.RenderStart)
- ctx->Driver.RenderStart( ctx );
+ ctx->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs );
do
{
@@ -564,9 +601,6 @@ static GLboolean run_render( GLcontext *ctx,
length= VB->PrimitiveLength[i];
ASSERT(length || (flags & PRIM_LAST));
ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1);
-/* fprintf(stderr, "render %s %d..%d\n", */
-/* _mesa_prim_name[flags & PRIM_MODE_MASK], */
-/* i, i+length); */
if (length)
tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
}
@@ -595,6 +629,7 @@ static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
{
struct render_stage_data *store = RENDER_STAGE_DATA(stage);
GLuint interp = 0;
+ GLuint copy = 0;
GLuint inputs = VERT_CLIP;
GLuint i;
@@ -643,6 +678,12 @@ static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
inputs |= VERT_TEX_ANY;
}
+ if (ctx->_TriangleCaps & DD_FLATSHADE) {
+ copy = interp & (INTERP_RGBA|INTERP_SPEC|INTERP_INDEX);
+ interp &= ~copy;
+ }
+
+ store->copypv = copy_tab[copy];
store->interp = interp_tab[interp];
stage->inputs = inputs;
}
@@ -688,6 +729,7 @@ const struct gl_pipeline_stage _tnl_render_stage =
"render",
(_NEW_BUFFERS |
_DD_NEW_SEPERATE_SPECULAR |
+ _DD_NEW_FLATSHADE |
_NEW_TEXTURE|
_NEW_LIGHT|
_NEW_POINT|
diff --git a/src/mesa/tnl/t_vb_rendertmp.h b/src/mesa/tnl/t_vb_rendertmp.h
index 5712d342d2..9c9271ff22 100644
--- a/src/mesa/tnl/t_vb_rendertmp.h
+++ b/src/mesa/tnl/t_vb_rendertmp.h
@@ -1,4 +1,4 @@
-/* $Id: t_vb_rendertmp.h,v 1.3 2000/12/28 22:11:06 keithw Exp $ */
+/* $Id: t_vb_rendertmp.h,v 1.4 2001/01/05 02:26:49 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -60,6 +60,10 @@
#define ELT(x) x
#endif
+#ifndef RENDER_TAB_QUALIFIER
+#define RENDER_TAB_QUALIFIER static
+#endif
+
static void TAG(render_points)( GLcontext *ctx,
GLuint start,
GLuint count,
@@ -68,7 +72,6 @@ static void TAG(render_points)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
RESET_OCCLUSION;
INIT(GL_POINTS);
RENDER_POINTS( start, count );
@@ -84,7 +87,6 @@ static void TAG(render_lines)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
RESET_OCCLUSION;
INIT(GL_LINES);
for (j=start+1; j<count; j+=2 ) {
@@ -104,7 +106,6 @@ static void TAG(render_line_strip)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
RESET_OCCLUSION;
INIT(GL_LINES);
@@ -128,7 +129,6 @@ static void TAG(render_line_loop)( GLcontext *ctx,
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
RESET_OCCLUSION;
INIT(GL_LINES);
@@ -160,18 +160,17 @@ static void TAG(render_triangles)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2; j<count; j+=3) {
/* Leave the edgeflags as supplied by the user.
*/
- RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j), ELT(j), 0 );
+ RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
RESET_STIPPLE;
}
} else {
for (j=start+2; j<count; j+=3) {
- RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j), ELT(j), 0 );
+ RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
}
}
POSTFIX;
@@ -191,15 +190,11 @@ static void TAG(render_tri_strip)( GLcontext *ctx,
if (TEST_PRIM_PARITY(flags))
parity = 1;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++,parity^=1) {
- /* All edges are boundary. Set edgeflags to 1, draw the
- * triangle, and restore them to the original values.
- */
- GLuint ej2 = ELT(j-2);
- GLuint ej1 = ELT(j-1);
+ GLuint ej2 = ELT(j-2+parity);
+ GLuint ej1 = ELT(j-1-parity);
GLuint ej = ELT(j);
GLboolean ef2 = EDGEFLAG_GET( ej2 );
GLboolean ef1 = EDGEFLAG_GET( ej1 );
@@ -207,15 +202,15 @@ static void TAG(render_tri_strip)( GLcontext *ctx,
EDGEFLAG_SET( ej2, GL_TRUE );
EDGEFLAG_SET( ej1, GL_TRUE );
EDGEFLAG_SET( ej, GL_TRUE );
- RENDER_TRI( ej2, ej1, ej, ej, parity );
+ RENDER_TRI( ej2, ej1, ej );
EDGEFLAG_SET( ej2, ef2 );
EDGEFLAG_SET( ej1, ef1 );
EDGEFLAG_SET( ej, ef );
RESET_STIPPLE;
}
} else {
- for (j=start+2;j<count;j++,parity^=1) {
- RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j), ELT(j), parity );
+ for (j=start+2; j<count ; j++, parity^=1) {
+ RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
}
}
POSTFIX;
@@ -231,7 +226,6 @@ static void TAG(render_tri_fan)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++) {
@@ -246,7 +240,7 @@ static void TAG(render_tri_fan)( GLcontext *ctx,
EDGEFLAG_SET( ejs, GL_TRUE );
EDGEFLAG_SET( ej1, GL_TRUE );
EDGEFLAG_SET( ej, GL_TRUE );
- RENDER_TRI( ejs, ej1, ej, ej, 0);
+ RENDER_TRI( ejs, ej1, ej);
EDGEFLAG_SET( ejs, efs );
EDGEFLAG_SET( ej1, ef1 );
EDGEFLAG_SET( ej, ef );
@@ -254,7 +248,7 @@ static void TAG(render_tri_fan)( GLcontext *ctx,
}
} else {
for (j=start+2;j<count;j++) {
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(j), 0 );
+ RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
}
}
@@ -262,22 +256,15 @@ static void TAG(render_tri_fan)( GLcontext *ctx,
}
-/* This is a bit of a hack. Clipping produces polygons and really
- * wants to use this function to render them (in particular to get the
- * edgeflags right). However, the rule that pv==start for polys
- * doens't hold there, hence the extra arg and the wrapper below.
- */
-static void TAG(render_poly_pv)( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags,
- GLuint pv )
+static void TAG(render_poly)( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint flags )
{
GLuint j = start+2;
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
GLboolean efstart = EDGEFLAG_GET( ELT(start) );
@@ -300,7 +287,7 @@ static void TAG(render_poly_pv)( GLcontext *ctx,
if (j<count-1) {
GLboolean ef = EDGEFLAG_GET( ELT(j) );
EDGEFLAG_SET( ELT(j), GL_FALSE );
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
EDGEFLAG_SET( ELT(j), ef );
j++;
@@ -311,7 +298,7 @@ static void TAG(render_poly_pv)( GLcontext *ctx,
for (;j<count-1;j++) {
GLboolean efj = EDGEFLAG_GET( ELT(j) );
EDGEFLAG_SET( ELT(j), GL_FALSE );
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
EDGEFLAG_SET( ELT(j), efj );
}
}
@@ -319,7 +306,7 @@ static void TAG(render_poly_pv)( GLcontext *ctx,
/* Draw the last or only triangle
*/
if (j < count)
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(pv), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
/* Restore the first and last edgeflags:
*/
@@ -332,21 +319,12 @@ static void TAG(render_poly_pv)( GLcontext *ctx,
}
else {
for (j=start+2;j<count;j++) {
- RENDER_TRI( ELT(start), ELT(j-1), ELT(j), ELT(start), 0 );
+ RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
}
}
POSTFIX;
}
-static void TAG(render_poly)( GLcontext *ctx,
- GLuint start,
- GLuint count,
- GLuint flags )
-{
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
- TAG(render_poly_pv)( ctx, start, count, flags, start );
-}
-
static void TAG(render_quads)( GLcontext *ctx,
GLuint start,
GLuint count,
@@ -356,18 +334,17 @@ static void TAG(render_quads)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+3; j<count; j+=4) {
/* Use user-specified edgeflags for quads.
*/
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j), ELT(j) );
+ RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
RESET_STIPPLE;
}
} else {
for (j=start+3; j<count; j+=4) {
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j), ELT(j) );
+ RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
}
}
POSTFIX;
@@ -382,7 +359,6 @@ static void TAG(render_quad_strip)( GLcontext *ctx,
LOCAL_VARS;
(void) flags;
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
INIT(GL_POLYGON);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+3;j<count;j+=2) {
@@ -397,7 +373,7 @@ static void TAG(render_quad_strip)( GLcontext *ctx,
EDGEFLAG_SET( ELT(j-2), GL_TRUE );
EDGEFLAG_SET( ELT(j-1), GL_TRUE );
EDGEFLAG_SET( ELT(j), GL_TRUE );
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j), ELT(j-1), ELT(j) );
+ RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
EDGEFLAG_SET( ELT(j-3), ef3 );
EDGEFLAG_SET( ELT(j-2), ef2 );
EDGEFLAG_SET( ELT(j-1), ef1 );
@@ -406,7 +382,7 @@ static void TAG(render_quad_strip)( GLcontext *ctx,
}
} else {
for (j=start+3;j<count;j+=2) {
- RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j), ELT(j-1), ELT(j) );
+ RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
}
}
POSTFIX;
@@ -417,14 +393,13 @@ static void TAG(render_noop)( GLcontext *ctx,
GLuint count,
GLuint flags )
{
-/* fprintf(stderr, "%s %d..%d\n", __FUNCTION__, start, count); */
(void)(ctx && start && count && flags);
}
-static void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
- GLuint,
- GLuint,
- GLuint) =
+RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
{
TAG(render_points),
TAG(render_lines),
@@ -452,6 +427,7 @@ static void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
#undef RESET_STIPPLE
#undef DBG
#undef ELT
+#undef RENDER_TAB_QUALIFIER
#endif
#ifndef PRESERVE_TAG