diff options
Diffstat (limited to 'src/mesa/tnl/t_imm_fixup.c')
-rw-r--r-- | src/mesa/tnl/t_imm_fixup.c | 222 |
1 files changed, 123 insertions, 99 deletions
diff --git a/src/mesa/tnl/t_imm_fixup.c b/src/mesa/tnl/t_imm_fixup.c index 53e5dcbdc55..1c3cf2861c5 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.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)) { |