summaryrefslogtreecommitdiffstats
path: root/src/mesa/tnl/t_imm_fixup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl/t_imm_fixup.c')
-rw-r--r--src/mesa/tnl/t_imm_fixup.c222
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)) {