-/* $Id: t_imm_fixup.c,v 1.19 2001/05/16 09:28:32 keithw Exp $ */
+/* $Id: t_imm_fixup.c,v 1.28 2001/12/03 17:47:04 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "t_imm_debug.h"
#include "t_imm_elt.h"
#include "t_imm_fixup.h"
+#include "t_imm_exec.h"
#include "t_pipeline.h"
{
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;
}
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);
}
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;
/* 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);
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]) {
- next->TexSize |= tnl->ExecCopyTexSize;
- next->CopyOrFlag |= (prev->CopyOrFlag & VERT_FIXUP);
- next->CopyAndFlag &= (prev->CopyOrFlag & VERT_FIXUP);
- flag = (prev->CopyOrFlag & VERT_FIXUP);
+ flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_FIXUP);
+ next->CopyOrFlag |= flag;
}
else {
/* Don't let an early 'glColor', etc. poison the elt path.
*/
- next->CopyAndFlag &= (prev->OrFlag & VERT_FIXUP);
- flag = (prev->OrFlag & VERT_FIXUP);
+ 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
*/
for (i = 0 ; i < count ; i++)
*/
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],
}
next->Flag[dst] = flag;
- next->OrFlag |= prev->Flag[src]; /* for non-fanlike prims,
- otherwise redundant */
+ next->CopyOrFlag |= prev->Flag[src] & (VERT_FIXUP|
+ VERT_MATERIAL|
+ VERT_OBJ);
}
}
}
+
/* 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;
* 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;
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,
fixup_first_3f(IM->Normal, IM->Flag, VERT_NORM, start,
ctx->Current.Normal );
}
+
+ IM->CopyOrFlag |= fixup;
}
+
/* Materials:
*/
} 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;
-}
-
-
-/* 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;
}
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;
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;
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] );