From 701208d25937ac629dd146560fc0861eaac755cb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Nov 2003 11:42:50 +0000 Subject: Add CallLists() to vtxfmt. Restore old NormalLength optimization for display lists. Add some heuristics to t_vtx_api.c to prevent bloated vertices and excessive flushing (hopefully). --- src/mesa/tnl/t_context.h | 11 +++-- src/mesa/tnl/t_save_api.c | 58 ++++++++++++++++++++--- src/mesa/tnl/t_save_playback.c | 7 +-- src/mesa/tnl/t_vb_lighttmp.h | 4 +- src/mesa/tnl/t_vtx_api.c | 104 ++++++++++++++++++++++++++++++----------- src/mesa/tnl/t_vtx_exec.c | 9 +++- 6 files changed, 149 insertions(+), 44 deletions(-) diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index 112d8edb72..9d806da81f 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -231,7 +231,7 @@ struct tnl_copied_vtx { GLuint nr; }; -#define VERT_BUFFER_SIZE 2048 +#define VERT_BUFFER_SIZE 2048 /* 8kbytes */ typedef void (*attrfv_func)( const GLfloat * ); @@ -285,6 +285,7 @@ struct tnl_vertex_list { GLuint dangling_attr_ref; /* current attr implicitly referenced outside the list */ + GLfloat *normal_lengths; struct tnl_prim *prim; GLuint prim_count; @@ -292,7 +293,9 @@ struct tnl_vertex_list { struct tnl_primitive_store *prim_store; }; -/* These buffers should be a reasonable size: +/* These buffers should be a reasonable size to support upload to + * hardware? Maybe drivers should stitch them back together, or + * specify a desired size? */ #define SAVE_BUFFER_SIZE (16*1024) #define SAVE_PRIM_SIZE 128 @@ -377,11 +380,11 @@ struct vertex_buffer { /* Constant over life of the vertex_buffer. */ - GLuint Size; + GLuint Size; /* Constant over the pipeline. */ - GLuint Count; /* for everything except Elts */ + GLuint Count; /* for everything except Elts */ /* Pointers to current data. */ diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c index d17b41d009..63a59e77d1 100644 --- a/src/mesa/tnl/t_save_api.c +++ b/src/mesa/tnl/t_save_api.c @@ -151,9 +151,33 @@ static GLuint _save_copy_vertices( GLcontext *ctx, } +static void +build_normal_lengths( struct tnl_vertex_list *node ) +{ + GLuint i; + GLfloat *len; + GLfloat *n = node->buffer; + GLuint stride = node->vertex_size; + GLuint count = node->count; + + len = node->normal_lengths = MALLOC( count * sizeof(GLfloat) ); + if (!len) + return; + + /* Find the normal of the first vertex: + */ + for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++) + n += node->attrsz[i]; + + for (i = 0 ; i < count ; i++, n += stride) { + len[i] = LEN_3FV( n ); + if (len[i] > 0.0F) len[i] = 1.0F / len[i]; + } +} + static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) { - struct tnl_vertex_store *store = ALIGN_MALLOC( sizeof(*store), 32 ); + struct tnl_vertex_store *store = MALLOC( sizeof(*store) ); store->used = 0; store->refcount = 1; return store; @@ -161,7 +185,7 @@ static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx ) { - struct tnl_primitive_store *store = ALIGN_MALLOC( sizeof(*store), 32 ); + struct tnl_primitive_store *store = MALLOC( sizeof(*store) ); store->used = 0; store->refcount = 1; return store; @@ -222,13 +246,20 @@ static void _save_compile_vertex_list( GLcontext *ctx ) node->vertex_store = tnl->save.vertex_store; node->prim_store = tnl->save.prim_store; node->dangling_attr_ref = tnl->save.dangling_attr_ref; + node->normal_lengths = 0; node->vertex_store->refcount++; node->prim_store->refcount++; - assert(node->attrsz[_TNL_ATTRIB_POS] != 0); + /* Maybe calculate normal lengths: + */ + if (tnl->CalcDListNormalLengths && + node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && + !node->dangling_attr_ref) + build_normal_lengths( node ); + tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; tnl->save.prim_store->used += node->prim_count; @@ -279,6 +310,8 @@ static void _save_wrap_buffers( GLcontext *ctx ) assert(i < tnl->save.prim_max); assert(i >= 0); + /* Close off in-progress primitive. + */ tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - tnl->save.prim[i].start); mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END); @@ -1118,10 +1151,20 @@ static void _save_EvalPoint2( GLint i, GLint j ) static void _save_CallList( GLuint l ) { GET_CURRENT_CONTEXT(ctx); + fprintf(stderr, "%s\n", __FUNCTION__); FALLBACK(ctx); ctx->Save->CallList( l ); } +static void _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) +{ + GET_CURRENT_CONTEXT(ctx); + fprintf(stderr, "%s\n", __FUNCTION__); + FALLBACK(ctx); + ctx->Save->CallLists( n, type, v ); +} + + /* This begin is hooked into ... Updating of @@ -1311,7 +1354,6 @@ static void _save_vtxfmt_init( GLcontext *ctx ) vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ vfmt->Begin = _save_Begin; - vfmt->CallList = _mesa_CallList; vfmt->Color3f = _save_Color3f; vfmt->Color3fv = _save_Color3fv; vfmt->Color4f = _save_Color4f; @@ -1362,6 +1404,7 @@ static void _save_vtxfmt_init( GLcontext *ctx ) /* This will all require us to fallback to saving the list as opcodes: */ vfmt->CallList = _save_CallList; /* inside begin/end */ + vfmt->CallLists = _save_CallLists; /* inside begin/end */ vfmt->EvalCoord1f = _save_EvalCoord1f; vfmt->EvalCoord1fv = _save_EvalCoord1fv; vfmt->EvalCoord2f = _save_EvalCoord2f; @@ -1438,10 +1481,13 @@ static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; if ( --node->vertex_store->refcount == 0 ) - ALIGN_FREE( node->vertex_store ); + FREE( node->vertex_store ); if ( --node->prim_store->refcount == 0 ) - ALIGN_FREE( node->prim_store ); + FREE( node->prim_store ); + + if ( node->normal_lengths ) + FREE( node->normal_lengths ); } diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c index 78e6c66159..52011996b0 100644 --- a/src/mesa/tnl/t_save_playback.c +++ b/src/mesa/tnl/t_save_playback.c @@ -64,7 +64,7 @@ static void _tnl_bind_vertex_list( GLcontext *ctx, VB->Primitive = node->prim; VB->PrimitiveCount = node->prim_count; VB->Elts = NULL; - VB->NormalLengthPtr = NULL; + VB->NormalLengthPtr = node->normal_lengths; for (attr = 0; attr <= _TNL_ATTRIB_INDEX; attr++) { if (node->attrsz[attr]) { @@ -173,7 +173,7 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) if (node->prim_count) { if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && - (node->prim[0].mode & PRIM_BEGIN)) { + (node->prim[0].mode & PRIM_BEGIN)) { /* Degenerate case: list is called inside begin/end pair and * includes operations such as glBegin or glDrawArrays. @@ -182,7 +182,8 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) _tnl_loopback_vertex_list( ctx, data ); return; } - else if (node->dangling_attr_ref) { + else if (tnl->LoopbackDListCassettes || + node->dangling_attr_ref) { /* Degenerate case: list references current data and would * require fixup. Take the easier option & loop it back. */ diff --git a/src/mesa/tnl/t_vb_lighttmp.h b/src/mesa/tnl/t_vb_lighttmp.h index eaca5552d7..167325eae8 100644 --- a/src/mesa/tnl/t_vb_lighttmp.h +++ b/src/mesa/tnl/t_vb_lighttmp.h @@ -37,7 +37,7 @@ /* define TRACE to trace lighting code */ -/* #define TRACE 1 */ +/* #define TRACE 1 */ /* * ctx is the current context @@ -532,7 +532,7 @@ static void TAG(light_fast_rgba)( GLcontext *ctx, const struct gl_light *light; #ifdef TRACE - fprintf(stderr, "%s\n", __FUNCTION__ ); + fprintf(stderr, "%s %d\n", __FUNCTION__, nr ); #endif (void) input; diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c index 894744f349..21ec1c9a7b 100644 --- a/src/mesa/tnl/t_vtx_api.c +++ b/src/mesa/tnl/t_vtx_api.c @@ -42,6 +42,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "t_vtx_api.h" +static void init_attrfv( TNLcontext *tnl ); + + /* Close off the last primitive, execute the buffer, restart the * primitive. */ @@ -166,6 +169,7 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, GLuint oldsz; GLint i; GLfloat *tmp; + GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter; /* Run pipeline on current vertices, copy wrapped vertices @@ -179,6 +183,20 @@ static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, */ _tnl_copy_to_current( ctx ); + + /* Heuristic: Attempt to isolate attributes received outside + * begin/end so that they don't bloat the vertices. + */ +#if 1 + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && + tnl->vtx.attrsz[attr] == 0 + && lastcount > 8 + ) { + init_attrfv( tnl ); + } +#endif + + /* Fix up sizes: */ oldsz = tnl->vtx.attrsz[attr]; @@ -407,29 +425,33 @@ ATTRS( 15 ) static void init_attrfv( TNLcontext *tnl ) { - GLuint i; - - init_0( tnl ); - init_1( tnl ); - init_2( tnl ); - init_3( tnl ); - init_4( tnl ); - init_5( tnl ); - init_6( tnl ); - init_7( tnl ); - init_8( tnl ); - init_9( tnl ); - init_10( tnl ); - init_11( tnl ); - init_12( tnl ); - init_13( tnl ); - init_14( tnl ); - init_15( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->vtx.attrsz[i] = 0; - - tnl->vtx.vertex_size = 0; + if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, tnl->vtx.vertex_size); + + if (tnl->vtx.vertex_size) { + GLuint i; + + init_0( tnl ); + init_1( tnl ); + init_2( tnl ); + init_3( tnl ); + init_4( tnl ); + init_5( tnl ); + init_6( tnl ); + init_7( tnl ); + init_8( tnl ); + init_9( tnl ); + init_10( tnl ); + init_11( tnl ); + init_12( tnl ); + init_13( tnl ); + init_14( tnl ); + init_15( tnl ); + + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + tnl->vtx.attrsz[i] = 0; + + tnl->vtx.vertex_size = 0; + } } /* These can be made efficient with codegen. Further, by adding more @@ -952,6 +974,14 @@ static void _tnl_Begin( GLenum mode ) return; } +#if 1 + /* Heuristic: attempt to isolate attributes occuring outside + * begin/end pairs. + */ + if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) + _tnl_FlushVertices( ctx, ~0 ); +#endif + i = tnl->vtx.prim_count++; tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; @@ -978,8 +1008,19 @@ static void _tnl_End( void ) ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - if (tnl->vtx.prim_count == TNL_MAX_PRIM) +#if 0 + if (tnl->vtx.counter * 2 > tnl->vtx.initial_counter) + _tnl_FlushVertices( ctx, ~0 ); +#endif + + if (tnl->vtx.prim_count == TNL_MAX_PRIM) { +#if 0 + _tnl_FlushVertices( ctx, ~0 ); +#else _tnl_flush_vtx( ctx ); +#endif + } + } else _mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ ); @@ -992,6 +1033,7 @@ static void _tnl_exec_vtxfmt_init( GLcontext *ctx ) vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ vfmt->Begin = _tnl_Begin; vfmt->CallList = _mesa_CallList; + vfmt->CallLists = _mesa_CallLists; vfmt->Color3f = _tnl_Color3f; vfmt->Color3fv = _tnl_Color3fv; vfmt->Color4f = _tnl_Color4f; @@ -1061,18 +1103,24 @@ void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) if (tnl->vtx.counter != tnl->vtx.initial_counter) { _tnl_flush_vtx( ctx ); - init_0( tnl ); +#if 0 + init_0(tnl); +#endif } - if (flags & FLUSH_UPDATE_CURRENT) { +#if 0 + if (flags & FLUSH_UPDATE_CURRENT) +#endif + { _tnl_copy_to_current( ctx ); /* reset attrfv table */ init_attrfv( tnl ); + flags |= FLUSH_UPDATE_CURRENT; } - ctx->Driver.NeedFlush &= ~flags; + ctx->Driver.NeedFlush = 0; } static void _tnl_current_init( GLcontext *ctx ) @@ -1106,7 +1154,7 @@ void _tnl_vtx_init( GLcontext *ctx ) _tnl_exec_vtxfmt_init( ctx ); _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - init_attrfv( tnl ); + tnl->vtx.vertex_size = 1; init_attrfv( tnl ); } diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c index 376e580e3e..b72f10c36a 100644 --- a/src/mesa/tnl/t_vtx_exec.c +++ b/src/mesa/tnl/t_vtx_exec.c @@ -77,7 +77,7 @@ static GLint get_size( const GLfloat *f ) /* Some nasty stuff still hanging on here. * - * TODO - remove VB->ColorPtr, etc and just use the AttrPtr's. + * TODO - remove VB->NormalPtr, etc and just use the AttrPtr's. */ static void _tnl_vb_bind_vtx( GLcontext *ctx ) { @@ -88,6 +88,10 @@ static void _tnl_vb_bind_vtx( GLcontext *ctx ) GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter; GLuint attr, i; + fprintf(stderr, "%s: %d verts %d vertsize\n", + __FUNCTION__, count, tnl->vtx.vertex_size); + + /* Setup constant data in the VB. */ VB->Count = count; @@ -137,8 +141,11 @@ static void _tnl_vb_bind_vtx( GLcontext *ctx ) VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0]; + VB->ColorPtr[1] = 0; VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX]; + VB->IndexPtr[1] = 0; VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1]; + VB->SecondaryColorPtr[1] = 0; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; -- cgit v1.2.3