X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Ftnl%2Ft_imm_fixup.c;h=ce593343a9093fdd9e71d7fcc58d9caa62d0bdb8;hb=c34cb25bdd63766a26db771353d7a96c07f112a8;hp=530058528111e4bc5c1d90d254e1c096173c57b5;hpb=c6083e1dc47057b64179079715c5eac8f6010467;p=mesa.git diff --git a/src/mesa/tnl/t_imm_fixup.c b/src/mesa/tnl/t_imm_fixup.c index 53005852811..ce593343a90 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.16 2001/05/11 15:53:06 keithw Exp $ */ +/* $Id: t_imm_fixup.c,v 1.28 2001/12/03 17:47:04 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -50,6 +50,7 @@ #include "t_imm_debug.h" #include "t_imm_elt.h" #include "t_imm_fixup.h" +#include "t_imm_exec.h" #include "t_pipeline.h" @@ -74,8 +75,14 @@ _tnl_fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match ) { GLuint i = start; + for (;;) { if ((flag[++i] & match) == 0) { +/* fprintf(stderr, "_tnl_fixup_3f copy to %p values %f %f %f\n", */ +/* data[i], */ +/* data[i-1][0], */ +/* data[i-1][1], */ +/* data[i-1][2]); */ COPY_3V(data[i], data[i-1]); if (flag[i] & VERT_END_VB) break; } @@ -145,6 +152,9 @@ fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match, GLuint i = start-1; match |= VERT_END_VB; +/* fprintf(stderr, "fixup_first_3f default: %f %f %f start: %d\n", */ +/* dflt[0], dflt[1], dflt[2], start); */ + while ((flag[++i]&match) == 0) COPY_3FV(data[i], dflt); } @@ -184,13 +194,48 @@ fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match, data[i] = dflt; } +static void copy_from_current( GLcontext *ctx, struct immediate *IM, + GLuint start, GLuint copy ) +{ + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + _tnl_print_vert_flags("copy from current", copy); + + if (copy & VERT_NORM) { + COPY_3V( IM->Normal[start], ctx->Current.Normal ); + } + + if (copy & VERT_RGBA) { + COPY_4FV( IM->Color[start], ctx->Current.Color); + } + + if (copy & VERT_SPEC_RGB) + COPY_4FV( IM->SecondaryColor[start], ctx->Current.SecondaryColor); + + if (copy & VERT_FOG_COORD) + IM->FogCoord[start] = ctx->Current.FogCoord; + + if (copy & VERT_INDEX) + IM->Index[start] = ctx->Current.Index; + + if (copy & VERT_EDGE) + IM->EdgeFlag[start] = ctx->Current.EdgeFlag; + + if (copy & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (copy & VERT_TEX(i)) + COPY_4FV( IM->TexCoord[i][start], ctx->Current.Texcoord[i] ); + } + } +} + void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint start = IM->CopyStart; GLuint andflag = IM->CopyAndFlag; - GLuint orflag = IM->CopyOrFlag; + GLuint orflag = IM->CopyOrFlag | IM->Evaluated; GLuint fixup; IM->CopyTexSize = IM->TexSize; @@ -219,39 +264,8 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) /* Equivalent to a lazy copy-from-current when setting up the * immediate. */ - if (ctx->ExecuteFlag && copy) { - - if (MESA_VERBOSE&VERBOSE_IMMEDIATE) - _tnl_print_vert_flags("copy from current", copy); - - if (copy & VERT_NORM) { - COPY_3V( IM->Normal[start], ctx->Current.Normal ); - } - - if (copy & VERT_RGBA) { - COPY_4FV( IM->Color[start], ctx->Current.Color); - } - - if (copy & VERT_SPEC_RGB) - COPY_4FV( IM->SecondaryColor[start], ctx->Current.SecondaryColor); - - if (copy & VERT_FOG_COORD) - IM->FogCoord[start] = ctx->Current.FogCoord; - - if (copy & VERT_INDEX) - IM->Index[start] = ctx->Current.Index; - - if (copy & VERT_EDGE) - IM->EdgeFlag[start] = ctx->Current.EdgeFlag; - - if (copy & VERT_TEX_ANY) { - GLuint i; - for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { - if (copy & VERT_TEX(i)) - COPY_4FV( IM->TexCoord[i][start], ctx->Current.Texcoord[i] ); - } - } - } + if (ctx->ExecuteFlag && copy) + copy_from_current( ctx, IM, start, copy ); if (MESA_VERBOSE&VERBOSE_IMMEDIATE) _tnl_print_vert_flags("fixup", fixup); @@ -364,6 +378,18 @@ static void copy_material( struct immediate *next, MEMCPY(next->Material[dst], prev->Material[src], 2*sizeof(GLmaterial)); } +static GLboolean is_fan_like[GL_POLYGON+1] = { + GL_FALSE, + GL_FALSE, + GL_TRUE, /* line loop */ + GL_FALSE, + GL_FALSE, + GL_FALSE, + GL_TRUE, /* tri fan */ + GL_FALSE, + GL_FALSE, + GL_TRUE /* polygon */ +}; /* Copy the untransformed data from the shared vertices of a primitive @@ -405,15 +431,31 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) next->Elt[dst] = prev->Elt[src]; next->Flag[dst] = VERT_ELT; } +/* fprintf(stderr, "ADDING VERT_ELT!\n"); */ next->CopyOrFlag |= VERT_ELT; next->CopyAndFlag &= VERT_ELT; } else { - /* prev->CopyOrFlag is hacked to include values generated by eval: - */ - GLuint copy = tnl->pipeline.inputs & prev->CopyOrFlag; - + GLuint copy = tnl->pipeline.inputs & (prev->CopyOrFlag|prev->Evaluated); + GLuint flag; + + if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) { + flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_FIXUP); + next->CopyOrFlag |= flag; + } + else { + /* Don't let an early 'glColor', etc. poison the elt path. + */ + flag = ((prev->OrFlag|prev->Evaluated) & VERT_FIXUP); + } + next->TexSize |= tnl->ExecCopyTexSize; + next->CopyAndFlag &= flag; + + +/* _tnl_print_vert_flags("copy vertex components", copy); */ +/* _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */ +/* _tnl_print_vert_flags("flag", flag); */ /* Copy whole vertices */ @@ -430,8 +472,15 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) */ COPY_4FV( next->Obj[dst], inputs->Obj.data[isrc] ); - if (copy & VERT_NORM) + if (copy & VERT_NORM) { +/* fprintf(stderr, "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->Normal[dst], inputs->Normal.data[isrc] ); + } if (copy & VERT_RGBA) COPY_4FV( next->Color[dst], @@ -464,11 +513,11 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) next->FogCoord[dst] = prev->FogCoord[src]; } - next->Flag[dst] = (prev->CopyOrFlag & VERT_FIXUP); + next->Flag[dst] = flag; + next->CopyOrFlag |= prev->Flag[src] & (VERT_FIXUP| + VERT_MATERIAL| + VERT_OBJ); } - - next->CopyOrFlag |= (prev->CopyOrFlag & VERT_FIXUP); - next->CopyAndFlag &= (prev->CopyOrFlag & VERT_FIXUP); } if (--tnl->ExecCopySource->ref_count == 0) @@ -479,20 +528,21 @@ void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) } + /* Revive a compiled immediate struct - propogate new 'Current' * values. Often this is redundant because the current values were - * known and fixed up at compile time. + * known and fixed up at compile time (or in the first execution of + * the cassette). */ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint fixup; - GLuint count = IM->Count; GLuint start = IM->Start; - if (count == start) - return; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + IM->Evaluated = 0; IM->CopyOrFlag = IM->OrFlag; IM->CopyAndFlag = IM->AndFlag; IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize; @@ -507,12 +557,23 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) * display list. Need to translate them away: */ if (IM->CopyOrFlag & VERT_ELT) { + GLuint copy = tnl->pipeline.inputs & ~ctx->Array._Enabled; + GLuint i; + ASSERT(IM->CopyStart < IM->Start); + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start ); + + for (i = IM->CopyStart ; i < IM->Start ; i++) + copy_from_current( ctx, IM, i, copy ); + + _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->Start ); } fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_FIXUP; +/* _tnl_print_vert_flags("fixup compiled", fixup); */ + if (fixup) { if (fixup & VERT_TEX_ANY) { GLuint i; @@ -531,10 +592,13 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) fixup_first_1ui(IM->Index, IM->Flag, VERT_INDEX, start, ctx->Current.Index ); - if (fixup & VERT_RGBA) + if (fixup & VERT_RGBA) { if (IM->CopyOrFlag & VERT_RGBA) fixup_first_4f(IM->Color, IM->Flag, VERT_RGBA, start, ctx->Current.Color ); + else + fixup &= ~VERT_RGBA; + } if (fixup & VERT_SPEC_RGB) fixup_first_4f(IM->SecondaryColor, IM->Flag, VERT_SPEC_RGB, start, @@ -548,7 +612,10 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) fixup_first_3f(IM->Normal, IM->Flag, VERT_NORM, start, ctx->Current.Normal ); } + + IM->CopyOrFlag |= fixup; } + /* Materials: */ @@ -568,96 +635,6 @@ void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) } while (vulnerable); } - - /* Can potentially overwrite primitive details - need to save the - * first slot: - */ - tnl->DlistPrimitive = IM->Primitive[IM->Start]; - tnl->DlistPrimitiveLength = IM->PrimitiveLength[IM->Start]; - tnl->DlistLastPrimitive = IM->LastPrimitive; - - /* The first primitive may be different from what was recorded in - * the immediate struct. Consider an immediate that starts with a - * glBegin, compiled in a display list, which is called from within - * an existing Begin/End object. - */ - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - GLuint i; - - if (IM->BeginState & VERT_ERROR_1) - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd"); - - for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) - if (IM->Flag[i] & (VERT_BEGIN|VERT_END_VB)) - break; - - /* Would like to just ignore vertices upto this point. Can't - * set copystart because it might skip materials? - */ - ASSERT(IM->Start == IM->CopyStart); - if (i > IM->CopyStart) { - IM->Primitive[IM->CopyStart] = GL_POLYGON+1; - IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart; - if (IM->Flag[i] & VERT_END_VB) { - IM->Primitive[IM->CopyStart] |= PRIM_LAST; - IM->LastPrimitive = IM->CopyStart; - } - } - } else { - GLuint i; - - if (IM->BeginState & VERT_ERROR_0) - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd"); - - if (IM->CopyStart == IM->Start && - IM->Flag[IM->Start] & (VERT_END|VERT_END_VB)) - { - } - else - { - IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive; - if (tnl->ExecParity) - IM->Primitive[IM->CopyStart] |= PRIM_PARITY; - - /* one of these should be true, else we'll be in an infinite loop */ - assert(IM->PrimitiveLength[IM->Start] > 0 || - IM->Flag[IM->Start] & (VERT_END|VERT_END_VB)); - for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) - if (IM->Flag[i] & (VERT_END|VERT_END_VB)) { - IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart; - if (IM->Flag[i] & VERT_END_VB) { - IM->Primitive[IM->CopyStart] |= PRIM_LAST; - IM->LastPrimitive = IM->CopyStart; - } - if (IM->Flag[i] & VERT_END) { - IM->Primitive[IM->CopyStart] |= PRIM_END; - } - break; - } - } - } - - if (IM->Primitive[IM->LastPrimitive] & PRIM_END) - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - 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]); */ -} - - -/* Undo any changes potentially made to the immediate in the range - * IM->Start..IM->Count above. - */ -void _tnl_restore_compiled_cassette( GLcontext *ctx, struct immediate *IM ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - IM->Primitive[IM->Start] = tnl->DlistPrimitive; - IM->PrimitiveLength[IM->Start] = tnl->DlistPrimitiveLength; } @@ -758,7 +735,12 @@ _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ) tnl->ExecCopySource = IM; tnl->ExecCopyCount = 0; tnl->ExecCopyTexSize = IM->CopyTexSize; - tnl->ExecParity = IM->PrimitiveLength[IM->LastPrimitive] & 1; + + if (IM->LastPrimitive != IM->CopyStart) + tnl->ExecParity = 0; + + tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1; + if (pincr != 1 && (IM->Count - last - pintro)) ovf = (IM->Count - last - pintro) % pincr; @@ -784,7 +766,10 @@ _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ) GLuint ovf = 0, i; tnl->ExecCopyCount = 0; - tnl->ExecParity = IM->PrimitiveLength[last] & 1; + if (IM->LastPrimitive != IM->CopyStart) + tnl->ExecParity = 0; + + tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1; if (pincr != 1 && (IM->Count - last - pintro)) ovf = (IM->Count - last - pintro) % pincr; @@ -803,8 +788,8 @@ void _tnl_upgrade_current_data( GLcontext *ctx, GLuint flags ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct immediate *IM = TNL_CURRENT_IM(ctx); /* hmmm */ struct vertex_buffer *VB = &tnl->vb; + struct immediate *IM = (struct immediate *)VB->import_source; ASSERT(IM); @@ -819,6 +804,11 @@ void _tnl_upgrade_current_data( GLcontext *ctx, tmp->Flags = 0; COPY_4FV( IM->Color[start], ctx->Current.Color); + + /* + ASSERT(IM->Flag[IM->LastData+1] & VERT_END_VB); + */ + fixup_first_4f( IM->Color, IM->Flag, VERT_END_VB, start, IM->Color[start] );