Lots more eval fixes
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 30 Apr 2001 21:08:51 +0000 (21:08 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Mon, 30 Apr 2001 21:08:51 +0000 (21:08 +0000)
13 files changed:
src/mesa/drivers/common/t_dd_vb.c
src/mesa/main/enums.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_eval_api.c
src/mesa/tnl/t_imm_alloc.c
src/mesa/tnl/t_imm_api.c
src/mesa/tnl/t_imm_dlist.c
src/mesa/tnl/t_imm_elt.c
src/mesa/tnl/t_imm_eval.c
src/mesa/tnl/t_imm_eval.h
src/mesa/tnl/t_imm_exec.c
src/mesa/tnl/t_imm_fixup.c
src/mesa/tnl/t_imm_fixup.h

index e3bb890..97be42d 100644 (file)
@@ -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
 #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?
index 8510ce8..7fe9d94 100644 (file)
@@ -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;
    }
 }
index 5b57fe8..d5fc43f 100644 (file)
@@ -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;
index 10700e8..798b8f4 100644 (file)
@@ -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;
index def3b9c..2b497a7 100644 (file)
@@ -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;
+}
index 5b46308..c7184c8 100644 (file)
@@ -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 );
index 7218244..9af32da 100644 (file)
@@ -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);
 }
 
 
index c339897..b6fb093 100644 (file)
@@ -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;
 }
index d06f702..8a83ec1 100644 (file)
@@ -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. */
    }
 }
index 951a93d..341da51 100644 (file)
@@ -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
index 18eaa48..4ee77b7 100644 (file)
@@ -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
 
 
 
-/* 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);
+   }
 }
index 53e5dcb..1c3cf28 100644 (file)
@@ -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)) {
index 5847121..5ca68b2 100644 (file)
@@ -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,