diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2003-10-13 18:01:05 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2003-10-13 18:01:05 +0000 |
commit | 79a49e30a19af701b75e3d1ec0e64628f4607eed (patch) | |
tree | 2fa451b644d95a73290df33140776982679abe1c | |
parent | f1582dbe52460b03320862aa6d71ba3c6a89da5b (diff) |
Fix several more display list glitches.
Get 'loopback' replay of display lists working.
-rw-r--r-- | src/mesa/tnl/t_save_api.c | 130 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_loopback.c | 45 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_playback.c | 83 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_light.c | 2 |
4 files changed, 163 insertions, 97 deletions
diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c index 56b26ac3aa..643645f211 100644 --- a/src/mesa/tnl/t_save_api.c +++ b/src/mesa/tnl/t_save_api.c @@ -68,8 +68,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "dlist.h" #include "context.h" +#include "dlist.h" +#include "enums.h" #include "macros.h" #include "api_validate.h" #include "api_arrayelt.h" @@ -89,10 +90,12 @@ static GLuint _save_copy_vertices( GLcontext *ctx, GLuint sz = tnl->save.vertex_size; GLfloat *src = node->buffer + prim->start * sz; GLfloat *dst = tnl->save.copied.buffer; - GLenum mode = prim->mode & PRIM_MODE_MASK; GLuint ovf, i; - switch( mode ) + if (prim->mode & PRIM_END) + return 0; + + switch( prim->mode & PRIM_MODE_MASK ) { case GL_POINTS: return 0; @@ -197,11 +200,6 @@ static void _save_compile_vertex_list( GLcontext *ctx ) TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_vertex_list *node; - if (tnl->save.initial_counter == tnl->save.counter) { - _save_reset_counters( ctx ); - return; - } - /* Allocate space for this structure in the display list currently * being compiled. */ @@ -226,6 +224,9 @@ static void _save_compile_vertex_list( GLcontext *ctx ) node->vertex_store->refcount++; node->prim_store->refcount++; + + assert(node->attrsz[_TNL_ATTRIB_POS] != 0); + tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; tnl->save.prim_store->used += node->prim_count; @@ -298,13 +299,6 @@ static void _save_wrap_buffers( GLcontext *ctx ) /* Called only when buffers are wrapped as the result of filling the * vertex_store struct. - * - * -- what about when be wraps? - * -- Don't need to copy vertices or emit fake begin/ends - * -- Just call _save_compile_vertex_list() - * -- what about vertex upgrades? - * -- Same logic, but want to do more before emitting vertices in new - * format. */ static void _save_wrap_filled_vertex( GLcontext *ctx ) { @@ -392,8 +386,8 @@ static void _save_upgrade_vertex( GLcontext *ctx, /* Store the current run of vertices, and emit a GL_END. Emit a * BEGIN in the new buffer. */ - _save_wrap_buffers( ctx ); - + if (tnl->save.initial_counter != tnl->save.counter) + _save_wrap_buffers( ctx ); /* Do a COPY_TO_CURRENT to ensure back-copying works for the case * when the attribute already exists in the vertex and is having @@ -401,7 +395,6 @@ static void _save_upgrade_vertex( GLcontext *ctx, */ _save_copy_to_current( ctx ); - /* Fix up sizes: */ oldsz = tnl->save.attrsz[attr]; @@ -1103,17 +1096,21 @@ static void _save_CallList( GLuint l ) static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - int i = tnl->save.prim_count++; - assert(i < tnl->save.prim_max); - tnl->save.prim[i].mode = mode | PRIM_BEGIN; - tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; - tnl->save.prim[i].count = 0; + if (1) { + int i = tnl->save.prim_count++; - _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); + assert(i < tnl->save.prim_max); + tnl->save.prim[i].mode = mode | PRIM_BEGIN; + tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; + tnl->save.prim[i].count = 0; - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; + _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); + ctx->Driver.SaveNeedFlush = 1; + return GL_TRUE; + } + else + return GL_FALSE; } @@ -1277,11 +1274,34 @@ static void _save_vtxfmt_init( GLcontext *ctx ) } +void _tnl_SaveFlushVertices( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLint i; + + /* Noop when we are actually active: + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || + ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) + return; + + if (tnl->save.initial_counter != tnl->save.counter || + tnl->save.prim_count) + _save_compile_vertex_list( ctx ); + + save_init_attrfv( tnl ); + + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + tnl->save.attrsz[i] = 0; + + tnl->save.vertex_size = 0; + ctx->Driver.SaveNeedFlush = 0; +} void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - assert(tnl->save.vertex_size == 0); + GLuint i; if (!tnl->save.prim_store) tnl->save.prim_store = alloc_prim_store( ctx ); @@ -1291,6 +1311,14 @@ void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) tnl->save.vbptr = tnl->save.vertex_store->buffer; } + save_init_attrfv( tnl ); + + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + tnl->save.attrsz[i] = 0; + + tnl->save.vertex_size = 0; + ctx->Driver.SaveNeedFlush = 0; + _save_reset_counters( ctx ); } @@ -1308,28 +1336,6 @@ void _tnl_EndCallList( GLcontext *ctx ) { } -/* Called when - */ -void _tnl_SaveFlushVertices( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - _save_compile_vertex_list( ctx ); - - save_init_attrfv( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->save.attrsz[i] = 0; - - tnl->save.vertex_size = 0; - - ctx->Driver.SaveNeedFlush = 0; -} static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) { @@ -1346,10 +1352,23 @@ static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) static void _tnl_print_vertex_list( GLcontext *ctx, void *data ) { struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; + GLuint i; - _mesa_debug(ctx, "TNL-VERTEX-LIST, %u vertices %d primitives\n", + _mesa_debug(0, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", node->count, - node->prim_count); + node->prim_count, + node->vertex_size); + + for (i = 0 ; i < node->prim_count ; i++) { + struct tnl_prim *prim = &node->prim[i]; + _mesa_debug(0, " prim %d: %s %d..%d %s %s\n", + i, + _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK), + prim->start, + prim->start + prim->count, + (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)", + (prim->mode & PRIM_END) ? "END" : "(wrap)"); + } } @@ -1383,14 +1402,6 @@ void _tnl_save_init( GLcontext *ctx ) struct tnl_vertex_arrays *tmp = &tnl->save_inputs; GLuint i; - save_init_attrfv( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->save.attrsz[i] = 0; - - tnl->save.vertex_size = 0; - - _save_vtxfmt_init( ctx ); for (i = 0; i < _TNL_ATTRIB_MAX; i++) _mesa_vector4f_init( &tmp->Attribs[i], 0, 0); @@ -1404,6 +1415,7 @@ void _tnl_save_init( GLcontext *ctx ) ctx->Driver.NotifySaveBegin = _save_NotifyBegin; + _save_vtxfmt_init( ctx ); _save_current_init( ctx ); } diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c index 26fa9ccdfd..351a60bb70 100644 --- a/src/mesa/tnl/t_save_loopback.c +++ b/src/mesa/tnl/t_save_loopback.c @@ -28,6 +28,7 @@ */ #include "context.h" +#include "enums.h" #include "glapi.h" #include "imports.h" #include "macros.h" @@ -175,10 +176,10 @@ struct loopback_attr { void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list ) { - struct loopback_attr la[32]; + struct loopback_attr la[_TNL_ATTRIB_MAX]; GLuint i, nr = 0; - for (i = 1 ; i <= _TNL_ATTRIB_TEX7 ; i++) { + for (i = 0 ; i <= _TNL_ATTRIB_TEX7 ; i++) { if (list->attrsz[i]) { la[nr].target = i; la[nr].sz = list->attrsz[i]; @@ -212,32 +213,20 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list ) nr++; } - /* Must be last - */ - if (list->attrsz[_TNL_ATTRIB_POS]) { - la[nr].target = _TNL_ATTRIB_POS; - la[nr].sz = list->attrsz[_TNL_ATTRIB_POS]; - la[nr].func = vert_attrfunc[list->attrsz[0]-1]; - nr++; - } - else { - fprintf(stderr, "No pos attrib???\n"); - return; - } - /* Don't emit ends and begins on wrapped primitives. Don't replay * wrapped vertices. If we get here, it's probably because the the * precalculated wrapping is wrong. */ for (i = 0 ; i < list->prim_count ; i++) { - GLint begin = list->prim[i].start; - GLint end = begin + list->prim[i].count; + struct tnl_prim *prim = &list->prim[i]; + GLint begin = prim->start; + GLint end = begin + prim->count; GLfloat *data; GLint j, k; - if (list->prim[i].mode & PRIM_BEGIN) - glBegin( list->prim[i].mode & PRIM_MODE_MASK ); - else { + if (prim->mode & PRIM_BEGIN) { + glBegin( prim->mode & PRIM_MODE_MASK ); + } else { assert(i == 0); assert(begin == 0); begin += list->wrap_count; @@ -246,14 +235,22 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list ) data = list->buffer + begin * list->vertex_size; for (j = begin ; j < end ; j++) { - for (k = 0 ; k < nr ; k++) { - la[k].func( la[k].target, data ); - data += la[k].sz; + GLfloat *tmp = data + la[0].sz; + + for (k = 1 ; k < nr ; k++) { + la[k].func( la[k].target, tmp ); + tmp += la[k].sz; } + + /* Fire the vertex + */ + la[0].func( VERT_ATTRIB_POS, data ); + data = tmp; } - if (list->prim[i].mode & PRIM_END) + if (prim->mode & PRIM_END) { glEnd(); + } else { assert (i == list->prim_count-1); } diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c index f62057249c..4928e33dde 100644 --- a/src/mesa/tnl/t_save_playback.c +++ b/src/mesa/tnl/t_save_playback.c @@ -30,6 +30,8 @@ #include "context.h" #include "imports.h" #include "mtypes.h" +#include "macros.h" +#include "light.h" #include "state.h" #include "t_pipeline.h" #include "t_save_api.h" @@ -114,6 +116,49 @@ static void _tnl_bind_vertex_list( GLcontext *ctx, } } +static void _playback_copy_to_current( GLcontext *ctx, + struct tnl_vertex_list *node ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLfloat *data; + GLuint i; + + if (node->count) + data = node->buffer + (node->count-1) * node->vertex_size; + else + data = node->buffer; + + for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) { + if (node->attrsz[i]) { + ASSIGN_4V(tnl->vtx.current[i], 0, 0, 0, 1); + COPY_SZ_4V(tnl->vtx.current[i], node->attrsz[i], data); + data += node->attrsz[i]; + } + } + + /* Edgeflag requires special treatment: + */ + if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) { + ctx->Current.EdgeFlag = (data[0] == 1.0); + } + + /* Colormaterial -- this kindof sucks. + */ + if (ctx->Light.ColorMaterialEnabled) { + _mesa_update_color_material( ctx, + ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); + } + + /* CurrentExecPrimitive + */ + if (node->prim_count) { + GLenum mode = node->prim[node->prim_count - 1].mode; + if (mode & PRIM_END) + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + else + ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK); + } +} /** @@ -126,25 +171,39 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) FLUSH_CURRENT(ctx, 0); - if (!node->prim_count || !node->count) - return; + if (node->prim_count) { - if (ctx->NewState) - _mesa_update_state( ctx ); + /* Degenerate case: list is called inside begin/end pair. + */ + if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && + (node->prim[0].mode & PRIM_BEGIN)) { + _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin"); + _tnl_loopback_vertex_list( ctx, data ); + return; + } + else if (1) { + _tnl_loopback_vertex_list( ctx, data ); + return; + } + + if (ctx->NewState) + _mesa_update_state( ctx ); - if (tnl->pipeline.build_state_changes) - _tnl_validate_pipeline( ctx ); + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); - _tnl_bind_vertex_list( ctx, node ); + _tnl_bind_vertex_list( ctx, node ); - /* Invalidate all stored data before and after run: - */ - tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; - tnl->Driver.RunPipeline( ctx ); - tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; + /* Invalidate all stored data before and after run: + */ + tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; + tnl->Driver.RunPipeline( ctx ); + tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; + } /* Copy to current? */ + _playback_copy_to_current( ctx, node ); } diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c index a42147c803..ae1cc6231c 100644 --- a/src/mesa/tnl/t_vb_light.c +++ b/src/mesa/tnl/t_vb_light.c @@ -173,8 +173,6 @@ static GLboolean run_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr; GLuint idx; -/* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */ - /* Make sure we can talk about position x,y and z: * * FIXME! |