diff options
| -rw-r--r-- | src/mesa/main/api_noop.c | 2 | ||||
| -rw-r--r-- | src/mesa/main/context.c | 4 | ||||
| -rw-r--r-- | src/mesa/main/get.c | 6 | ||||
| -rw-r--r-- | src/mesa/main/mtypes.h | 10 | ||||
| -rw-r--r-- | src/mesa/main/state.c | 4 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_context.c | 57 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_context.h | 14 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec.h | 3 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec_api.c | 76 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec_draw.c | 2 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_save.c | 9 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_save_draw.c | 22 | 
12 files changed, 107 insertions, 102 deletions
| diff --git a/src/mesa/main/api_noop.c b/src/mesa/main/api_noop.c index 33d44e4329..0c1a35361f 100644 --- a/src/mesa/main/api_noop.c +++ b/src/mesa/main/api_noop.c @@ -45,7 +45,7 @@  static void GLAPIENTRY _mesa_noop_EdgeFlag( GLboolean b )  {     GET_CURRENT_CONTEXT(ctx); -   ctx->Current.EdgeFlag = b; +   ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] = (GLfloat)b;  }  static void GLAPIENTRY _mesa_noop_Indexf( GLfloat f ) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index e0630c33d0..15b69db595 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -967,8 +967,8 @@ _mesa_init_current( GLcontext *ctx )     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 ); -   ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0] = 1.0; -   ctx->Current.EdgeFlag = GL_TRUE; +   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); +   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );  } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 61a76d000b..2a24b56974 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -323,7 +323,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )        case GL_EDGE_FLAG:           {           FLUSH_CURRENT(ctx, 0); -         params[0] = ctx->Current.EdgeFlag; +         params[0] = (ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F);           }           break;        case GL_FEEDBACK_BUFFER_SIZE: @@ -2147,7 +2147,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )        case GL_EDGE_FLAG:           {           FLUSH_CURRENT(ctx, 0); -         params[0] = BOOLEAN_TO_FLOAT(ctx->Current.EdgeFlag); +         params[0] = BOOLEAN_TO_FLOAT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F);           }           break;        case GL_FEEDBACK_BUFFER_SIZE: @@ -3971,7 +3971,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )        case GL_EDGE_FLAG:           {           FLUSH_CURRENT(ctx, 0); -         params[0] = BOOLEAN_TO_INT(ctx->Current.EdgeFlag); +         params[0] = BOOLEAN_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F);           }           break;        case GL_FEEDBACK_BUFFER_SIZE: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 903779edae..bc7c6b8026 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -143,7 +143,7 @@ enum     VERT_ATTRIB_COLOR1 = 4,     VERT_ATTRIB_FOG = 5,     VERT_ATTRIB_COLOR_INDEX = 6, -   VERT_ATTRIB_SEVEN = 7, +   VERT_ATTRIB_EDGEFLAG = 7,     VERT_ATTRIB_TEX0 = 8,     VERT_ATTRIB_TEX1 = 9,     VERT_ATTRIB_TEX2 = 10, @@ -183,7 +183,7 @@ enum  #define VERT_BIT_COLOR1      (1 << VERT_ATTRIB_COLOR1)  #define VERT_BIT_FOG         (1 << VERT_ATTRIB_FOG)  #define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX) -#define VERT_BIT_SEVEN       (1 << VERT_ATTRIB_SEVEN) +#define VERT_BIT_EDGEFLAG    (1 << VERT_ATTRIB_EDGEFLAG)  #define VERT_BIT_TEX0        (1 << VERT_ATTRIB_TEX0)  #define VERT_BIT_TEX1        (1 << VERT_ATTRIB_TEX1)  #define VERT_BIT_TEX2        (1 << VERT_ATTRIB_TEX2) @@ -616,11 +616,11 @@ struct gl_current_attrib     /**      * \name Current vertex attributes.      * \note Values are valid only after FLUSH_VERTICES has been called. +    * \note Index and Edgeflag current values are stored as floats in the  +    * SIX and SEVEN attribute slots.      */     /*@{*/     GLfloat Attrib[VERT_ATTRIB_MAX][4];	/**< Position, color, texcoords, etc */ -   GLfloat Index;			/**< Current color index */ -   GLboolean EdgeFlag;			/**< Current edge flag */     /*@}*/     /** @@ -2604,7 +2604,7 @@ struct matrix_stack  #define _NEW_ARRAY_COLOR1           VERT_BIT_COLOR1  #define _NEW_ARRAY_FOGCOORD         VERT_BIT_FOG  #define _NEW_ARRAY_INDEX            VERT_BIT_COLOR_INDEX -#define _NEW_ARRAY_EDGEFLAG         VERT_BIT_SEVEN +#define _NEW_ARRAY_EDGEFLAG         VERT_BIT_EDGEFLAG  #define _NEW_ARRAY_TEXCOORD_0       VERT_BIT_TEX0  #define _NEW_ARRAY_TEXCOORD_1       VERT_BIT_TEX1  #define _NEW_ARRAY_TEXCOORD_2       VERT_BIT_TEX2 diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 7dbcf8ad97..d57217d9c4 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -887,8 +887,8 @@ update_arrays( GLcontext *ctx )     /* 7 */     if (ctx->VertexProgram._Enabled -       && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN].Enabled) { -      min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN]._MaxElement); +       && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { +      min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement);     }     /* 8..15 */ diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 291eb0bed3..165e32da8a 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -61,27 +61,14 @@ static void init_legacy_currval(GLcontext *ctx)     for (i = 0; i < NR_LEGACY_ATTRIBS; i++) {        struct gl_client_array *cl = &arrays[i]; -      switch (i) { -      case VBO_ATTRIB_EDGEFLAG: -	 cl->Type = GL_UNSIGNED_BYTE; -	 cl->Ptr = (const void *)&ctx->Current.EdgeFlag; -	 break; -      case VBO_ATTRIB_INDEX: -	 cl->Type = GL_FLOAT; -	 cl->Ptr = (const void *)&ctx->Current.Index; -	 break; -      default: -	 cl->Type = GL_FLOAT; -	 cl->Ptr = (const void *)ctx->Current.Attrib[i]; -	 break; -      } - -      /* This will have to be determined at runtime: +      /* Size will have to be determined at runtime:         */        cl->Size = 1;        cl->Stride = 0;        cl->StrideB = 0;        cl->Enabled = 1; +      cl->Type = GL_FLOAT; +      cl->Ptr = (const void *)ctx->Current.Attrib[i];        cl->BufferObj = ctx->Array.NullBufferObj;     }  } @@ -118,12 +105,12 @@ static void init_mat_currval(GLcontext *ctx)     struct gl_client_array *arrays = vbo->mat_currval;     GLuint i; -   memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); +   memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS);     /* Set up a constant (StrideB == 0) array for each current      * attribute:      */ -   for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { +   for (i = 0; i < NR_MAT_ATTRIBS; i++) {        struct gl_client_array *cl = &arrays[i];        /* Size is fixed for the material attributes, for others will @@ -156,7 +143,23 @@ static void init_mat_currval(GLcontext *ctx)     }  } +#if 0 +static void vbo_exec_current_init( struct vbo_exec_context *exec )  +{ +   GLcontext *ctx = exec->ctx; +   GLint i; + +   /* setup the pointers for the typical 16 vertex attributes */ +   for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++)  +      exec->vtx.current[i] = ctx->Current.Attrib[i]; + +   /* setup pointers for the 12 material attributes */ +   for (i = 0; i < MAT_ATTRIB_MAX; i++) +      exec->vtx.current[VBO_ATTRIB_FIRST_MATERIAL + i] =  +	 ctx->Light.Material.Attrib[i]; +} +#endif  GLboolean _vbo_CreateContext( GLcontext *ctx )  { @@ -171,13 +174,11 @@ GLboolean _vbo_CreateContext( GLcontext *ctx )        return GL_FALSE;     } -   /* Hook our functions into exec and compile dispatch tables.  These -    * will pretty much be permanently installed, which means that the -    * vtxfmt mechanism can be removed now. +   /* TODO: remove these pointers.      */ -   vbo_exec_init( ctx ); -   vbo_save_init( ctx ); - +   vbo->legacy_currval = &vbo->currval[VBO_ATTRIB_POS]; +   vbo->generic_currval = &vbo->currval[VBO_ATTRIB_GENERIC0]; +   vbo->mat_currval = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT];     init_legacy_currval( ctx );     init_generic_currval( ctx ); @@ -207,6 +208,14 @@ GLboolean _vbo_CreateContext( GLcontext *ctx )     /* By default:       */     vbo->draw_prims = _tnl_draw_prims; + +   /* Hook our functions into exec and compile dispatch tables.  These +    * will pretty much be permanently installed, which means that the +    * vtxfmt mechanism can be removed now. +    */ +   vbo_exec_init( ctx ); +   vbo_save_init( ctx ); +     return GL_TRUE;  } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 982da00437..cd02472023 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -57,13 +57,21 @@  struct vbo_context { -   struct gl_client_array legacy_currval[16]; -   struct gl_client_array generic_currval[16]; -   struct gl_client_array mat_currval[16]; +   struct gl_client_array currval[VBO_ATTRIB_MAX]; +    +   /* These point into the above.  TODO: remove.  +    */ +   struct gl_client_array *legacy_currval; +   struct gl_client_array *generic_currval; +   struct gl_client_array *mat_currval;     GLuint map_vp_none[32];     GLuint map_vp_arb[32]; +   GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ +   GLfloat CurrentFloatEdgeFlag; + +     struct vbo_exec_context exec;     struct vbo_save_context save; diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index ef158de825..e1fc7b2794 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -87,9 +87,6 @@ struct vbo_exec_context        GLfloat *vbptr;		     /* cursor, points into buffer */        GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */ -      GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ -      GLfloat CurrentFloatEdgeFlag; -        GLuint vert_count;        GLuint max_vert;        struct vbo_exec_copied_vtx copied; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index c764c4d8b6..71fee8ca16 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -130,17 +130,28 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )  static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )  {     GLcontext *ctx = exec->ctx; +   struct vbo_context *vbo = vbo_context(ctx);     GLuint i;     for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {        if (exec->vtx.attrsz[i]) { +	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; +           /* Note: the exec->vtx.current[i] pointers point into the            * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.            */ -	 COPY_CLEAN_4V(exec->vtx.current[i],  +	 COPY_CLEAN_4V(current,   		       exec->vtx.attrsz[i],   		       exec->vtx.attrptr[i]); +	  +	 /* Given that we explicitly state size here, there is no need +	  * for the COPY_CLEAN above, could just copy 16 bytes and be +	  * done.  The only problem is when Mesa accesses ctx->Current +	  * directly. +	  */ +	 vbo->currval[i].Size = exec->vtx.attrsz[i]; +  	 /* This triggers rather too much recalculation of Mesa state  	  * that doesn't get used (eg light positions).  	  */ @@ -150,19 +161,6 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )        }     } -   /* color index is special (it's not a float[4] so COPY_CLEAN_4V above -    * will trash adjacent memory!) -    */ -   if (exec->vtx.attrsz[VBO_ATTRIB_INDEX]) { -      ctx->Current.Index = exec->vtx.attrptr[VBO_ATTRIB_INDEX][0]; -   } - -   /* Edgeflag requires additional treatment: -    */ -   if (exec->vtx.attrsz[VBO_ATTRIB_EDGEFLAG]) { -      ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); -   } -     /* Colormaterial -- this kindof sucks.      */     if (ctx->Light.ColorMaterialEnabled && @@ -178,21 +176,19 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )  static void vbo_exec_copy_from_current( struct vbo_exec_context *exec )  {     GLcontext *ctx = exec->ctx; +   struct vbo_context *vbo = vbo_context(ctx);     GLint i; -   /* Edgeflag requires additional treatment: -    */ -   exec->vtx.CurrentFloatEdgeFlag =  -      (GLfloat)ctx->Current.EdgeFlag; -    -   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++)  +   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { +      const GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;        switch (exec->vtx.attrsz[i]) { -      case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; -      case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; -      case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; -      case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; +      case 4: exec->vtx.attrptr[i][3] = current[3]; +      case 3: exec->vtx.attrptr[i][2] = current[2]; +      case 2: exec->vtx.attrptr[i][1] = current[1]; +      case 1: exec->vtx.attrptr[i][0] = current[0];  	 break;        } +   }     ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;  } @@ -205,6 +201,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,  					  GLuint newsz )  {     GLcontext *ctx = exec->ctx; +   struct vbo_context *vbo = vbo_context(ctx);     GLint lastcount = exec->vtx.vert_count;     GLfloat *tmp;     GLuint oldsz; @@ -281,7 +278,8 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,  		     data += oldsz;  		     dest += newsz;  		  } else { -		     COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); +		     const GLfloat *current = (const GLfloat *)vbo->currval[j].Ptr; +		     COPY_SZ_4V( dest, newsz, current );  		     dest += newsz;  		  }  	       } @@ -627,27 +625,10 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )  } -static void vbo_exec_current_init( struct vbo_exec_context *exec )  -{ -   GLcontext *ctx = exec->ctx; -   GLint i; - -   /* setup the pointers for the typical 16 vertex attributes */ -   for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++)  -      exec->vtx.current[i] = ctx->Current.Attrib[i]; - -   /* setup pointers for the 12 material attributes */ -   for (i = 0; i < MAT_ATTRIB_MAX; i++) -      exec->vtx.current[VBO_ATTRIB_FIRST_MATERIAL + i] =  -	 ctx->Light.Material.Attrib[i]; - -   exec->vtx.current[VBO_ATTRIB_INDEX] = &ctx->Current.Index; -   exec->vtx.current[VBO_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; -} -  void vbo_exec_vtx_init( struct vbo_exec_context *exec )  {     GLcontext *ctx = exec->ctx; +   struct vbo_context *vbo = vbo_context(ctx);     GLuint i;     /* Allocate a buffer object.  Will just reuse this object @@ -656,7 +637,6 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )     exec->vtx.bufferobj = ctx->Array.NullBufferObj;     exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); -   vbo_exec_current_init( exec );     vbo_exec_vtxfmt_init( exec );     /* Hook our functions into the dispatch table. @@ -668,7 +648,13 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )        exec->vtx.active_sz[i] = 0;        exec->vtx.inputs[i] = &exec->vtx.arrays[i];     } -  +    +   { +      struct gl_client_array *arrays = exec->vtx.arrays; +      memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0])); +      memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); +   } +     exec->vtx.vertex_size = 0;  } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index c1898aea49..846d5dc196 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -151,7 +151,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )     switch (get_program_mode(exec->ctx)) {     case VP_NONE:        memcpy(arrays,      vbo->legacy_currval, 16 * sizeof(arrays[0])); -      memcpy(arrays + 16, vbo->mat_currval,    16 * sizeof(arrays[0])); +      memcpy(arrays + 16, vbo->mat_currval,    MAT_ATTRIB_MAX * sizeof(arrays[0]));        map = vbo->map_vp_none;        break;     case VP_NV: diff --git a/src/mesa/vbo/vbo_save.c b/src/mesa/vbo/vbo_save.c index 3a97ea66a4..e7f4687963 100644 --- a/src/mesa/vbo/vbo_save.c +++ b/src/mesa/vbo/vbo_save.c @@ -49,13 +49,20 @@ static void vbo_save_callback_init( GLcontext *ctx )  void vbo_save_init( GLcontext *ctx )  { -   struct vbo_save_context *save = &vbo_context(ctx)->save; +   struct vbo_context *vbo = vbo_context(ctx); +   struct vbo_save_context *save = &vbo->save;     save->ctx = ctx;     vbo_save_api_init( save );     vbo_save_callback_init(ctx); +   { +      struct gl_client_array *arrays = save->arrays; +      memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0])); +      memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); +   } +     ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;  } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 18c770a41c..527e57d6bd 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -41,7 +41,7 @@  static void _playback_copy_to_current( GLcontext *ctx,  				       const struct vbo_save_vertex_list *node )  { -   struct vbo_save_context *save = &vbo_context(ctx)->save;  +   struct vbo_context *vbo = vbo_context(ctx);     GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex;     GLuint i, offset; @@ -55,7 +55,14 @@ static void _playback_copy_to_current( GLcontext *ctx,     for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) {        if (node->attrsz[i]) { -	 COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); +	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + +	 COPY_CLEAN_4V(current,  +		       node->attrsz[i],  +		       data); + +	 vbo->currval[i].Size = node->attrsz[i]; +  	 data += node->attrsz[i];  	 if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && @@ -64,20 +71,11 @@ static void _playback_copy_to_current( GLcontext *ctx,        }     } -   /* Edgeflag requires special treatment: -    */ -   if (node->attrsz[VBO_ATTRIB_EDGEFLAG]) { -      ctx->Current.EdgeFlag = (data[0] == 1.0); -   } - - -#if 1     /* Colormaterial -- this kindof sucks.      */     if (ctx->Light.ColorMaterialEnabled) {        _mesa_update_color_material(ctx, ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);     } -#endif     /* CurrentExecPrimitive      */ @@ -111,7 +109,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx,     switch (get_program_mode(ctx)) {     case VP_NONE:        memcpy(arrays,      vbo->legacy_currval, 16 * sizeof(arrays[0])); -      memcpy(arrays + 16, vbo->mat_currval,    16 * sizeof(arrays[0])); +      memcpy(arrays + 16, vbo->mat_currval,    MAT_ATTRIB_MAX * sizeof(arrays[0]));        map = vbo->map_vp_none;        break;     case VP_NV: | 
