summaryrefslogtreecommitdiff
path: root/src/mesa/tnl/t_imm_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl/t_imm_exec.c')
-rw-r--r--src/mesa/tnl/t_imm_exec.c142
1 files changed, 76 insertions, 66 deletions
diff --git a/src/mesa/tnl/t_imm_exec.c b/src/mesa/tnl/t_imm_exec.c
index 18eaa488a3..4ee77b773f 100644
--- a/src/mesa/tnl/t_imm_exec.c
+++ b/src/mesa/tnl/t_imm_exec.c
@@ -1,4 +1,4 @@
-/* $Id: t_imm_exec.c,v 1.18 2001/04/28 08:39:18 keithw Exp $ */
+/* $Id: t_imm_exec.c,v 1.19 2001/04/30 21:08:52 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -57,13 +57,12 @@
-/* Called to initialize new buffers, and to recycle old ones.
- */
void _tnl_reset_input( GLcontext *ctx,
GLuint start,
GLuint beginstate,
GLuint savedbeginstate )
{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
struct immediate *IM = TNL_CURRENT_IM(ctx);
/* Clear the dirty part of the flag array.
@@ -71,9 +70,19 @@ void _tnl_reset_input( GLcontext *ctx,
if (start < IM->Count+2)
MEMSET(IM->Flag + start, 0, sizeof(GLuint) * (IM->Count+2-start));
- IM->CopyStart = IM->Start = IM->Count = start;
- IM->Primitive[IM->Start] = (ctx->Driver.CurrentExecPrimitive | PRIM_LAST);
- IM->LastPrimitive = IM->Start;
+ IM->Start = IM->Count = start;
+ IM->CopyStart = IM->Start - tnl->ExecCopyCount;
+ IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive;
+ if (tnl->ExecParity)
+ IM->Primitive[IM->CopyStart] |= PRIM_PARITY;
+
+ if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
+ ASSERT(tnl->ExecCopyTexSize == 0);
+ ASSERT(tnl->ExecCopyCount == 0);
+ ASSERT(IM->CopyStart == IM->Start);
+ }
+
+ IM->LastPrimitive = IM->CopyStart;
IM->BeginState = beginstate;
IM->SavedBeginState = savedbeginstate;
IM->TexSize = 0;
@@ -83,7 +92,6 @@ void _tnl_reset_input( GLcontext *ctx,
if (IM->MaterialMask)
IM->MaterialMask[IM->Start] = 0;
-
IM->ArrayEltFlags = ~ctx->Array._Enabled;
IM->ArrayEltIncr = ctx->Array.Vertex.Enabled ? 1 : 0;
IM->ArrayEltFlush = !ctx->Array.LockCount;
@@ -91,6 +99,7 @@ void _tnl_reset_input( GLcontext *ctx,
+
void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM,
GLuint flag )
{
@@ -317,16 +326,13 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
VB->MaterialMask = IM->MaterialMask + start;
VB->Material = IM->Material + start;
}
-
-/* _tnl_print_vert_flags("_tnl_vb_bind_immediate: importable", */
-/* VB->importable_data); */
-
}
-/* Called by exec_cassette and execute_compiled_cassette.
+/* Called by exec_cassette execute_compiled_cassette, but not
+ * exec_elt_cassette.
*/
void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM )
{
@@ -335,11 +341,7 @@ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM )
_tnl_vb_bind_immediate( ctx, IM );
if (IM->CopyOrFlag & VERT_EVAL_ANY)
- _tnl_eval_vb( ctx,
- IM->Obj + IM->CopyStart,
- IM->CopyOrFlag,
- IM->CopyAndFlag );
-
+ _tnl_eval_immediate( ctx, IM );
/* Invalidate all stored data before and after run:
*/
@@ -350,7 +352,32 @@ void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM )
_tnl_copy_to_current( ctx, IM, IM->OrFlag );
}
+/* Called for regular vertex cassettes.
+ */
+static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM )
+{
+ if (IM->OrFlag & VERT_ELT) {
+ GLuint andflag = ~0;
+ GLuint i;
+ GLuint start = IM->FlushElt ? IM->LastPrimitive : IM->CopyStart;
+ _tnl_translate_array_elts( ctx, IM, start, IM->Count );
+
+ /* Need to recompute andflag and orflag for fixup.
+ */
+ if (IM->CopyAndFlag & VERT_ELT)
+ IM->CopyAndFlag |= ctx->Array._Enabled;
+ else {
+ for (i = IM->CopyStart ; i < IM->Count ; i++)
+ andflag &= IM->Flag[i];
+ IM->CopyAndFlag = andflag;
+ }
+ IM->CopyOrFlag |= ctx->Array._Enabled;
+ }
+ _tnl_fixup_input( ctx, IM );
+ _tnl_print_cassette( IM );
+ _tnl_run_cassette( ctx, IM );
+}
/* Called for pure, locked VERT_ELT cassettes instead of
@@ -363,6 +390,8 @@ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM )
_tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount );
+ /* Take only elements and primitive information from the immediate:
+ */
VB->Elts = IM->Elt + IM->CopyStart;
VB->Primitive = IM->Primitive + IM->CopyStart;
VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart;
@@ -382,31 +411,13 @@ static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM )
}
-
-/* Called for regular vertex cassettes.
- */
-static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM )
+static void
+exec_empty_cassette( GLcontext *ctx, struct immediate *IM )
{
- if (IM->OrFlag & VERT_ELT) {
- GLuint andflag = ~0;
- GLuint i;
- GLuint start = IM->FlushElt ? IM->LastPrimitive : IM->CopyStart;
- _tnl_translate_array_elts( ctx, IM, start, IM->Count );
-
- /* Need to recompute andflag.
- */
- if (IM->CopyAndFlag & VERT_ELT)
- IM->CopyAndFlag |= ctx->Array._Enabled;
- else {
- for (i = IM->CopyStart ; i < IM->Count ; i++)
- andflag &= IM->Flag[i];
- IM->CopyAndFlag = andflag;
- }
- }
+ if (IM->OrFlag & VERT_ELT)
+ _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart );
- _tnl_fixup_input( ctx, IM );
-/* _tnl_print_cassette( IM ); */
- _tnl_run_cassette( ctx, IM );
+ _tnl_copy_to_current( ctx, IM, IM->OrFlag );
}
@@ -418,27 +429,17 @@ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- ASSERT(tnl->ExecCopySource == IM);
-
_tnl_compute_orflag( IM );
-
- /* Mark the last primitive:
- */
- IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
- ASSERT(IM->Primitive[IM->LastPrimitive] & PRIM_LAST);
+ _tnl_copy_immediate_vertices( ctx, IM ); /* ?? flags, orflag above */
+ _tnl_get_exec_copy_verts( ctx, IM );
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
- _tnl_get_exec_copy_verts( ctx, IM );
-
if (IM->CopyStart == IM->Count) {
- if (IM->OrFlag & VERT_ELT)
- _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart );
-
- _tnl_copy_to_current( ctx, IM, IM->OrFlag );
+ exec_empty_cassette( ctx, IM );
}
- else if ((IM->OrFlag & VERT_DATA) == VERT_ELT &&
+ else if ((IM->CopyOrFlag & VERT_DATA) == VERT_ELT &&
ctx->Array.LockCount &&
ctx->Array.Vertex.Enabled) {
exec_elt_cassette( ctx, IM );
@@ -447,15 +448,23 @@ void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM )
exec_vert_cassette( ctx, IM );
}
- _tnl_reset_input( ctx,
- IMM_MAX_COPIED_VERTS,
- IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1),
- IM->SavedBeginState );
-
- /* Copy vertices and primitive information to immediate before it
- * can be overwritten.
+ /* Only reuse the immediate if there are no copied vertices living
+ * inside it:
*/
- _tnl_copy_immediate_vertices( ctx, IM );
+ {
+ GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1);
+ GLuint saved_begin_state = IM->SavedBeginState;
+
+ if (--IM->ref_count != 0) {
+ IM = _tnl_alloc_immediate( ctx );
+ SET_IMMEDIATE( ctx, IM );
+ }
+
+ IM->ref_count++;
+
+ _tnl_reset_input( ctx, IMM_MAX_COPIED_VERTS,
+ begin_state, saved_begin_state );
+ }
if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
@@ -483,8 +492,7 @@ void _tnl_imm_init( GLcontext *ctx )
tnl->ExecCopyTexSize = 0;
tnl->ExecCopyCount = 0;
- tnl->ExecCopySource = TNL_CURRENT_IM(ctx);
- TNL_CURRENT_IM(ctx)->ref_count++;
+ tnl->ExecCopySource = 0;
TNL_CURRENT_IM(ctx)->CopyStart = IMM_MAX_COPIED_VERTS;
@@ -523,7 +531,9 @@ void _tnl_imm_init( GLcontext *ctx )
void _tnl_imm_destroy( GLcontext *ctx )
{
- if (TNL_CURRENT_IM(ctx))
+ if (TNL_CURRENT_IM(ctx)) {
+ TNL_CURRENT_IM(ctx)->ref_count--;
_tnl_free_immediate( TNL_CURRENT_IM(ctx) );
-
+ SET_IMMEDIATE(ctx, 0);
+ }
}