From 05b26510668fc1e5039c6c9088247f9b3c508cb7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 31 Mar 2003 18:19:56 +0000 Subject: [PATCH] reduce memory needed for vertex attributes (allocate on demand) --- src/mesa/tnl/t_context.h | 24 ++-- src/mesa/tnl/t_imm_alloc.c | 23 +++- src/mesa/tnl/t_imm_api.c | 261 +++++++++++++++++++++---------------- src/mesa/tnl/t_imm_dlist.c | 12 +- src/mesa/tnl/t_imm_elt.c | 15 ++- src/mesa/tnl/t_imm_eval.c | 15 ++- src/mesa/tnl/t_imm_fixup.c | 171 +++++++++++++++--------- src/mesa/tnl/t_imm_fixup.h | 10 +- 8 files changed, 327 insertions(+), 204 deletions(-) diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index d08da93abdb..b7153c545f5 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.45 2003/03/28 01:39:04 brianp Exp $ */ +/* $Id: t_context.h,v 1.46 2003/03/31 18:19:56 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -192,16 +192,12 @@ struct immediate GLuint PrimitiveLength[IMM_SIZE]; /* BEGIN/END */ GLuint Flag[IMM_SIZE]; /* VERT_BIT_* flags */ - /* All vertex attributes (position, normal, color, secondary color, - * texcoords, fog coord) are stored in the Attrib[] arrays instead - * of individual arrays as we did prior to Mesa 4.1. - * - * XXX may need to use 32-byte aligned allocation for this!!! - * XXX replace this with GLfloat *Attrib[VERT_ATTRIB_MAX] and allocate - * the attribute arrays as needed, so save memory. As is, we're using - * 256 bytes per vertex (16 attribs * 4 comps/attrib * 4 bytes/comp). + /* Attrib is an array [MAX_VERT_ATTRIBS] of pointer to array [][4] + * of GLfloat. + * We only pre-allocate the vertex position array. The other vertex + * attribute arrays are only allocated when needed to save memory. */ - GLfloat Attrib[VERT_ATTRIB_MAX][IMM_SIZE][4]; /* GL_NV_vertex_program */ + GLfloat (*Attrib[VERT_ATTRIB_MAX])[4]; GLfloat *NormalLengthPtr; /* length of normal vectors (display list only) */ @@ -213,16 +209,16 @@ struct immediate struct vertex_arrays { - /* XXX move a bunch of these fields into the Attribs[] array??? */ + /* Conventional vertex attribute arrays */ GLvector4f Obj; GLvector4f Normal; struct gl_client_array Color; struct gl_client_array SecondaryColor; - GLvector1ui Index; - GLvector1ub EdgeFlag; + GLvector4f FogCoord; GLvector4f TexCoord[MAX_TEXTURE_COORD_UNITS]; + GLvector1ub EdgeFlag; + GLvector1ui Index; GLvector1ui Elt; - GLvector4f FogCoord; /* These attributes don't alias with the conventional attributes. * The GL_NV_vertex_program extension defines 16 extra sets of vertex diff --git a/src/mesa/tnl/t_imm_alloc.c b/src/mesa/tnl/t_imm_alloc.c index f0c31a7642e..48a657028b5 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.19 2003/03/29 17:09:42 brianp Exp $ */ +/* $Id: t_imm_alloc.c,v 1.20 2003/03/31 18:19:56 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -57,6 +57,20 @@ real_alloc_immediate( GLcontext *ctx ) immed->TexSize = 0; immed->NormalLengthPtr = 0; + /* Only allocate space for vertex positions right now. Color, texcoord, + * etc storage will be allocated as needed. + */ + immed->Attrib[VERT_ATTRIB_POS] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + + /* Enable this to allocate all attribute arrays up front */ + if (0) + { + int i; + for (i = 1; i < VERT_ATTRIB_MAX; i++) { + immed->Attrib[i] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + } + } + immed->CopyTexSize = 0; immed->CopyStart = immed->Start; @@ -68,6 +82,13 @@ static void real_free_immediate( struct immediate *immed ) { static int freed = 0; + GLuint i; + + for (i =0; i < VERT_ATTRIB_MAX; i++) { + if (immed->Attrib[i]) + _mesa_free(immed->Attrib[i]); + immed->Attrib[i] = NULL; + } if (immed->Material) { FREE( immed->Material ); diff --git a/src/mesa/tnl/t_imm_api.c b/src/mesa/tnl/t_imm_api.c index 462d8dbaf6e..0eef3b735ca 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.39 2003/01/14 04:55:47 brianp Exp $ */ +/* $Id: t_imm_api.c,v 1.40 2003/03/31 18:19:56 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -330,10 +330,6 @@ _tnl_hard_begin( GLcontext *ctx, GLenum p ) } - - - - /* Both streams now outside begin/end. * * Leave SavedBeginState untouched -- attempt to gather several @@ -404,16 +400,32 @@ _tnl_End(void) } +/* If the given vertex attribute array hasn't been allocated yet, + * allocate it now. + */ +#define CHECK_ATTRIB_ARRAY(IM, ATTR) \ + if (!IM->Attrib[ATTR]) { \ + IM->Attrib[ATTR] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); \ + if (!IM->Attrib[ATTR]) { \ + GET_CURRENT_CONTEXT(ctx); \ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glVertex/Normal/etc"); \ + return; \ + } \ + } + + #define COLOR( r, g, b, a ) \ { \ GET_IMMEDIATE; \ GLuint count = IM->Count; \ - GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \ - IM->Flag[count] |= VERT_BIT_COLOR0; \ + GLfloat *color; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_COLOR0); \ + color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \ color[0] = r; \ color[1] = g; \ color[2] = b; \ color[3] = a; \ + IM->Flag[count] |= VERT_BIT_COLOR0; \ } static void @@ -478,16 +490,17 @@ _tnl_Color4ubv( const GLubyte *v) - #define SECONDARY_COLOR( r, g, b ) \ { \ - GLuint count; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + GLfloat *color; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_COLOR1); \ + color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \ + color[0] = r; \ + color[1] = g; \ + color[2] = b; \ IM->Flag[count] |= VERT_BIT_COLOR1; \ - IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r; \ - IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g; \ - IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b; \ } static void @@ -544,20 +557,20 @@ _tnl_EdgeFlagv( const GLboolean *flag ) static void _tnl_FogCoordfEXT( GLfloat f ) { - GLuint count; GET_IMMEDIATE; - count = IM->Count; - IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; /*FogCoord[count] = f;*/ + GLuint count = IM->Count; + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_FOG); + IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; IM->Flag[count] |= VERT_BIT_FOG; } static void _tnl_FogCoordfvEXT( const GLfloat *v ) { - GLuint count; GET_IMMEDIATE; - count = IM->Count; - IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; /*FogCoord[count] = v[0];*/ + GLuint count = IM->Count; + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_FOG); + IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; IM->Flag[count] |= VERT_BIT_FOG; } @@ -586,27 +599,27 @@ _tnl_Indexiv( const GLint *c ) #define NORMAL( x, y, z ) \ { \ - GLuint count; \ - GLfloat *normal; \ GET_IMMEDIATE; \ - count = IM->Count; \ - IM->Flag[count] |= VERT_BIT_NORMAL; \ + GLuint count = IM->Count; \ + GLfloat *normal; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_NORMAL); \ normal = IM->Attrib[VERT_ATTRIB_NORMAL][count]; \ ASSIGN_3V(normal, x,y,z); \ + IM->Flag[count] |= VERT_BIT_NORMAL; \ } -#if defined(USE_IEEE) +#if defined(USE_IEEE_foo) #define NORMALF( x, y, z ) \ { \ - GLuint count; \ - fi_type *normal; \ GET_IMMEDIATE; \ - count = IM->Count; \ - IM->Flag[count] |= VERT_BIT_NORMAL; \ + GLuint count = IM->Count; \ + fi_type *normal; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_NORMAL); \ normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count]; \ normal[0].i = ((fi_type *)&(x))->i; \ normal[1].i = ((fi_type *)&(y))->i; \ normal[2].i = ((fi_type *)&(z))->i; \ + IM->Flag[count] |= VERT_BIT_NORMAL; \ } #else #define NORMALF NORMAL @@ -623,54 +636,52 @@ static void _tnl_Normal3fv( const GLfloat *v ) { NORMALF( v[0], v[1], v[2] ); -/* struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */ -/* IM->Flag[IM->Count] = VERT_NORM; */ } #define TEXCOORD1(s) \ { \ - GLuint count; \ - GLfloat *tc; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + GLfloat *tc; \ IM->Flag[count] |= VERT_BIT_TEX0; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0); \ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \ ASSIGN_4V(tc,s,0,0,1); \ } #define TEXCOORD2(s, t) \ { \ - GLuint count; \ - GLfloat *tc; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + GLfloat *tc; \ IM->Flag[count] |= VERT_BIT_TEX0; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0); \ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \ ASSIGN_4V(tc, s, t, 0, 1); \ } #define TEXCOORD3(s, t, u) \ { \ - GLuint count; \ - GLfloat *tc; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + GLfloat *tc; \ IM->Flag[count] |= VERT_BIT_TEX0; \ IM->TexSize |= TEX_0_SIZE_3; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0); \ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \ ASSIGN_4V(tc, s, t, u, 1); \ } #define TEXCOORD4(s, t, u, v) \ { \ - GLuint count; \ - GLfloat *tc; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + GLfloat *tc; \ IM->Flag[count] |= VERT_BIT_TEX0; \ IM->TexSize |= TEX_0_SIZE_4; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0); \ tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \ ASSIGN_4V(tc, s, t, u, v); \ } @@ -678,11 +689,11 @@ _tnl_Normal3fv( const GLfloat *v ) #if defined(USE_IEEE) #define TEXCOORD2F(s, t) \ { \ - GLuint count; \ - fi_type *tc; \ GET_IMMEDIATE; \ - count = IM->Count; \ + GLuint count = IM->Count; \ + fi_type *tc; \ IM->Flag[count] |= VERT_BIT_TEX0; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0); \ tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count]; \ tc[0].i = ((fi_type *)&(s))->i; \ tc[1].i = ((fi_type *)&(t))->i; \ @@ -754,7 +765,7 @@ _tnl_TexCoord4fv( const GLfloat *v ) GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BIT_POS; \ ASSIGN_4V(dest, x, y, 0, 1); \ -/* ASSERT(IM->Flag[IM->Count]==0); */ \ + /*ASSERT(IM->Flag[IM->Count]==0);*/ \ if (count == IMM_MAXDATA - 1) \ _tnl_flush_immediate( NULL, IM ); \ } @@ -765,7 +776,7 @@ _tnl_TexCoord4fv( const GLfloat *v ) GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BITS_OBJ_23; \ ASSIGN_4V(dest, x, y, z, 1); \ -/* ASSERT(IM->Flag[IM->Count]==0); */ \ + /*ASSERT(IM->Flag[IM->Count]==0);*/ \ if (count == IMM_MAXDATA - 1) \ _tnl_flush_immediate( NULL, IM ); \ } @@ -790,7 +801,7 @@ _tnl_TexCoord4fv( const GLfloat *v ) dest[1].i = ((fi_type *)&(y))->i; \ dest[2].i = 0; \ dest[3].i = IEEE_ONE; \ -/* ASSERT(IM->Flag[IM->Count]==0); */ \ + /*ASSERT(IM->Flag[IM->Count]==0);*/ \ if (count == IMM_MAXDATA - 1) \ _tnl_flush_immediate( NULL, IM ); \ } @@ -808,7 +819,7 @@ _tnl_TexCoord4fv( const GLfloat *v ) dest[1].i = ((fi_type *)&(y))->i; \ dest[2].i = ((fi_type *)&(z))->i; \ dest[3].i = IEEE_ONE; \ -/* ASSERT(IM->Flag[IM->Count]==0); */ \ + /*ASSERT(IM->Flag[IM->Count]==0);*/ \ if (count == IMM_MAXDATA - 1) \ _tnl_flush_immediate( NULL, IM ); \ } @@ -889,71 +900,81 @@ _tnl_Vertex4fv( const GLfloat *v ) #define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_COORD_UNITS) -#define MULTI_TEXCOORD1(target, s) \ -{ \ - GET_IMMEDIATE; \ - GLuint texunit = target - GL_TEXTURE0_ARB; \ - if (texunit < IM->MaxTextureUnits) { \ - GLuint count = IM->Count; \ - GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ - ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \ - IM->Flag[count] |= VERT_BIT_TEX(texunit); \ - } \ -} - -#define MULTI_TEXCOORD2(target, s, t) \ -{ \ - GET_IMMEDIATE; \ - GLuint texunit = target - GL_TEXTURE0_ARB; \ - if (texunit < IM->MaxTextureUnits) { \ - GLuint count = IM->Count; \ - GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ - ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \ - IM->Flag[count] |= VERT_BIT_TEX(texunit); \ - } \ +#define MULTI_TEXCOORD1(target, s) \ +{ \ + GET_IMMEDIATE; \ + const GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + const GLuint count = IM->Count; \ + GLfloat *tc; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0 + texunit); \ + tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ + ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \ + IM->Flag[count] |= VERT_BIT_TEX(texunit); \ + } \ } -#define MULTI_TEXCOORD3(target, s, t, u) \ -{ \ - GET_IMMEDIATE; \ - GLuint texunit = target - GL_TEXTURE0_ARB; \ - if (texunit < IM->MaxTextureUnits) { \ - GLuint count = IM->Count; \ - GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ - ASSIGN_4V(tc, s, t, u, 1.0F); \ - IM->Flag[count] |= VERT_BIT_TEX(texunit); \ - IM->TexSize |= TEX_SIZE_3(texunit); \ - } \ +#define MULTI_TEXCOORD2(target, s, t) \ +{ \ + GET_IMMEDIATE; \ + const GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + const GLuint count = IM->Count; \ + GLfloat *tc; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0 + texunit); \ + tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ + ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \ + IM->Flag[count] |= VERT_BIT_TEX(texunit); \ + } \ } -#define MULTI_TEXCOORD4(target, s, t, u, v) \ -{ \ - GET_IMMEDIATE; \ - GLuint texunit = target - GL_TEXTURE0_ARB; \ - if (texunit < IM->MaxTextureUnits) { \ - GLuint count = IM->Count; \ - GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ - ASSIGN_4V(tc, s, t, u, v); \ - IM->Flag[count] |= VERT_BIT_TEX(texunit); \ - IM->TexSize |= TEX_SIZE_4(texunit); \ - } \ +#define MULTI_TEXCOORD3(target, s, t, u) \ +{ \ + GET_IMMEDIATE; \ + const GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + const GLuint count = IM->Count; \ + GLfloat *tc; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0 + texunit); \ + tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ + ASSIGN_4V(tc, s, t, u, 1.0F); \ + IM->Flag[count] |= VERT_BIT_TEX(texunit); \ + IM->TexSize |= TEX_SIZE_3(texunit); \ + } \ } -#if defined(USE_IEEE) -#define MULTI_TEXCOORD2F(target, s, t) \ +#define MULTI_TEXCOORD4(target, s, t, u, v) \ { \ GET_IMMEDIATE; \ - GLuint texunit = target - GL_TEXTURE0_ARB; \ + const GLuint texunit = target - GL_TEXTURE0_ARB; \ if (texunit < IM->MaxTextureUnits) { \ - GLuint count = IM->Count; \ - fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\ + const GLuint count = IM->Count; \ + GLfloat *tc; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0 + texunit); \ + tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ + ASSIGN_4V(tc, s, t, u, v); \ IM->Flag[count] |= VERT_BIT_TEX(texunit); \ - tc[0].i = ((fi_type *)&(s))->i; \ - tc[1].i = ((fi_type *)&(t))->i; \ - tc[2].i = 0; \ - tc[3].i = IEEE_ONE; \ + IM->TexSize |= TEX_SIZE_4(texunit); \ } \ } + +#if defined(USE_IEEE) +#define MULTI_TEXCOORD2F(target, s, t) \ +{ \ + GET_IMMEDIATE; \ + const GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + const GLuint count = IM->Count; \ + fi_type *tc; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_TEX0 + texunit); \ + tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \ + IM->Flag[count] |= VERT_BIT_TEX(texunit); \ + tc[0].i = ((fi_type *)&(s))->i; \ + tc[1].i = ((fi_type *)&(t))->i; \ + tc[2].i = 0; \ + tc[3].i = IEEE_ONE; \ + } \ +} #else #define MULTI_TEXCOORD2F MULTI_TEXCOORD2 #endif @@ -1016,8 +1037,10 @@ _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v) */ #define EVALCOORD1(IM, x) \ { \ - GLuint count = IM->Count++; \ - GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ + const GLuint count = IM->Count++; \ + GLfloat *dest; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_POS); \ + dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BIT_EVAL_C1; \ ASSIGN_4V(dest, x, 0, 0, 1); \ if (count == IMM_MAXDATA-1) \ @@ -1026,8 +1049,10 @@ _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v) #define EVALCOORD2(IM, x, y) \ { \ - GLuint count = IM->Count++; \ - GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ + const GLuint count = IM->Count++; \ + GLfloat *dest; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_POS); \ + dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BIT_EVAL_C2; \ ASSIGN_4V(dest, x, y, 0, 1); \ if (count == IMM_MAXDATA-1) \ @@ -1036,8 +1061,10 @@ _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v) #define EVALPOINT1(IM, x) \ { \ - GLuint count = IM->Count++; \ - GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ + const GLuint count = IM->Count++; \ + GLfloat *dest; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_POS); \ + dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BIT_EVAL_P1; \ ASSIGN_4V(dest, x, 0, 0, 1); \ if (count == IMM_MAXDATA-1) \ @@ -1046,8 +1073,10 @@ _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v) #define EVALPOINT2(IM, x, y) \ { \ - GLuint count = IM->Count++; \ - GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ + const GLuint count = IM->Count++; \ + GLfloat *dest; \ + CHECK_ATTRIB_ARRAY(IM, VERT_ATTRIB_POS); \ + dest = IM->Attrib[VERT_ATTRIB_POS][count]; \ IM->Flag[count] |= VERT_BIT_EVAL_P2; \ ASSIGN_4V(dest, x, y, 0, 1); \ if (count == IMM_MAXDATA-1) \ @@ -1156,10 +1185,12 @@ _tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v ) static void _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { - if (index < 16) { + if (index < VERT_ATTRIB_MAX) { GET_IMMEDIATE; const GLuint count = IM->Count; - GLfloat *attrib = IM->Attrib[index][count]; + GLfloat *attrib; + CHECK_ATTRIB_ARRAY(IM, index); + attrib = IM->Attrib[index][count]; ASSIGN_4V(attrib, x, y, z, w); IM->Flag[count] |= (1 << index); if (index == 0) { @@ -1177,10 +1208,12 @@ _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w static void _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) { - if (index < 16) { + if (index < VERT_ATTRIB_MAX) { GET_IMMEDIATE; const GLuint count = IM->Count; - GLfloat *attrib = IM->Attrib[index][count]; + GLfloat *attrib; + CHECK_ATTRIB_ARRAY(IM, index); + attrib = IM->Attrib[index][count]; COPY_4V(attrib, v); IM->Flag[count] |= (1 << index); if (index == 0) { diff --git a/src/mesa/tnl/t_imm_dlist.c b/src/mesa/tnl/t_imm_dlist.c index 07dd86b334e..ff382c27c35 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.47 2003/03/28 01:39:05 brianp Exp $ */ +/* $Id: t_imm_dlist.c,v 1.48 2003/03/31 18:19:56 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -76,6 +76,11 @@ build_normal_lengths( struct immediate *IM ) GLuint *flags = IM->Flag + IM->Start; GLuint count = IM->Count - IM->Start; +#if 0 + if (!IM->Attrib[VERT_ATTRIB_NORMAL]) + return; +#endif + if (!dest) { dest = IM->NormalLengthPtr = (GLfloat *) ALIGN_MALLOC( IMM_SIZE*sizeof(GLfloat), 32 ); if (!dest) return; @@ -174,7 +179,10 @@ _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ) node->MaterialOrMask = im->MaterialOrMask; node->MaterialAndMask = im->MaterialAndMask; - if (tnl->CalcDListNormalLengths) { + /* + * XXX always allocate VERT_ATTRIB_NORMAL array now??? + */ + if (tnl->CalcDListNormalLengths && IM->Attrib[VERT_ATTRIB_NORMAL]) { build_normal_lengths( im ); } diff --git a/src/mesa/tnl/t_imm_elt.c b/src/mesa/tnl/t_imm_elt.c index c5f740373ed..7b3972af2a9 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.21 2003/03/01 01:50:27 brianp Exp $ */ +/* $Id: t_imm_elt.c,v 1.22 2003/03/31 18:19:56 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -755,7 +755,7 @@ void _tnl_translate_array_elts( GLcontext *ctx, struct immediate *IM, GLuint *flags = IM->Flag; GLuint *elts = IM->Elt; GLuint translate = ctx->Array._Enabled; - GLuint i; + GLuint i, attr; if (MESA_VERBOSE & VERBOSE_IMMEDIATE) _mesa_debug(ctx, "exec_array_elements %d .. %d\n", start, count); @@ -772,6 +772,17 @@ void _tnl_translate_array_elts( GLcontext *ctx, struct immediate *IM, translate |= VERT_BITS_OBJ_23; } + /* Allocate destination attribute arrays if needed */ + for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) { + if ((translate & (1 << attr)) && !IM->Attrib[attr]) { + IM->Attrib[attr] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + if (!IM->Attrib[attr]) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing2"); + return; + } + } + } + if (translate & VERT_BIT_NORMAL) _tnl_trans_elt_4f( IM->Attrib[VERT_ATTRIB_NORMAL], diff --git a/src/mesa/tnl/t_imm_eval.c b/src/mesa/tnl/t_imm_eval.c index f9f942aeea0..3b92d2a1740 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.28 2003/03/01 01:50:27 brianp Exp $ */ +/* $Id: t_imm_eval.c,v 1.29 2003/03/31 18:19:57 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -453,6 +453,7 @@ void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ) GLuint req = 0; GLuint purge_flags = 0; GLfloat (*coord)[4] = IM->Attrib[VERT_ATTRIB_POS] + IM->CopyStart; + GLuint attr; if (IM->AndFlag & VERT_BITS_EVAL_ANY) copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */ @@ -503,6 +504,18 @@ void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ) } } + /* Allocate vertex attribute storage now */ + for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { + if ((req & (1 << attr)) && !store->Attrib[attr]) { + store->Attrib[attr] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + if (!store->Attrib[attr]) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "evaluator processing"); + return; + } + } + } + + /* Perform the evaluations on active data elements. */ if (req & VERT_BIT_INDEX) { diff --git a/src/mesa/tnl/t_imm_fixup.c b/src/mesa/tnl/t_imm_fixup.c index 6e40db6b438..fd41108699d 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.41 2003/03/28 01:39:05 brianp Exp $ */ +/* $Id: t_imm_fixup.c,v 1.42 2003/03/31 18:19:57 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -57,7 +57,8 @@ static const GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 }; static const GLuint intro[GL_POLYGON+2] = { 0,0,2,2,0,2,2,0,2,2,0 }; void -_tnl_fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match ) +_tnl_fixup_4f( GLfloat data[][4], const GLuint flag[], + GLuint start, GLuint match ) { GLuint i = start; @@ -70,11 +71,11 @@ _tnl_fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match ) } void -_tnl_fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match ) +_tnl_fixup_3f( GLfloat data[][3], const GLuint flag[], + GLuint start, GLuint match ) { GLuint i = start; - for (;;) { if ((flag[++i] & match) == 0) { /* _mesa_debug(NULL, "_tnl_fixup_3f copy to %p values %f %f %f\n", */ @@ -119,7 +120,7 @@ _tnl_fixup_1f( GLfloat *data, GLuint flag[], GLuint start, GLuint match ) } void -_tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match ) +_tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match) { GLuint i = start; @@ -134,8 +135,8 @@ _tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match ) static void -fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match, - GLuint start, GLfloat *dflt ) +fixup_first_4f( GLfloat data[][4], const GLuint flag[], GLuint match, + GLuint start, const GLfloat *dflt ) { GLuint i = start-1; match |= VERT_BIT_END_VB; @@ -146,8 +147,8 @@ fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match, #if 0 static void -fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match, - GLuint start, GLfloat *dflt ) +fixup_first_3f( GLfloat data[][3], const GLuint flag[], GLuint match, + GLuint start, const GLfloat *dflt ) { GLuint i = start-1; match |= VERT_BIT_END_VB; @@ -161,8 +162,8 @@ fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match, #endif static void -fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match, - GLuint start, GLuint dflt ) +fixup_first_1ui( GLuint data[], const GLuint flag[], GLuint match, + GLuint start, const GLuint dflt ) { GLuint i = start-1; match |= VERT_BIT_END_VB; @@ -173,7 +174,7 @@ fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match, #if 00 static void -fixup_first_1f( GLfloat data[], GLuint flag[], GLuint match, +fixup_first_1f( GLfloat data[], const GLuint flag[], GLuint match, GLuint start, GLfloat dflt ) { GLuint i = start-1; @@ -185,7 +186,7 @@ fixup_first_1f( GLfloat data[], GLuint flag[], GLuint match, #endif static void -fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match, +fixup_first_1ub( GLubyte data[], const GLuint flag[], GLuint match, GLuint start, GLubyte dflt ) { GLuint i = start-1; @@ -200,7 +201,7 @@ fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match, * struct at the given position according to copyMask. */ static void copy_from_current( GLcontext *ctx, struct immediate *IM, - GLuint pos, GLuint copyMask ) + GLuint pos, GLuint copyMask ) { GLuint attrib, attribBit; @@ -209,6 +210,13 @@ static void copy_from_current( GLcontext *ctx, struct immediate *IM, for (attrib = 0, attribBit = 1; attrib < 16; attrib++, attribBit <<= 1) { if (copyMask & attribBit) { + if (!IM->Attrib[attrib]) { + IM->Attrib[attrib] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + if (!IM->Attrib[attrib]) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing3"); + return; + } + } COPY_4FV( IM->Attrib[attrib][pos], ctx->Current.Attrib[attrib]); } } @@ -249,8 +257,7 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) fixup = 0; if (fixup) { - GLuint copy = fixup & ~IM->Flag[start]; - + const GLuint copy = fixup & ~IM->Flag[start]; /* Equivalent to a lazy copy-from-current when setting up the * immediate. @@ -268,7 +275,7 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) if (fixup & VERT_BITS_TEX_ANY) { GLuint i; for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { - if (fixup & VERT_BIT_TEX(i)) { + if ((fixup & VERT_BIT_TEX(i))) { if (orflag & VERT_BIT_TEX(i)) _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag, start, VERT_BIT_TEX(i) ); @@ -280,23 +287,6 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) } } - - if (fixup & VERT_BIT_EDGEFLAG) { - if (orflag & VERT_BIT_EDGEFLAG) - _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_BIT_EDGEFLAG ); - else - fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_BIT_END_VB, start, - IM->EdgeFlag[start] ); - } - - if (fixup & VERT_BIT_INDEX) { - if (orflag & VERT_BIT_INDEX) - _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_BIT_INDEX ); - else - fixup_first_1ui( IM->Index, IM->Flag, VERT_BIT_END_VB, start, - IM->Index[start] ); - } - if (fixup & VERT_BIT_COLOR0) { if (orflag & VERT_BIT_COLOR0) _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag, start, @@ -311,7 +301,8 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, start, VERT_BIT_COLOR1 ); else - fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, VERT_BIT_END_VB, start, + fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, + VERT_BIT_END_VB, start, IM->Attrib[VERT_ATTRIB_COLOR1][start] ); } @@ -320,7 +311,8 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag, start, VERT_BIT_FOG ); else - fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag, VERT_BIT_END_VB, + fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag, + VERT_BIT_END_VB, start, IM->Attrib[VERT_ATTRIB_FOG][start] ); } @@ -333,6 +325,23 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) VERT_BIT_END_VB, start, IM->Attrib[VERT_ATTRIB_NORMAL][start] ); } + + if (fixup & VERT_BIT_EDGEFLAG) { + if (orflag & VERT_BIT_EDGEFLAG) + _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_BIT_EDGEFLAG ); + else + fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_BIT_END_VB, start, + IM->EdgeFlag[start] ); + } + + if (fixup & VERT_BIT_INDEX) { + if (orflag & VERT_BIT_INDEX) + _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_BIT_INDEX ); + else + fixup_first_1ui( IM->Index, IM->Flag, VERT_BIT_END_VB, start, + IM->Index[start] ); + } + } /* Prune possible half-filled slot. @@ -443,7 +452,7 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) } else { GLuint copy = tnl->pipeline.inputs & (prev->CopyOrFlag|prev->Evaluated); - GLuint flag; + GLuint flag, attr; if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) { flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_BITS_FIXUP); @@ -463,6 +472,17 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) /* _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */ /* _tnl_print_vert_flags("flag", flag); */ + /* Allocate attribute arrays in the destination immediate struct */ + for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { + if ((copy & (1 << attr)) && !next->Attrib[attr]) { + next->Attrib[attr] = _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat)); + if (!next->Attrib[attr]) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing"); + return; + } + } + } + /* Copy whole vertices */ for (i = 0 ; i < count ; i++) @@ -475,27 +495,21 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) * struct. (Copied rows should not be evaluated twice). * * Note these pointers are null when inactive. + * + * XXX try to use a loop over vertex attribs here. */ COPY_4FV( next->Attrib[VERT_ATTRIB_POS][dst], inputs->Obj.data[isrc] ); if (copy & VERT_BIT_NORMAL) { -/* _mesa_debug(ctx, "copy vert norm %d to %d (%p): %f %f %f\n", */ -/* isrc, dst, */ -/* next->Normal[dst], */ -/* inputs->Normal.data[isrc][0], */ -/* inputs->Normal.data[isrc][1], */ -/* inputs->Normal.data[isrc][2]); */ - COPY_3FV( next->Attrib[VERT_ATTRIB_NORMAL][dst], inputs->Normal.data[isrc] ); + COPY_3FV( next->Attrib[VERT_ATTRIB_NORMAL][dst], + inputs->Normal.data[isrc] ); } if (copy & VERT_BIT_COLOR0) COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR0][dst], ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] ); - if (copy & VERT_BIT_INDEX) - next->Index[dst] = inputs->Index.data[isrc]; - if (copy & VERT_BITS_TEX_ANY) { GLuint i; for (i = 0 ; i < prev->MaxTextureUnits ; i++) { @@ -505,22 +519,28 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) } } - /* Remaining values should be the same in the 'input' struct and the - * original immediate. - */ - if (copy & (VERT_BIT_ELT|VERT_BIT_EDGEFLAG|VERT_BIT_COLOR1|VERT_BIT_FOG| - VERT_BIT_MATERIAL)) { - - if (prev->Flag[src] & VERT_BIT_MATERIAL) - copy_material(next, prev, dst, src); - - next->Elt[dst] = prev->Elt[src]; - next->EdgeFlag[dst] = prev->EdgeFlag[src]; + /* the rest aren't used for evaluators */ + if (copy & VERT_BIT_COLOR1) COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR1][dst], prev->Attrib[VERT_ATTRIB_COLOR1][src] ); + + if (copy & VERT_BIT_FOG) COPY_4FV( next->Attrib[VERT_ATTRIB_FOG][dst], prev->Attrib[VERT_ATTRIB_FOG][src] ); - } + + + if (copy & VERT_BIT_INDEX) + next->Index[dst] = inputs->Index.data[isrc]; + + if (copy & VERT_BIT_EDGEFLAG) + next->EdgeFlag[dst] = prev->EdgeFlag[src]; + + if (copy & VERT_BIT_ELT) + next->Elt[dst] = prev->Elt[src]; + + if (copy & VERT_BIT_MATERIAL) + if (prev->Flag[src] & VERT_BIT_MATERIAL) + copy_material(next, prev, dst, src); next->Flag[dst] = flag; next->CopyOrFlag |= prev->Flag[src] & (VERT_BITS_FIXUP| @@ -589,6 +609,27 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) * attributes. */ +#if 0 + GLuint attr; + for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) { + if (fixup & (1 << attr)) { + if (attr == VERT_ATTRIB_COLOR0) { + /* special case, darn */ + if (IM->CopyOrFlag & VERT_BIT_COLOR0) + fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag, + VERT_BIT_COLOR0, start, + ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); + else + fixup &= ~VERT_BIT_COLOR0; + } + else { + fixup_first_4f(IM->Attrib[attr], IM->Flag, + 1 << attr, start, ctx->Current.Attrib[attr] ); + } + } + } + +#else if (fixup & VERT_BIT_NORMAL) { fixup_first_4f(IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag, VERT_BIT_NORMAL, start, @@ -623,6 +664,7 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i] ); } } +#endif if (fixup & VERT_BIT_EDGEFLAG) fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_BIT_EDGEFLAG, start, @@ -659,9 +701,6 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) - - - static void copy_none( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf) { (void) (start && ovf && tnl && count); @@ -805,9 +844,11 @@ _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ) } -void _tnl_upgrade_current_data( GLcontext *ctx, - GLuint required, - GLuint flags ) +/* + * Called via the VB->import_data function pointer. + */ +void +_tnl_upgrade_current_data( GLcontext *ctx, GLuint required, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; diff --git a/src/mesa/tnl/t_imm_fixup.h b/src/mesa/tnl/t_imm_fixup.h index 806933aa68a..7ffcb1ebc8e 100644 --- a/src/mesa/tnl/t_imm_fixup.h +++ b/src/mesa/tnl/t_imm_fixup.h @@ -1,10 +1,10 @@ -/* $Id: t_imm_fixup.h,v 1.6 2001/06/04 16:09:28 keithw Exp $ */ +/* $Id: t_imm_fixup.h,v 1.7 2003/03/31 18:19:57 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 5.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 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"), @@ -40,10 +40,10 @@ extern void _tnl_fixup_1f( GLfloat *data, GLuint flag[], extern void _tnl_fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match ); -extern void _tnl_fixup_3f( float data[][3], GLuint flag[], +extern void _tnl_fixup_3f( GLfloat data[][3], const GLuint flag[], GLuint start, GLuint match ); -extern void _tnl_fixup_4f( GLfloat data[][4], GLuint flag[], +extern void _tnl_fixup_4f( GLfloat data[][4], const GLuint flag[], GLuint start, GLuint match ); extern void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ); -- 2.30.2