diff options
author | Keith Whitwell <[email protected]> | 2001-04-30 21:08:51 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2001-04-30 21:08:51 +0000 |
commit | 0e14d6d68eae5b9a3f8d21d63d8129db947e3580 (patch) | |
tree | d13e7d5bbac6a09c4e2eaa82013d4ef2e2cea4c5 | |
parent | 16837e4219e03df36c34f08cee1967b946c44536 (diff) |
Lots more eval fixes
-rw-r--r-- | src/mesa/drivers/common/t_dd_vb.c | 6 | ||||
-rw-r--r-- | src/mesa/main/enums.c | 4 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.h | 7 | ||||
-rw-r--r-- | src/mesa/tnl/t_eval_api.c | 20 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_alloc.c | 34 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_api.c | 41 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_dlist.c | 47 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_elt.c | 4 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_eval.c | 175 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_eval.h | 5 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_exec.c | 142 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_fixup.c | 222 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_fixup.h | 7 |
13 files changed, 407 insertions, 307 deletions
diff --git a/src/mesa/drivers/common/t_dd_vb.c b/src/mesa/drivers/common/t_dd_vb.c index e3bb890365d..97be42d7e89 100644 --- a/src/mesa/drivers/common/t_dd_vb.c +++ b/src/mesa/drivers/common/t_dd_vb.c @@ -1,4 +1,4 @@ -/* $Id: t_dd_vb.c,v 1.12 2001/04/29 08:48:43 keithw Exp $ */ +/* $Id: t_dd_vb.c,v 1.13 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -39,6 +39,10 @@ #define LOCALVARS #endif +#ifndef CHECK_HW_DIVIDE +#define CHECK_HW_DIVIDE 1 +#endif + /* These don't need to be duplicated, but there's currently nowhere * really convenient to put them. Need to build some actual .o files in * this directory? diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index 8510ce81058..7fe9d94c161 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -1,4 +1,4 @@ -/* $Id: enums.c,v 1.18 2001/04/17 21:25:53 brianp Exp $ */ +/* $Id: enums.c,v 1.19 2001/04/30 21:08:51 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -925,7 +925,7 @@ const char *_mesa_lookup_enum_by_nr( int nr ) } else { /* this isn't re-entrant safe, no big deal here */ - sprintf(token_tmp, "0x%x\n", nr); + sprintf(token_tmp, "0x%x", nr); return token_tmp; } } diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index 5b57fe86354..d5fc43fe4e2 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.21 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_context.h,v 1.22 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -484,7 +484,6 @@ typedef struct { * objects. */ GLboolean ReplayHardBeginEnd; - GLenum CurrentPrimitive; /* Note which vertices need copying over succesive immediates. * Will add save versions to precompute vertex copying where @@ -500,6 +499,10 @@ typedef struct { GLuint DlistPrimitiveLength; GLuint DlistLastPrimitive; + /* Cache a single free immediate (refcount == 0) + */ + struct immediate *freed_immediate; + /* Probably need a better configuration mechanism: */ GLboolean NeedProjCoords; diff --git a/src/mesa/tnl/t_eval_api.c b/src/mesa/tnl/t_eval_api.c index 10700e83299..798b8f46e2a 100644 --- a/src/mesa/tnl/t_eval_api.c +++ b/src/mesa/tnl/t_eval_api.c @@ -1,4 +1,4 @@ -/* $Id: t_eval_api.c,v 1.4 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: t_eval_api.c,v 1.5 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -61,6 +61,8 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) GLenum prim; ASSERT_OUTSIDE_BEGIN_END(ctx); + fprintf(stderr, "%s\n", __FUNCTION__); + switch (mode) { case GL_POINT: prim = GL_POINTS; @@ -95,6 +97,7 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) if (compiling) { FLUSH_VERTICES( ctx, 0 ); SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) ); + TNL_CURRENT_IM(ctx)->ref_count++; ctx->CompileFlag = GL_FALSE; } @@ -104,8 +107,12 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) } _tnl_end(ctx); + /* Need this for replay *and* compile: + */ + FLUSH_VERTICES( ctx, 0 ); + if (compiling) { - FLUSH_VERTICES( ctx, 0 ); + TNL_CURRENT_IM(ctx)->ref_count--; ASSERT( TNL_CURRENT_IM(ctx)->ref_count == 0 ); _tnl_free_immediate( TNL_CURRENT_IM(ctx) ); SET_IMMEDIATE( ctx, im ); @@ -124,6 +131,8 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) GLfloat u, du, v, dv, v1, u1; ASSERT_OUTSIDE_BEGIN_END(ctx); + fprintf(stderr, "%s\n", __FUNCTION__); + /* No effect if vertex maps disabled. */ if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) @@ -146,6 +155,7 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) if (compiling) { FLUSH_VERTICES( ctx, 0 ); SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) ); + TNL_CURRENT_IM(ctx)->ref_count++; ctx->CompileFlag = GL_FALSE; } @@ -190,8 +200,12 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) return; } + /* Need this for replay *and* compile: + */ + FLUSH_VERTICES( ctx, 0 ); + if (compiling) { - FLUSH_VERTICES( ctx, 0 ); + TNL_CURRENT_IM(ctx)->ref_count--; _tnl_free_immediate( TNL_CURRENT_IM( ctx ) ); SET_IMMEDIATE( ctx, im ); ctx->CompileFlag = GL_TRUE; diff --git a/src/mesa/tnl/t_imm_alloc.c b/src/mesa/tnl/t_imm_alloc.c index def3b9cc6cd..2b497a70583 100644 --- a/src/mesa/tnl/t_imm_alloc.c +++ b/src/mesa/tnl/t_imm_alloc.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_alloc.c,v 1.6 2001/04/26 14:53:48 keithw Exp $ */ +/* $Id: t_imm_alloc.c,v 1.7 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -36,7 +36,7 @@ static int id = 0; -struct immediate *_tnl_alloc_immediate( GLcontext *ctx ) +static struct immediate *real_alloc_immediate( GLcontext *ctx ) { struct immediate *IM = ALIGN_MALLOC_STRUCT( immediate, 32 ); GLuint j; @@ -81,7 +81,7 @@ struct immediate *_tnl_alloc_immediate( GLcontext *ctx ) } -void _tnl_free_immediate( struct immediate *IM ) +static void real_free_immediate( struct immediate *IM ) { static int freed = 0; GLuint j; @@ -101,3 +101,31 @@ void _tnl_free_immediate( struct immediate *IM ) freed++; /* printf("outstanding %d\n", id - freed); */ } + + +/* Cache a single allocated immediate struct. + */ +struct immediate *_tnl_alloc_immediate( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *tmp = tnl->freed_immediate; + + if (tmp) { + tnl->freed_immediate = 0; + return tmp; + } + else + return real_alloc_immediate( ctx ); +} + +void _tnl_free_immediate( struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(IM->backref); + + ASSERT(IM->ref_count == 0); + + if (tnl->freed_immediate) + real_free_immediate( tnl->freed_immediate ); + + tnl->freed_immediate = IM; +} diff --git a/src/mesa/tnl/t_imm_api.c b/src/mesa/tnl/t_imm_api.c index 5b4630881bb..c7184c85230 100644 --- a/src/mesa/tnl/t_imm_api.c +++ b/src/mesa/tnl/t_imm_api.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_api.c,v 1.11 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_api.c,v 1.12 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -52,6 +52,11 @@ void _tnl_flush_immediate( struct immediate *IM ) { GLcontext *ctx = IM->backref; + /* Mark the last primitive: + */ + IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; + IM->Primitive[IM->LastPrimitive] |= PRIM_LAST; + if (ctx->CompileFlag) _tnl_compile_cassette( ctx, IM ); else @@ -107,17 +112,15 @@ _tnl_begin( GLcontext *ctx, GLenum p ) GLuint count = IM->Count; GLuint last = IM->LastPrimitive; - ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); - state |= (VERT_BEGIN_0|VERT_BEGIN_1); IM->Flag[count] |= VERT_BEGIN; - IM->Primitive[IM->LastPrimitive] &= ~PRIM_LAST; - IM->Primitive[count] = p | PRIM_BEGIN | PRIM_LAST; + IM->Primitive[count] = p | PRIM_BEGIN; IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive; IM->LastPrimitive = count; /* Not quite right. Need to use the fallback '_aa_ArrayElement' - * when not known to be inside begin/end and arrays are unlocked. + * when not known to be inside begin/end and arrays are + * unlocked. */ if (IM->FlushElt) { _tnl_translate_array_elts( ctx, IM, last, count ); @@ -156,8 +159,10 @@ _tnl_Begin( GLenum mode ) else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) ctx->Driver.CurrentSavePrimitive = mode; } - else if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) + else if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { +/* fprintf(stderr, "setting cep %x in %s\n", mode, __FUNCTION__); */ ctx->Driver.CurrentExecPrimitive = mode; + } } @@ -178,6 +183,8 @@ _tnl_hard_begin( GLcontext *ctx, GLenum p ) /* Set this for the duration: */ ctx->Driver.CurrentExecPrimitive = p; +/* fprintf(stderr, "setting cep %x in %s\n", */ +/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */ return GL_TRUE; } @@ -217,11 +224,8 @@ _tnl_hard_begin( GLcontext *ctx, GLenum p ) count = IM->Count; last = IM->LastPrimitive; - ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); - IM->Flag[count] |= VERT_BEGIN; - IM->Primitive[last] &= ~PRIM_LAST; - IM->Primitive[count] = p | PRIM_BEGIN | PRIM_LAST; + IM->Primitive[count] = p | PRIM_BEGIN; IM->PrimitiveLength[last] = count - last; IM->LastPrimitive = count; @@ -252,7 +256,7 @@ _tnl_save_Begin( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); - if (mode > GL_POLYGON) { + if (mode > GL_POLYGON) { _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" ); return; } @@ -294,14 +298,11 @@ _tnl_end( GLcontext *ctx ) GLuint count = IM->Count; GLuint last = IM->LastPrimitive; - ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); - state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */ IM->Flag[count] |= VERT_END; IM->Primitive[last] |= PRIM_END; - IM->Primitive[last] &= ~PRIM_LAST; IM->PrimitiveLength[last] = count - last; - IM->Primitive[count] = (GL_POLYGON+1) | PRIM_LAST; + IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; IM->LastPrimitive = count; if (IM->FlushElt) { @@ -312,9 +313,11 @@ _tnl_end( GLcontext *ctx ) IM->BeginState = state; - if (!ctx->CompileFlag) + if (!ctx->CompileFlag) { ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - +/* fprintf(stderr, "setting cep %x in %s\n", */ +/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */ + } /* You can set this flag to get the old 'flush_vb on glEnd()' * behaviour. @@ -1116,6 +1119,8 @@ _tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) { GET_CURRENT_CONTEXT(ctx); +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + if (_tnl_hard_begin( ctx, GL_QUADS )) { _tnl_vertex2f( ctx, x1, y1 ); _tnl_vertex2f( ctx, x2, y1 ); diff --git a/src/mesa/tnl/t_imm_dlist.c b/src/mesa/tnl/t_imm_dlist.c index 7218244ae31..9af32dad0f6 100644 --- a/src/mesa/tnl/t_imm_dlist.c +++ b/src/mesa/tnl/t_imm_dlist.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_dlist.c,v 1.14 2001/04/30 09:04:00 keithw Exp $ */ +/* $Id: t_imm_dlist.c,v 1.15 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -95,15 +95,11 @@ _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ) andflag &= IM->Flag[i]; IM->CopyAndFlag = IM->AndFlag = andflag; } + IM->CopyOrFlag |= ctx->Array._Enabled; } _tnl_fixup_input( ctx, IM ); - /* Mark the last primitive: - */ - IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; - ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); - /* _tnl_print_cassette( IM ); */ @@ -145,10 +141,9 @@ _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ) /* Call it full... */ struct immediate *new_im = _tnl_alloc_immediate(ctx); - if (!new_im) return; new_im->ref_count++; - im->ref_count--; /* remove CURRENT_IM reference */ - ASSERT(im->ref_count > 0); + im->ref_count--; /* remove CURRENT_IM reference */ + ASSERT(im->ref_count > 0); /* it is compiled into a display list */ SET_IMMEDIATE( ctx, new_im ); _tnl_reset_input( ctx, IMM_MAX_COPIED_VERTS, new_beginstate, node->SavedBeginState ); @@ -270,41 +265,28 @@ _tnl_BeginCallList( GLcontext *ctx, GLuint list ) } -/* Called at the tail of a CallList. Copy vertices out of the display - * list if necessary. +/* Called at the tail of a CallList. Nothing to do. */ void _tnl_EndCallList( GLcontext *ctx ) { - /* May have to copy vertices from a dangling begin/end inside the - * list to the current immediate. - */ - if (ctx->CallDepth == 0) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct immediate *IM = TNL_CURRENT_IM(ctx); - - if (tnl->ExecCopySource != IM) - _tnl_copy_immediate_vertices( ctx, IM ); - } } void _tnl_EndList( GLcontext *ctx ) { - TNLcontext *tnl = TNL_CONTEXT(ctx); struct immediate *IM = TNL_CURRENT_IM(ctx); /* fprintf(stderr, "%s\n", __FUNCTION__); */ ctx->swtnl_im = 0; IM->ref_count--; - if (IM == tnl->ExecCopySource) { - IM->ref_count--; - } else { - if ( --tnl->ExecCopySource->ref_count == 0 ) - _tnl_free_immediate( tnl->ExecCopySource ); - } + + /* outside begin/end, even in COMPILE_AND_EXEC, + * so no vertices to copy, right? + */ + ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0); /* If this one isn't free, get a clean one. (Otherwise we'll be * using one that's already half full). @@ -314,19 +296,10 @@ _tnl_EndList( GLcontext *ctx ) ASSERT(IM->ref_count == 0); - tnl->ExecCopyCount = 0; - tnl->ExecCopySource = IM; - IM->ref_count++; - SET_IMMEDIATE( ctx, IM ); IM->ref_count++; _tnl_reset_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 ); - - /* outside begin/end, even in COMPILE_AND_EXEC, - * so no vertices to copy, right? - */ - ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0); } diff --git a/src/mesa/tnl/t_imm_elt.c b/src/mesa/tnl/t_imm_elt.c index c339897bc95..b6fb0933948 100644 --- a/src/mesa/tnl/t_imm_elt.c +++ b/src/mesa/tnl/t_imm_elt.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_elt.c,v 1.8 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_elt.c,v 1.9 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -816,6 +816,4 @@ void _tnl_translate_array_elts( GLcontext *ctx, struct immediate *IM, for (i = start ; i < count ; i++) if (flags[i] & VERT_ELT) flags[i] |= translate; - - IM->CopyOrFlag |= translate; } diff --git a/src/mesa/tnl/t_imm_eval.c b/src/mesa/tnl/t_imm_eval.c index d06f702e5bc..8a83ec1adba 100644 --- a/src/mesa/tnl/t_imm_eval.c +++ b/src/mesa/tnl/t_imm_eval.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_eval.c,v 1.8 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_eval.c,v 1.9 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -35,6 +35,7 @@ #include "math/m_eval.h" #include "t_context.h" +#include "t_imm_debug.h" #include "t_imm_eval.h" #include "t_imm_exec.h" #include "t_imm_fixup.h" @@ -63,13 +64,16 @@ static void eval_points2( GLfloat outcoord[][4], GLfloat dv, GLfloat v1 ) { GLuint i; + fprintf(stderr, "%p %p\n", coord, outcoord); for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) { if (flags[i] & VERT_EVAL_ANY) { outcoord[i][0] = coord[i][0]; outcoord[i][1] = coord[i][1]; if (flags[i] & VERT_EVAL_P2) { + fprintf(stderr, "point %f %f ==>", coord[i][0], coord[i][1]); outcoord[i][0] = coord[i][0] * du + u1; outcoord[i][1] = coord[i][1] * dv + v1; + fprintf(stderr, "%f %f\n", outcoord[i][0], outcoord[i][1]); } } } @@ -189,6 +193,8 @@ static void eval2_obj_norm( GLvector4f *obj_ptr, GLfloat (*normal)[3] = norm_ptr->data; GLuint i; + fprintf(stderr, "%s\n", __FUNCTION__); + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { GLfloat u = (coord[i][0] - u1) * du; @@ -225,6 +231,8 @@ static void eval2_4f( GLvector4f *dest, if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { GLfloat u = (coord[i][0] - u1) * du; GLfloat v = (coord[i][1] - v1) * dv; + fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]); + _math_horner_bezier_surf(map->Points, to[i], u, v, dimension, map->Uorder, map->Vorder); } @@ -318,6 +326,20 @@ static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count ) MEMCPY( to, from, count * sizeof(to[0])); } +static void copy_4f_stride( GLfloat to[][4], GLfloat *from, + GLuint stride, GLuint count ) +{ + if (stride == 4 * sizeof(GLfloat)) + MEMCPY( to, from, count * sizeof(to[0])); + else { + int i; + fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__, + stride, count); + for (i = 0 ; i < count ; i++, STRIDE_F(from, stride)) + COPY_4FV( to[i], from ); + } +} + static void copy_3f( GLfloat to[][3], GLfloat from[][3], GLuint count ) { MEMCPY( to, from, (count) * sizeof(to[0])); @@ -400,24 +422,27 @@ static void update_eval( GLcontext *ctx ) * Really want to cache the results of this function in display lists, * at least for EvalMesh commands. */ -void _tnl_eval_vb( GLcontext *ctx, - GLfloat (*coord)[4], - GLuint orflag, - GLuint andflag ) +void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_arrays *tmp = &tnl->imm_inputs; struct immediate *store = tnl->eval.im; - GLuint *flags = tnl->vb.Flag; - GLuint count = tnl->vb.Count; + GLuint *flags = IM->Flag + IM->CopyStart; + GLuint copycount; + GLuint orflag = IM->OrFlag; GLuint any_eval1 = orflag & (VERT_EVAL_C1|VERT_EVAL_P1); GLuint any_eval2 = orflag & (VERT_EVAL_C2|VERT_EVAL_P2); - GLuint all_eval = andflag & VERT_EVAL_ANY; /* may have false negatives */ GLuint req = 0; GLuint purge_flags = 0; + GLfloat (*coord)[4] = IM->Obj + IM->CopyStart; -/* if (input->writable) */ -/* store = input; */ + if (IM->AndFlag & VERT_EVAL_ANY) + copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */ + else + copycount = IM->Count - IM->CopyStart; /* copy all vertices */ + + fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n", + __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount); if (!store) store = tnl->eval.im = _tnl_alloc_immediate( ctx ); @@ -425,44 +450,42 @@ void _tnl_eval_vb( GLcontext *ctx, if (tnl->eval.EvalNewState & _NEW_EVAL) update_eval( ctx ); - /* Handle the degenerate cases. - */ - if (any_eval1 && !ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) - purge_flags = (VERT_EVAL_P1|VERT_EVAL_C1); + if (any_eval1) { + req |= tnl->pipeline.inputs & tnl->eval.EvalMap1Flags; - if (any_eval2 && !ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) - purge_flags |= (VERT_EVAL_P1|VERT_EVAL_C1); + if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) + purge_flags = (VERT_EVAL_P1|VERT_EVAL_C1); - if (any_eval1) - req |= tnl->pipeline.inputs & tnl->eval.EvalMap1Flags; + if (orflag & VERT_EVAL_P1) { + eval_points1( store->Obj + IM->CopyStart, + coord, flags, + ctx->Eval.MapGrid1du, + ctx->Eval.MapGrid1u1); + + coord = store->Obj + IM->CopyStart; + } + } - if (any_eval2) + if (any_eval2) { req |= tnl->pipeline.inputs & tnl->eval.EvalMap2Flags; + if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) + purge_flags |= (VERT_EVAL_P2|VERT_EVAL_C2); - /* Translate points into coords. Use store->Obj to hold the - * new data. - */ - if (any_eval1 && (orflag & VERT_EVAL_P1)) - { - eval_points1( store->Obj, coord, flags, - ctx->Eval.MapGrid1du, - ctx->Eval.MapGrid1u1); + if (orflag & VERT_EVAL_P2) { + eval_points2( store->Obj + IM->CopyStart, + coord, flags, + ctx->Eval.MapGrid2du, + ctx->Eval.MapGrid2u1, + ctx->Eval.MapGrid2dv, + ctx->Eval.MapGrid2v1 ); - coord = store->Obj; + coord = store->Obj + IM->CopyStart; + } } - if (any_eval2 && (orflag & VERT_EVAL_P2)) - { - eval_points2( store->Obj, coord, flags, - ctx->Eval.MapGrid2du, - ctx->Eval.MapGrid2u1, - ctx->Eval.MapGrid2dv, - ctx->Eval.MapGrid2v1 ); - - coord = store->Obj; - } + _tnl_print_vert_flags(__FUNCTION__, req); /* Perform the evaluations on active data elements. */ @@ -470,11 +493,11 @@ void _tnl_eval_vb( GLcontext *ctx, { GLuint generated = 0; - if (!all_eval) - copy_1ui( store->Index, tmp->Index.data, count ); + if (copycount) + copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount ); - tmp->Index.data = store->Index; - tmp->Index.start = store->Index; + tmp->Index.data = store->Index + IM->CopyStart; + tmp->Index.start = store->Index + IM->CopyStart; if (ctx->Eval.Map1Index && any_eval1) { eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index ); @@ -490,7 +513,7 @@ void _tnl_eval_vb( GLcontext *ctx, * maps are disabled. */ if (purge_flags & generated) - _tnl_fixup_1ui( store->Index, flags, 0, + _tnl_fixup_1ui( tmp->Index.data, flags, 0, VERT_INDEX| VERT_OBJ| generated| @@ -501,10 +524,16 @@ void _tnl_eval_vb( GLcontext *ctx, { GLuint generated = 0; - if (!all_eval) - copy_4f( store->Color, (GLfloat (*)[4])tmp->Color.Ptr, count ); + if (copycount) + copy_4f_stride( store->Color + IM->CopyStart, + (GLfloat *)tmp->Color.Ptr, + tmp->Color.StrideB, + copycount ); - tmp->Color.Ptr = store->Color; + tmp->Color.Ptr = store->Color + IM->CopyStart; + tmp->Color.StrideB = 4 * sizeof(GLfloat); + tmp->Color.Flags = 0; + tnl->vb.importable_data &= ~VERT_RGBA; if (ctx->Eval.Map1Color4 && any_eval1) { eval1_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map1Color4 ); @@ -520,7 +549,8 @@ void _tnl_eval_vb( GLcontext *ctx, * maps are disabled. */ if (purge_flags & generated) - _tnl_fixup_4f( store->Color, flags, 0, + _tnl_fixup_4f( store->Color + IM->CopyStart, + flags, 0, VERT_RGBA| VERT_OBJ| generated| @@ -532,13 +562,14 @@ void _tnl_eval_vb( GLcontext *ctx, { GLuint generated = 0; - if (!all_eval) - copy_4f( store->TexCoord[0], tmp->TexCoord[0].data, count ); + if (copycount) + copy_4f( store->TexCoord[0] + IM->CopyStart, + tmp->TexCoord[0].data, copycount ); else tmp->TexCoord[0].size = 0; - tmp->TexCoord[0].data = store->TexCoord[0]; - tmp->TexCoord[0].start = (GLfloat *)store->TexCoord[0]; + tmp->TexCoord[0].data = store->TexCoord[0] + IM->CopyStart; + tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data; if (any_eval1) { if (ctx->Eval.Map1TextureCoord4) { @@ -590,7 +621,7 @@ void _tnl_eval_vb( GLcontext *ctx, * maps are disabled. */ if (purge_flags & generated) - _tnl_fixup_4f( store->TexCoord[0], flags, 0, + _tnl_fixup_4f( tmp->TexCoord[0].data, flags, 0, VERT_TEX0| VERT_OBJ| generated| @@ -602,11 +633,14 @@ void _tnl_eval_vb( GLcontext *ctx, { GLuint generated = 0; - if (!all_eval) - copy_3f( store->Normal, tmp->Normal.data, count ); + if (copycount) { + fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); + copy_3f( store->Normal + IM->CopyStart, tmp->Normal.data, + copycount ); + } - tmp->Normal.data = store->Normal; - tmp->Normal.start = (GLfloat *)store->Normal; + tmp->Normal.data = store->Normal + IM->CopyStart; + tmp->Normal.start = (GLfloat *)tmp->Normal.data; if (ctx->Eval.Map1Normal && any_eval1) { eval1_norm( &tmp->Normal, coord, flags, @@ -624,7 +658,7 @@ void _tnl_eval_vb( GLcontext *ctx, * maps are disabled. */ if (purge_flags & generated) - _tnl_fixup_3f( store->Normal, flags, 0, + _tnl_fixup_3f( tmp->Normal.data, flags, 0, VERT_NORM| VERT_OBJ| generated| @@ -638,13 +672,20 @@ void _tnl_eval_vb( GLcontext *ctx, */ if (req & VERT_OBJ) { - if (!all_eval) { - copy_4f( store->Obj, tmp->Obj.data, count ); + if (copycount) { + /* This copy may already have occurred when eliminating + * glEvalPoint calls: + */ + if (coord != store->Obj + IM->CopyStart) + copy_4f( store->Obj + IM->CopyStart, tmp->Obj.data, copycount ); } else tmp->Obj.size = 0; - tmp->Obj.data = store->Obj; - tmp->Obj.start = (GLfloat *)store->Obj; + tmp->Obj.data = store->Obj + IM->CopyStart; + tmp->Obj.start = (GLfloat *)tmp->Obj.data; + + /* Note: Normal data is already prepared above. + */ if (any_eval1) { if (ctx->Eval.Map1Vertex4) { @@ -689,10 +730,12 @@ void _tnl_eval_vb( GLcontext *ctx, GLuint last_new_prim = 0; GLuint new_prim_length = 0; GLuint next_old_prim = 0; - GLuint i,j; struct vertex_buffer *VB = &tnl->vb; + GLuint i,j,count = VB->Count; - for (i = 0, j = 0 ; i < tnl->vb.Count ; i++) { + fprintf(stderr, "PURGING\n"); + + for (i = 0, j = 0 ; i < count ; i++) { if (flags[i] & vertex) { store->Elt[j++] = i; new_prim_length++; @@ -706,17 +749,17 @@ void _tnl_eval_vb( GLcontext *ctx, } VB->Elts = store->Elt; - - _tnl_fixup_purged_eval( ctx, store ); + _tnl_get_purged_copy_verts( ctx, store ); } /* Produce new flags array: */ { - GLuint i; + GLuint i, count = tnl->vb.Count; copy_1ui( store->Flag, flags, count ); tnl->vb.Flag = store->Flag; for (i = 0 ; i < count ; i++) store->Flag[i] |= req; + IM->CopyOrFlag |= req; /* hack for copying. */ } } diff --git a/src/mesa/tnl/t_imm_eval.h b/src/mesa/tnl/t_imm_eval.h index 951a93d896d..341da514810 100644 --- a/src/mesa/tnl/t_imm_eval.h +++ b/src/mesa/tnl/t_imm_eval.h @@ -1,4 +1,4 @@ -/* $Id: t_imm_eval.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: t_imm_eval.h,v 1.3 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -34,7 +34,6 @@ extern void _tnl_eval_init( void ); -extern void _tnl_eval_vb( GLcontext *ctx, GLfloat (*coord)[4], - GLuint orflag, GLuint andflag ); +extern void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ); #endif diff --git a/src/mesa/tnl/t_imm_exec.c b/src/mesa/tnl/t_imm_exec.c index 18eaa488a35..4ee77b773f0 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.18 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_exec.c,v 1.19 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -57,13 +57,12 @@ -/* Called to initialize new buffers, and to recycle old ones. - */ void _tnl_reset_input( GLcontext *ctx, GLuint start, GLuint beginstate, GLuint savedbeginstate ) { + TNLcontext *tnl = TNL_CONTEXT(ctx); struct immediate *IM = TNL_CURRENT_IM(ctx); /* Clear the dirty part of the flag array. @@ -71,9 +70,19 @@ void _tnl_reset_input( GLcontext *ctx, if (start < IM->Count+2) MEMSET(IM->Flag + start, 0, sizeof(GLuint) * (IM->Count+2-start)); - IM->CopyStart = IM->Start = IM->Count = start; - IM->Primitive[IM->Start] = (ctx->Driver.CurrentExecPrimitive | PRIM_LAST); - IM->LastPrimitive = IM->Start; + IM->Start = IM->Count = start; + IM->CopyStart = IM->Start - tnl->ExecCopyCount; + IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive; + if (tnl->ExecParity) + IM->Primitive[IM->CopyStart] |= PRIM_PARITY; + + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { + ASSERT(tnl->ExecCopyTexSize == 0); + ASSERT(tnl->ExecCopyCount == 0); + ASSERT(IM->CopyStart == IM->Start); + } + + IM->LastPrimitive = IM->CopyStart; IM->BeginState = beginstate; IM->SavedBeginState = savedbeginstate; IM->TexSize = 0; @@ -83,7 +92,6 @@ void _tnl_reset_input( GLcontext *ctx, if (IM->MaterialMask) IM->MaterialMask[IM->Start] = 0; - IM->ArrayEltFlags = ~ctx->Array._Enabled; IM->ArrayEltIncr = ctx->Array.Vertex.Enabled ? 1 : 0; IM->ArrayEltFlush = !ctx->Array.LockCount; @@ -91,6 +99,7 @@ void _tnl_reset_input( GLcontext *ctx, + void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, GLuint flag ) { @@ -317,16 +326,13 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM ) VB->MaterialMask = IM->MaterialMask + start; VB->Material = IM->Material + start; } - -/* _tnl_print_vert_flags("_tnl_vb_bind_immediate: importable", */ -/* VB->importable_data); */ - } -/* Called by exec_cassette and execute_compiled_cassette. +/* Called by exec_cassette execute_compiled_cassette, but not + * exec_elt_cassette. */ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ) { @@ -335,11 +341,7 @@ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ) _tnl_vb_bind_immediate( ctx, IM ); if (IM->CopyOrFlag & VERT_EVAL_ANY) - _tnl_eval_vb( ctx, - IM->Obj + IM->CopyStart, - IM->CopyOrFlag, - IM->CopyAndFlag ); - + _tnl_eval_immediate( ctx, IM ); /* Invalidate all stored data before and after run: */ @@ -350,7 +352,32 @@ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ) _tnl_copy_to_current( ctx, IM, IM->OrFlag ); } +/* Called for regular vertex cassettes. + */ +static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM ) +{ + if (IM->OrFlag & VERT_ELT) { + GLuint andflag = ~0; + GLuint i; + GLuint start = IM->FlushElt ? IM->LastPrimitive : IM->CopyStart; + _tnl_translate_array_elts( ctx, IM, start, IM->Count ); + + /* Need to recompute andflag and orflag for fixup. + */ + if (IM->CopyAndFlag & VERT_ELT) + IM->CopyAndFlag |= ctx->Array._Enabled; + else { + for (i = IM->CopyStart ; i < IM->Count ; i++) + andflag &= IM->Flag[i]; + IM->CopyAndFlag = andflag; + } + IM->CopyOrFlag |= ctx->Array._Enabled; + } + _tnl_fixup_input( ctx, IM ); + _tnl_print_cassette( IM ); + _tnl_run_cassette( ctx, IM ); +} /* Called for pure, locked VERT_ELT cassettes instead of @@ -363,6 +390,8 @@ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM ) _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount ); + /* Take only elements and primitive information from the immediate: + */ VB->Elts = IM->Elt + IM->CopyStart; VB->Primitive = IM->Primitive + IM->CopyStart; VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart; @@ -382,31 +411,13 @@ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM ) } - -/* Called for regular vertex cassettes. - */ -static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM ) +static void +exec_empty_cassette( GLcontext *ctx, struct immediate *IM ) { - if (IM->OrFlag & VERT_ELT) { - GLuint andflag = ~0; - GLuint i; - GLuint start = IM->FlushElt ? IM->LastPrimitive : IM->CopyStart; - _tnl_translate_array_elts( ctx, IM, start, IM->Count ); - - /* Need to recompute andflag. - */ - if (IM->CopyAndFlag & VERT_ELT) - IM->CopyAndFlag |= ctx->Array._Enabled; - else { - for (i = IM->CopyStart ; i < IM->Count ; i++) - andflag &= IM->Flag[i]; - IM->CopyAndFlag = andflag; - } - } + if (IM->OrFlag & VERT_ELT) + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); - _tnl_fixup_input( ctx, IM ); -/* _tnl_print_cassette( IM ); */ - _tnl_run_cassette( ctx, IM ); + _tnl_copy_to_current( ctx, IM, IM->OrFlag ); } @@ -418,27 +429,17 @@ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - ASSERT(tnl->ExecCopySource == IM); - _tnl_compute_orflag( IM ); - - /* Mark the last primitive: - */ - IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; - ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST); + _tnl_copy_immediate_vertices( ctx, IM ); /* ?? flags, orflag above */ + _tnl_get_exec_copy_verts( ctx, IM ); if (tnl->pipeline.build_state_changes) _tnl_validate_pipeline( ctx ); - _tnl_get_exec_copy_verts( ctx, IM ); - if (IM->CopyStart == IM->Count) { - if (IM->OrFlag & VERT_ELT) - _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); - - _tnl_copy_to_current( ctx, IM, IM->OrFlag ); + exec_empty_cassette( ctx, IM ); } - else if ((IM->OrFlag & VERT_DATA) == VERT_ELT && + else if ((IM->CopyOrFlag & VERT_DATA) == VERT_ELT && ctx->Array.LockCount && ctx->Array.Vertex.Enabled) { exec_elt_cassette( ctx, IM ); @@ -447,15 +448,23 @@ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ) exec_vert_cassette( ctx, IM ); } - _tnl_reset_input( ctx, - IMM_MAX_COPIED_VERTS, - IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1), - IM->SavedBeginState ); - - /* Copy vertices and primitive information to immediate before it - * can be overwritten. + /* Only reuse the immediate if there are no copied vertices living + * inside it: */ - _tnl_copy_immediate_vertices( ctx, IM ); + { + GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1); + GLuint saved_begin_state = IM->SavedBeginState; + + if (--IM->ref_count != 0) { + IM = _tnl_alloc_immediate( ctx ); + SET_IMMEDIATE( ctx, IM ); + } + + IM->ref_count++; + + _tnl_reset_input( ctx, IMM_MAX_COPIED_VERTS, + begin_state, saved_begin_state ); + } if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; @@ -483,8 +492,7 @@ void _tnl_imm_init( GLcontext *ctx ) tnl->ExecCopyTexSize = 0; tnl->ExecCopyCount = 0; - tnl->ExecCopySource = TNL_CURRENT_IM(ctx); - TNL_CURRENT_IM(ctx)->ref_count++; + tnl->ExecCopySource = 0; TNL_CURRENT_IM(ctx)->CopyStart = IMM_MAX_COPIED_VERTS; @@ -523,7 +531,9 @@ void _tnl_imm_init( GLcontext *ctx ) void _tnl_imm_destroy( GLcontext *ctx ) { - if (TNL_CURRENT_IM(ctx)) + if (TNL_CURRENT_IM(ctx)) { + TNL_CURRENT_IM(ctx)->ref_count--; _tnl_free_immediate( TNL_CURRENT_IM(ctx) ); - + SET_IMMEDIATE(ctx, 0); + } } diff --git a/src/mesa/tnl/t_imm_fixup.c b/src/mesa/tnl/t_imm_fixup.c index 53e5dcbdc55..1c3cf2861c5 100644 --- a/src/mesa/tnl/t_imm_fixup.c +++ b/src/mesa/tnl/t_imm_fixup.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_fixup.c,v 1.12 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_fixup.c,v 1.13 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -48,6 +48,7 @@ #include "t_context.h" #include "t_imm_alloc.h" #include "t_imm_debug.h" +#include "t_imm_elt.h" #include "t_imm_fixup.h" #include "t_pipeline.h" @@ -374,102 +375,117 @@ static void copy_material( struct immediate *next, * Have to be careful with the transitions between display list * replay, compile and normal execute modes. */ -static void copy_vertices( GLcontext *ctx, - struct immediate *next, - struct immediate *prev, - GLuint count, - GLuint *elts ) +void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) { TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *prev = tnl->ExecCopySource; + struct vertex_arrays *inputs = &tnl->imm_inputs; + GLuint count = tnl->ExecCopyCount; + GLuint *elts = tnl->ExecCopyElts; GLuint offset = IMM_MAX_COPIED_VERTS - count; GLuint i; - next->CopyStart = next->Start - count; + if (!prev) { + ASSERT(tnl->ExecCopyCount == 0); + return; + } - /* Copy the vertices - */ - for (i = 0 ; i < count ; i++) + next->CopyStart = next->Start - count; +/* fprintf(stderr, "%s prim %s count %d source %p\n", */ +/* __FUNCTION__, */ +/* _mesa_lookup_enum_by_nr(ctx->Driver.CurrentExecPrimitive), */ +/* count, prev); */ + + if ((prev->CopyOrFlag & VERT_DATA) == VERT_ELT && + ctx->Array.LockCount && + ctx->Array.Vertex.Enabled) { - GLuint src = elts[i+offset]; - GLuint dst = next->CopyStart+i; - - COPY_4FV( next->Obj[dst], prev->Obj[src] ); - COPY_3FV( next->Normal[dst], prev->Normal[src] ); - COPY_4FV( next->Color[dst], prev->Color[src] ); + /* Copy Elt values only + */ + for (i = 0 ; i < count ; i++) + { + GLuint src = elts[i+offset]; + GLuint dst = next->CopyStart+i; - if (prev->OrFlag & VERT_TEX_ANY) { - GLuint i; - for (i = 0 ; i < prev->MaxTextureUnits ; i++) { - if (prev->OrFlag & VERT_TEX(i)) - COPY_4FV( next->TexCoord[i][dst], prev->TexCoord[i][src] ); - } + next->Elt[dst] = prev->Elt[src]; + next->Flag[dst] = VERT_ELT; + next->CopyOrFlag |= VERT_ELT; + next->CopyAndFlag &= VERT_ELT; } - - if (prev->Flag[src] & VERT_MATERIAL) - copy_material(next, prev, dst, src); - - next->Elt[dst] = prev->Elt[src]; - next->EdgeFlag[dst] = prev->EdgeFlag[src]; - next->Index[dst] = prev->Index[src]; - COPY_4FV( next->SecondaryColor[dst], prev->SecondaryColor[src] ); - next->FogCoord[dst] = prev->FogCoord[src]; - next->Flag[dst] = (prev->CopyOrFlag & VERT_FIXUP); - next->CopyOrFlag |= prev->Flag[src]; /* redundant for current_im */ - next->CopyAndFlag &= prev->Flag[src]; /* redundant for current_im */ } + else { + /* prev->CopyOrFlag is hacked to include values generated by eval: + */ + GLuint copy = tnl->pipeline.inputs & prev->CopyOrFlag; +/* _tnl_print_vert_flags(__FUNCTION__, copy); */ + + + next->TexSize |= tnl->ExecCopyTexSize; - ASSERT(prev == tnl->ExecCopySource); + /* Copy whole vertices + */ + for (i = 0 ; i < count ; i++) + { + GLuint src = elts[i+offset]; + GLuint isrc = src - prev->CopyStart; + GLuint dst = next->CopyStart+i; - if (--tnl->ExecCopySource->ref_count == 0) - _tnl_free_immediate( tnl->ExecCopySource ); +/* fprintf(stderr, "src %d isrc %d dst %d\n", src, isrc, dst); */ - next->ref_count++; - tnl->ExecCopySource = next; + /* Values subject to eval must be copied out of the 'inputs' + * struct. (Copied rows should not be evaluated twice). + * + * Note these pointers are null when inactive. + */ + COPY_4FV( next->Obj[dst], inputs->Obj.data[isrc] ); - tnl->ExecCopyElts[0] = next->Start-3; - tnl->ExecCopyElts[1] = next->Start-2; - tnl->ExecCopyElts[2] = next->Start-1; -} + if (copy & VERT_NORM) + COPY_3FV( next->Normal[dst], inputs->Normal.data[isrc] ); -/* Copy vertices to an empty immediate struct. - */ -void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *IM ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); + if (copy & VERT_RGBA) + COPY_4FV( next->Color[dst], + ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] ); - ASSERT(IM == TNL_CURRENT_IM(ctx)); - ASSERT(IM->Count == IM->Start); + if (copy & VERT_INDEX) + next->Index[dst] = inputs->Index.data[isrc]; - /* Need to push this in now as it won't be computed anywhere else/ - */ - IM->TexSize = tnl->ExecCopyTexSize; + if (copy & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < prev->MaxTextureUnits ; i++) { + if (copy & VERT_TEX(i)) + COPY_4FV( next->TexCoord[i][dst], + inputs->TexCoord[i].data[isrc] ); + } + } - /* A wrapped primitive. We may be copying into a revived - * display list immediate, or onto the front of a new execute-mode - * immediate. - */ - copy_vertices( ctx, IM, - tnl->ExecCopySource, - tnl->ExecCopyCount, - tnl->ExecCopyElts ); + /* Remaining values should be the same in the 'input' struct and the + * original immediate. + */ + if (copy & (VERT_ELT|VERT_EDGE|VERT_SPEC_RGB|VERT_FOG_COORD| + VERT_MATERIAL)) { - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - /* Immediates are built by default to be correct in this state, - * and copying to the first slots of an immediate doesn't remove - * this property. - */ - ASSERT(tnl->ExecCopyTexSize == 0); - ASSERT(tnl->ExecCopyCount == 0); - ASSERT(IM->CopyStart == IM->Start); + if (prev->Flag[src] & VERT_MATERIAL) + copy_material(next, prev, dst, src); + + next->Elt[dst] = prev->Elt[src]; + next->EdgeFlag[dst] = prev->EdgeFlag[src]; + COPY_4FV( next->SecondaryColor[dst], prev->SecondaryColor[src] ); + next->FogCoord[dst] = prev->FogCoord[src]; + } + + next->Flag[dst] = (prev->CopyOrFlag & VERT_FIXUP); + } + + next->CopyOrFlag |= (prev->CopyOrFlag & VERT_FIXUP); + next->CopyAndFlag &= (prev->CopyOrFlag & VERT_FIXUP); } - /* Copy the primitive information: - */ - IM->Primitive[IM->CopyStart] = (ctx->Driver.CurrentExecPrimitive | PRIM_LAST); - IM->LastPrimitive = IM->CopyStart; - if (tnl->ExecParity) - IM->Primitive[IM->CopyStart] |= PRIM_PARITY; + if (--tnl->ExecCopySource->ref_count == 0) + _tnl_free_immediate( tnl->ExecCopySource ); + + tnl->ExecCopySource = 0; + tnl->ExecCopyCount = 0; } @@ -484,24 +500,29 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) GLuint count = IM->Count; GLuint start = IM->Start; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + if (count == start) return; - IM->CopyOrFlag = IM->OrFlag; /* redundant for current_im */ - IM->CopyAndFlag = IM->AndFlag; /* redundant for current_im */ + IM->CopyOrFlag = IM->OrFlag; + IM->CopyAndFlag = IM->AndFlag; IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize; - copy_vertices( ctx, IM, - tnl->ExecCopySource, - tnl->ExecCopyCount, - tnl->ExecCopyElts ); + _tnl_copy_immediate_vertices( ctx, IM ); if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - ASSERT(tnl->ExecCopyTexSize == 0); - ASSERT(tnl->ExecCopyCount == 0); ASSERT(IM->CopyStart == IM->Start); } + /* Naked array elements can be copied into the first cassette in a + * display list. Need to translate them away: + */ + if (IM->CopyOrFlag & VERT_ELT) { + ASSERT(IM->CopyStart < IM->Start); + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start ); + } + fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_FIXUP; if (fixup) { @@ -594,8 +615,6 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) IM->LastPrimitive = IM->CopyStart; } } - /* Shouldn't immediates be set up to have this structure *by default*? - */ } else { GLuint i; @@ -633,6 +652,11 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) else ctx->Driver.CurrentExecPrimitive = IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK; + +/* fprintf(stderr, "setting cep %x in %s\n", */ +/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */ +/* fprintf(stderr, "%s lastprim %d: %x\n", __FUNCTION__, */ +/* IM->LastPrimitive, IM->Primitive[IM->LastPrimitive]); */ } @@ -728,19 +752,20 @@ _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ) GLuint pintro = intro[prim]; GLuint ovf = 0; +/* fprintf(stderr, "_tnl_get_exec_copy_verts %s\n", */ +/* _mesa_lookup_enum_by_nr(prim)); */ - if (tnl->ExecCopySource != IM) { - if (--tnl->ExecCopySource->ref_count == 0) - _tnl_free_immediate( tnl->ExecCopySource ); - IM->ref_count++; - tnl->ExecCopySource = IM; - } + ASSERT(tnl->ExecCopySource == 0); if (prim == GL_POLYGON+1) { tnl->ExecCopyCount = 0; tnl->ExecCopyTexSize = 0; tnl->ExecParity = 0; } else { + /* Remember this immediate as the one to copy from. + */ + IM->ref_count++; + tnl->ExecCopySource = IM; tnl->ExecCopyCount = 0; tnl->ExecCopyTexSize = IM->CopyTexSize; tnl->ExecParity = IM->PrimitiveLength[IM->LastPrimitive] & 1; @@ -754,17 +779,14 @@ _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ) } -/* +/* Recalculate ExecCopyElts, ExecParity, etc. */ -void _tnl_fixup_purged_eval( GLcontext *ctx, struct immediate *IM ) +void +_tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - /* Recalculate ExecCopyElts, ExecParity, etc. These don't need the - * post-eval values, so using the original immediate is fine, but - * copied vertices will need to be re-evaluated. - */ - if (tnl->CurrentPrimitive != GL_POLYGON+1) { + if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { GLuint last = IM->LastPrimitive; GLenum prim = IM->Primitive[last]; GLuint pincr = increment[prim]; @@ -791,9 +813,11 @@ void _tnl_upgrade_current_data( GLcontext *ctx, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct immediate *IM = tnl->ExecCopySource; + struct immediate *IM = TNL_CURRENT_IM(ctx); /* hmmm */ struct vertex_buffer *VB = &tnl->vb; + ASSERT(IM); + /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */ if ((required & VERT_RGBA) && (VB->ColorPtr[0]->Flags & CA_CLIENT_DATA)) { diff --git a/src/mesa/tnl/t_imm_fixup.h b/src/mesa/tnl/t_imm_fixup.h index 584712167f0..5ca68b297a0 100644 --- a/src/mesa/tnl/t_imm_fixup.h +++ b/src/mesa/tnl/t_imm_fixup.h @@ -1,4 +1,4 @@ -/* $Id: t_imm_fixup.h,v 1.4 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_imm_fixup.h,v 1.5 2001/04/30 21:08:52 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -54,12 +54,11 @@ extern void _tnl_fixup_compiled_cassette( GLcontext *ctx, extern void _tnl_restore_compiled_cassette( GLcontext *ctx, struct immediate *IM ); - -extern void _tnl_fixup_purged_eval( GLcontext *ctx, struct immediate *IM ); - extern void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *IM ); +extern void _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ); + extern void _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ); extern void _tnl_upgrade_current_data( GLcontext *ctx, GLuint required, |