summaryrefslogtreecommitdiff
path: root/src/mesa/tnl/t_vb_render.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2001-01-05 02:26:48 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2001-01-05 02:26:48 +0000
commit58e991705392a2e17a1c8b034f4083a0adaf1943 (patch)
tree828804ca2671809e92a10642030ecd2d21a27b6d /src/mesa/tnl/t_vb_render.c
parentf22c04cdaec47dfef1068af0e90822062478631b (diff)
Remove 'pv' parameter from Line/Tri/Point funcs. The provoking vertex
is always the last vertex parameter. Modify clipping to preserve pv colors. Modify swrast and X11 driver to expect the pv in the last vertex (was looking in the first vertex previously). Remove all handling of flatshading from swrast_setup. Allow drivers to override the unclipped render tabs in tnl_render_stage directly. (Like in 3.4). Removed fxsimplerender stage. Modified t_vb_rendertmp.h to remove the need for 'parity' arguments in RENDER_TRI macros.
Diffstat (limited to 'src/mesa/tnl/t_vb_render.c')
-rw-r--r--src/mesa/tnl/t_vb_render.c416
1 files changed, 229 insertions, 187 deletions
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|