X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_imm_eval.c;h=f6d33dfa1a4c8055f63b2c5b618941deafda8d1a;hb=cd1cefae9146fc14b35ee93a04bdb1b1590fba7b;hp=a7c5b7db039d1ef56cf34f86c5fefb1710e7aff6;hpb=74b493a5e61237de081a438e774e5d8139d4c6b7;p=mesa.git diff --git a/src/mesa/tnl/t_imm_eval.c b/src/mesa/tnl/t_imm_eval.c index a7c5b7db039..f6d33dfa1a4 100644 --- a/src/mesa/tnl/t_imm_eval.c +++ b/src/mesa/tnl/t_imm_eval.c @@ -1,10 +1,10 @@ -/* $Id: t_imm_eval.c,v 1.4 2001/01/24 00:04:59 brianp Exp $ */ +/* $Id: t_imm_eval.c,v 1.13 2001/05/14 09:00:51 keithw Exp $ */ /* * Mesa 3-D graphics library * Version: 3.5 * - * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,10 @@ * 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. + * + * Authors: + * Keith Whitwell + * */ @@ -35,9 +39,11 @@ #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" +#include "t_imm_alloc.h" static void eval_points1( GLfloat outcoord[][4], @@ -84,10 +90,10 @@ static const GLubyte dirty_flags[5] = { static void eval1_4f( GLvector4f *dest, - GLfloat coord[][4], - const GLuint *flags, - GLuint dimension, - struct gl_1d_map *map ) + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_1d_map *map ) { const GLfloat u1 = map->u1; const GLfloat du = map->du; @@ -98,7 +104,7 @@ static void eval1_4f( GLvector4f *dest, if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { GLfloat u = (coord[i][0] - u1) * du; ASSIGN_4V(to[i], 0,0,0,1); - _math_horner_bezier_curve(map->Points, to[i], u, + _math_horner_bezier_curve(map->Points, to[i], u, dimension, map->Order); } @@ -106,6 +112,31 @@ static void eval1_4f( GLvector4f *dest, dest->flags |= dirty_flags[dimension]; } +static void eval1_4f_ca( struct gl_client_array *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_1d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr; + GLuint i; + + ASSERT(dest->Type == GL_FLOAT); + ASSERT(dest->StrideB == 4 * sizeof(GLfloat)); + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { + GLfloat u = (coord[i][0] - u1) * du; + ASSIGN_4V(to[i], 0,0,0,1); + _math_horner_bezier_curve(map->Points, to[i], u, + dimension, map->Order); + } + + dest->Size = MAX2(dest->Size, (GLint) dimension); +} + static void eval1_1ui( GLvector1ui *dest, GLfloat coord[][4], @@ -129,7 +160,7 @@ static void eval1_1ui( GLvector1ui *dest, static void eval1_norm( GLvector3f *dest, GLfloat coord[][4], - const GLuint *flags, + const GLuint *flags, struct gl_1d_map *map ) { const GLfloat u1 = map->u1; @@ -144,32 +175,6 @@ static void eval1_norm( GLvector3f *dest, } } -static void eval1_color( -#if CHAN_TYPE == GL_UNSIGNED_BYTE - GLvector4ub *dest, -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - GLvector4us *dest, -#elif CHAN_TYPE == GL_FLOAT - GLvector4f *dest, -#endif - GLfloat coord[][4], - const GLuint *flags, - struct gl_1d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - GLchan (*to)[4] = dest->data; - GLuint i; - - for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) { - if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { - GLfloat u = (coord[i][0] - u1) * du; - GLfloat fcolor[4]; - _math_horner_bezier_curve(map->Points, fcolor, u, 4, map->Order); - UNCLAMPED_FLOAT_TO_RGBA_CHAN(to[i], fcolor); - } - } -} @@ -189,6 +194,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 +232,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); } @@ -233,6 +242,33 @@ static void eval2_4f( GLvector4f *dest, dest->flags |= dirty_flags[dimension]; } +static void eval2_4f_ca( struct gl_client_array *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr; + GLuint i; + + ASSERT(dest->Type == GL_FLOAT); + ASSERT(dest->StrideB == 4 * sizeof(GLfloat)); + + 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; + GLfloat v = (coord[i][1] - v1) * dv; + _math_horner_bezier_surf(map->Points, to[i], u, v, dimension, + map->Uorder, map->Vorder); + } + + dest->Size = MAX2(dest->Size, (GLint) dimension); +} + static void eval2_norm( GLvector3f *dest, GLfloat coord[][4], @@ -283,57 +319,37 @@ static void eval2_1ui( GLvector1ui *dest, -static void eval2_color( -#if CHAN_TYPE == GL_UNSIGNED_BYTE - GLvector4ub *dest, -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - GLvector4us *dest, -#elif CHAN_TYPE == GL_FLOAT - GLvector4f *dest, -#endif - GLfloat coord[][4], - GLuint *flags, - struct gl_2d_map *map ) -{ - const GLfloat u1 = map->u1; - const GLfloat du = map->du; - const GLfloat v1 = map->v1; - const GLfloat dv = map->dv; - GLchan (*to)[4] = dest->data; - GLuint i; - - 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; - GLfloat v = (coord[i][1] - v1) * dv; - GLfloat fcolor[4]; - _math_horner_bezier_surf(map->Points, fcolor, u, v, 4, - map->Uorder, map->Vorder); - UNCLAMPED_FLOAT_TO_RGBA_CHAN(to[i], fcolor); - } - } -} static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count ) { - MEMCPY( to, from, count * sizeof(to[0])); + MEMCPY( to, from, count * sizeof(to[0])); } -static void copy_3f( GLfloat to[][3], GLfloat from[][3], GLuint count ) +static void copy_4f_stride( GLfloat to[][4], GLfloat *from, + GLuint stride, GLuint count ) { - MEMCPY( to, from, (count) * sizeof(to[0])); + if (stride == 4 * sizeof(GLfloat)) + MEMCPY( to, from, count * sizeof(to[0])); + else { + GLuint 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_4chan( GLchan to[][4], GLchan from[][4], GLuint count ) +static void copy_3f( GLfloat to[][3], GLfloat from[][3], GLuint count ) { - MEMCPY( to, from, (count) * sizeof(to[0])); + MEMCPY( to, from, (count) * sizeof(to[0])); } + static void copy_1ui( GLuint to[], GLuint from[], GLuint count ) { - MEMCPY( to, from, (count) * sizeof(to[0])); + MEMCPY( to, from, (count) * sizeof(to[0])); } @@ -382,13 +398,13 @@ static void update_eval( GLcontext *ctx ) eval1 |= VERT_OBJ_23; if (ctx->Eval.Map2Vertex4) { - if (ctx->Eval.AutoNormal) + if (ctx->Eval.AutoNormal) eval2 |= VERT_OBJ_234 | VERT_NORM; else eval2 |= VERT_OBJ_234; } else if (ctx->Eval.Map2Vertex3) { - if (ctx->Eval.AutoNormal) + if (ctx->Eval.AutoNormal) eval2 |= VERT_OBJ_23 | VERT_NORM; else eval2 |= VERT_OBJ_23; @@ -402,129 +418,180 @@ static void update_eval( GLcontext *ctx ) /* This looks a lot like a pipeline stage, but for various reasons is * better handled outside the pipeline, and considered the final stage - * of fixing up an immediate struct for execution. + * of fixing up an immediate struct for execution. * * Really want to cache the results of this function in display lists, - * at least for EvalMesh commands. + * 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 tnl_eval_store *store = &tnl->eval; - GLuint *flags = tnl->vb.Flag; - GLuint count = tnl->vb.Count; + struct immediate *store = tnl->eval.im; + 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 (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 ); 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; - - /* Translate points into coords. Use store->Coord to hold the - * new data. - */ - if (any_eval1 && (orflag & VERT_EVAL_P1)) - { - eval_points1( store->Coord, coord, flags, - ctx->Eval.MapGrid1du, - ctx->Eval.MapGrid1u1); + if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) + purge_flags |= (VERT_EVAL_P2|VERT_EVAL_C2); - coord = store->Coord; - } - - if (any_eval2 && (orflag & VERT_EVAL_P2)) - { - eval_points2( store->Coord, coord, flags, - ctx->Eval.MapGrid2du, - ctx->Eval.MapGrid2u1, - ctx->Eval.MapGrid2dv, - ctx->Eval.MapGrid2v1 ); + 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->Coord; + coord = store->Obj + IM->CopyStart; + } } +/* _tnl_print_vert_flags(__FUNCTION__, req); */ + /* Perform the evaluations on active data elements. */ if (req & VERT_INDEX) { - if (!all_eval) - copy_1ui( store->Index, tmp->Index.data, count ); + GLuint generated = 0; + + 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) + if (ctx->Eval.Map1Index && any_eval1) { eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } - if (ctx->Eval.Map2Index && any_eval2) + if (ctx->Eval.Map2Index && any_eval2) { eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_1ui( tmp->Index.data, flags, 0, + VERT_INDEX| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); } if (req & VERT_RGBA) { - if (!all_eval) - copy_4chan( store->Color, tmp->Color.data, count ); - - tmp->Color.data = store->Color; - tmp->Color.start = (GLchan *) store->Color; + GLuint generated = 0; + + if (copycount) + copy_4f_stride( store->Color + IM->CopyStart, + (GLfloat *)tmp->Color.Ptr, + tmp->Color.StrideB, + copycount ); + + 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 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } - if (ctx->Eval.Map1Color4 && any_eval1) - eval1_color( &tmp->Color, coord, flags, &ctx->EvalMap.Map1Color4 ); + if (ctx->Eval.Map2Color4 && any_eval2) { + eval2_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map2Color4 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } - if (ctx->Eval.Map2Color4 && any_eval2) - eval2_color( &tmp->Color, coord, flags, &ctx->EvalMap.Map2Color4 ); + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_4f( store->Color + IM->CopyStart, + flags, 0, + VERT_RGBA| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); } if (req & VERT_TEX(0)) { - if (!all_eval) - copy_4f( store->TexCoord, tmp->TexCoord[0].data, count ); - else + GLuint generated = 0; + + 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; - tmp->TexCoord[0].start = (GLfloat *)store->TexCoord; + + 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) { eval1_4f( &tmp->TexCoord[0], coord, flags, 4, &ctx->EvalMap.Map1Texture4 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; } else if (ctx->Eval.Map1TextureCoord3) { eval1_4f( &tmp->TexCoord[0], coord, flags, 3, &ctx->EvalMap.Map1Texture3 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; } else if (ctx->Eval.Map1TextureCoord2) { eval1_4f( &tmp->TexCoord[0], coord, flags, 2, &ctx->EvalMap.Map1Texture2 ); - } + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } else if (ctx->Eval.Map1TextureCoord1) { eval1_4f( &tmp->TexCoord[0], coord, flags, 1, &ctx->EvalMap.Map1Texture1 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; } } @@ -532,38 +599,71 @@ void _tnl_eval_vb( GLcontext *ctx, if (ctx->Eval.Map2TextureCoord4) { eval2_4f( &tmp->TexCoord[0], coord, flags, 4, &ctx->EvalMap.Map2Texture4 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; } else if (ctx->Eval.Map2TextureCoord3) { - eval2_4f( &tmp->TexCoord[0], coord, flags, 3, + eval2_4f( &tmp->TexCoord[0], coord, flags, 3, &ctx->EvalMap.Map2Texture3 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; } else if (ctx->Eval.Map2TextureCoord2) { eval2_4f( &tmp->TexCoord[0], coord, flags, 2, &ctx->EvalMap.Map2Texture2 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; } else if (ctx->Eval.Map2TextureCoord1) { eval2_4f( &tmp->TexCoord[0], coord, flags, 1, &ctx->EvalMap.Map2Texture1 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; } } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_4f( tmp->TexCoord[0].data, flags, 0, + VERT_TEX0| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); } if (req & VERT_NORM) { - if (!all_eval) - copy_3f( store->Normal, tmp->Normal.data, count ); + GLuint generated = 0; - tmp->Normal.data = store->Normal; - tmp->Normal.start = (GLfloat *)store->Normal; + if (copycount) { +/* fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); */ + copy_3f( store->Normal + IM->CopyStart, tmp->Normal.data, + copycount ); + } - if (ctx->Eval.Map1Normal && any_eval1) + 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, &ctx->EvalMap.Map1Normal ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } - if (ctx->Eval.Map2Normal && any_eval2) + if (ctx->Eval.Map2Normal && any_eval2) { eval2_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map2Normal ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_3f( tmp->Normal.data, flags, 0, + VERT_NORM| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); } @@ -573,17 +673,24 @@ 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) { - eval1_4f( &tmp->Obj, coord, flags, 4, + eval1_4f( &tmp->Obj, coord, flags, 4, &ctx->EvalMap.Map1Vertex4 ); } else if (ctx->Eval.Map1Vertex3) { @@ -595,16 +702,16 @@ void _tnl_eval_vb( GLcontext *ctx, if (any_eval2) { if (ctx->Eval.Map2Vertex4) { - if (ctx->Eval.AutoNormal && (req & VERT_NORM)) - eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4, + if (ctx->Eval.AutoNormal && (req & VERT_NORM)) + eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4, &ctx->EvalMap.Map2Vertex4 ); else - eval2_4f( &tmp->Obj, coord, flags, 4, + eval2_4f( &tmp->Obj, coord, flags, 4, &ctx->EvalMap.Map2Vertex4 ); } else if (ctx->Eval.Map2Vertex3) { - if (ctx->Eval.AutoNormal && (req & VERT_NORM)) + if (ctx->Eval.AutoNormal && (req & VERT_NORM)) eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3, &ctx->EvalMap.Map2Vertex3 ); else @@ -615,24 +722,47 @@ void _tnl_eval_vb( GLcontext *ctx, } + /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for + * the case where vertex maps are not enabled for some received eval + * coordinates. + */ + if (purge_flags) { + GLuint vertex = VERT_OBJ|(VERT_EVAL_ANY & ~purge_flags); + GLuint last_new_prim = 0; + GLuint new_prim_length = 0; + GLuint next_old_prim = 0; + struct vertex_buffer *VB = &tnl->vb; + GLuint i,j,count = VB->Count; + +/* fprintf(stderr, "PURGING\n"); */ + + for (i = 0, j = 0 ; i < count ; i++) { + if (flags[i] & vertex) { + store->Elt[j++] = i; + new_prim_length++; + } + if (i == next_old_prim) { + next_old_prim += VB->PrimitiveLength[i]; + VB->PrimitiveLength[last_new_prim] = new_prim_length; + VB->Primitive[j] = VB->Primitive[i]; + last_new_prim = j; + } + } + + VB->Elts = store->Elt; + _tnl_get_purged_copy_verts( ctx, store ); + } + + /* Produce new flags array: + */ { GLuint i; + GLuint count = tnl->vb.Count + 1; + copy_1ui( store->Flag, flags, count ); tnl->vb.Flag = store->Flag; - - /* This is overkill, but correct as fixup will have copied the - * values to all vertices in the VB - we may be falsely stating - * that some repeated values are new, but doing so is fairly - * harmless. - */ for (i = 0 ; i < count ; i++) store->Flag[i] |= req; + IM->CopyOrFlag |= req; /* hack for copying. */ } } - - - - - - -