diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2001-05-11 15:53:06 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2001-05-11 15:53:06 +0000 |
commit | c6083e1dc47057b64179079715c5eac8f6010467 (patch) | |
tree | 490b5d2c87c5f98b447ae1d387c6fcaf78638970 /src | |
parent | b8f9980999cb3619b3b60c089e6fa3b780a52292 (diff) |
Clean up _tnl_Begin/begin/hard_begin.
Fix some problems with draw_arrays, draw_elements.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/tnl/t_array_api.c | 54 | ||||
-rw-r--r-- | src/mesa/tnl/t_array_import.c | 3 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_api.c | 209 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_dlist.c | 9 | ||||
-rw-r--r-- | src/mesa/tnl/t_imm_fixup.c | 8 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_render.c | 5 |
6 files changed, 147 insertions, 141 deletions
diff --git a/src/mesa/tnl/t_array_api.c b/src/mesa/tnl/t_array_api.c index 0e482de5ab..257febefa1 100644 --- a/src/mesa/tnl/t_array_api.c +++ b/src/mesa/tnl/t_array_api.c @@ -1,4 +1,4 @@ -/* $Id: t_array_api.c,v 1.14 2001/05/11 08:11:31 keithw Exp $ */ +/* $Id: t_array_api.c,v 1.15 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -48,6 +48,8 @@ static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start, GLsizei count ) { +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + /* Need to produce immediate structs, either for compiling or * because the array range is too large to process in a single * VB. In GL_EXECUTE mode, this introduces two redundant @@ -56,20 +58,18 @@ static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start, */ #if 1 if (_tnl_hard_begin( ctx, mode )) { - GLint j; - for (j = 0 ; j < count ; ) { + GLint i; + for (i = 0 ; i < count ; ) { struct immediate *IM = TNL_CURRENT_IM(ctx); - GLuint nr = MIN2( IMM_MAXDATA - IM->Start, (GLuint) (count - j) ); - GLuint sf = IM->Flag[IM->Start]; - - _tnl_fill_immediate_drawarrays( ctx, IM, j, j+nr ); + GLuint start = IM->Start; + GLuint nr = MIN2( IMM_MAXDATA - start, (GLuint) (count - i) ); - if (j == 0) IM->Flag[IM->Start] |= sf; + _tnl_fill_immediate_drawarrays( ctx, IM, i, i+nr ); - IM->Count = IM->Start + nr; - j += nr; + IM->Count = start + nr; + i += nr; - if (j == count) + if (i == count) _tnl_end( ctx ); _tnl_flush_immediate( IM ); @@ -93,30 +93,31 @@ static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start, static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count, const GLuint *indices) { +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + #if 1 /* Optimized code that fakes the effect of calling * _tnl_array_element for each index in the list. */ if (_tnl_hard_begin( ctx, mode )) { GLint i, j; - for (j = 0 ; j < count ; ) { + for (i = 0 ; i < count ; ) { struct immediate *IM = TNL_CURRENT_IM(ctx); GLuint start = IM->Start; - GLint nr = MIN2( (GLint) (IMM_MAXDATA - start), count - j ) + start; + GLint end = MIN2( IMM_MAXDATA, (count - i) + start); GLuint sf = IM->Flag[start]; IM->FlushElt = IM->ArrayEltFlush; - for (i = start ; i < nr ; i++) { - IM->Elt[i] = (GLuint) *indices++; - IM->Flag[i] = VERT_ELT; + for (j = start ; j < end ; j++) { + IM->Elt[j] = (GLuint) *indices++; + IM->Flag[j] = VERT_ELT; } - if (j == 0) IM->Flag[start] |= sf; + IM->Flag[start] |= (sf & IM->ArrayEltFlags); + IM->Count = end; + i += end - start; - IM->Count = nr; - j += nr - start; - - if (j == count) + if (i == count) _tnl_end( ctx ); _tnl_flush_immediate( IM ); @@ -171,6 +172,8 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + /* Check arguments, etc. */ if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) @@ -277,11 +280,14 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) /* fprintf(stderr, "start %d count %d min %d modulo %d skip %d\n", */ /* start, count, minimum, modulo, skip); */ + + bufsz -= bufsz % modulo; + bufsz -= minimum; + for (j = start + minimum ; j < count ; j += nr + skip ) { nr = MIN2( bufsz, count - j ); - nr -= nr % modulo; /* fprintf(stderr, "%d..%d\n", j - minimum, j+nr); */ @@ -307,6 +313,8 @@ _tnl_DrawRangeElements(GLenum mode, TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint *ui_indices; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + /* Check arguments, etc. */ if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, @@ -367,6 +375,8 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type, TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint *ui_indices; +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + /* Check arguments, etc. */ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) diff --git a/src/mesa/tnl/t_array_import.c b/src/mesa/tnl/t_array_import.c index 5194758041..77fa8a4b97 100644 --- a/src/mesa/tnl/t_array_import.c +++ b/src/mesa/tnl/t_array_import.c @@ -1,4 +1,4 @@ -/* $Id: t_array_import.c,v 1.15 2001/05/11 08:11:31 keithw Exp $ */ +/* $Id: t_array_import.c,v 1.16 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -492,6 +492,7 @@ void _tnl_fill_immediate_drawarrays( GLcontext *ctx, struct immediate *IM, } IM->Count = IM->Start + n; + IM->Flag[IM->Start] &= IM->ArrayEltFlags; IM->Flag[IM->Start] |= required; for (i = IM->Start+1 ; i < IM->Count ; i++) IM->Flag[i] = required; diff --git a/src/mesa/tnl/t_imm_api.c b/src/mesa/tnl/t_imm_api.c index 143cee2d48..2a55e0ef63 100644 --- a/src/mesa/tnl/t_imm_api.c +++ b/src/mesa/tnl/t_imm_api.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_api.c,v 1.13 2001/05/11 08:11:31 keithw Exp $ */ +/* $Id: t_imm_api.c,v 1.14 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -78,6 +78,11 @@ void _tnl_flush_vertices( GLcontext *ctx, GLuint flags ) } + + +/* Note the ctx argument. This function called only by _tnl_Begin, + * _tnl_save_Begin and _tnl_hard_begin() in this file. + */ static void _tnl_begin( GLcontext *ctx, GLenum p ) { @@ -136,6 +141,25 @@ _tnl_begin( GLcontext *ctx, GLenum p ) } +void +_tnl_save_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (mode > GL_POLYGON) { + _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" ); + return; + } + + _tnl_begin( ctx, mode ); + + /* Update save_primitive now. + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) + ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM; + else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) + ctx->Driver.CurrentSavePrimitive = mode; +} static void _tnl_Begin( GLenum mode ) @@ -149,136 +173,101 @@ _tnl_Begin( GLenum mode ) _tnl_begin(ctx, mode); - /* If compiling update SavePrimitive now. - * - * In compile_and_exec mode, exec_primitive will be updated when - * the cassette is finished. - * - * If not compiling, update exec_primitive now. + /* Update exec_primitive now. */ - if (ctx->CompileFlag) { - if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) - ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM; - else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) - ctx->Driver.CurrentSavePrimitive = mode; - } - else if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { -/* fprintf(stderr, "setting cep %x in %s\n", mode, __FUNCTION__); */ + ASSERT (!ctx->CompileFlag); + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { ctx->Driver.CurrentExecPrimitive = mode; } } +/* Function which allows operations like 'glRectf' to decompose to a + * begin/end object and vertices without worrying about what happens + * with display lists. + */ GLboolean _tnl_hard_begin( GLcontext *ctx, GLenum p ) { - struct immediate *IM = TNL_CURRENT_IM(ctx); - GLuint count, last; - - if (ctx->NewState) - _mesa_update_state(ctx); - - /* If not compiling, treat as a normal begin(). - */ if (!ctx->CompileFlag) { - _tnl_begin( ctx, p ); - - /* Set this for the duration: + /* If not compiling, treat as a normal begin(). */ + _tnl_begin( ctx, p ); + ASSERT(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END); ctx->Driver.CurrentExecPrimitive = p; -/* fprintf(stderr, "setting cep %x in %s\n", */ -/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */ return GL_TRUE; } - - if (IM->Count > IMM_MAXDATA-8) { - _tnl_flush_immediate( IM ); - IM = TNL_CURRENT_IM(ctx); - } - - switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) { - case VERT_BEGIN_0|VERT_BEGIN_1: - /* This is an immediate known to be inside a begin/end object. - */ - IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0); - return GL_FALSE; - - case VERT_BEGIN_0: - case VERT_BEGIN_1: - /* This is a display-list immediate in an unknown begin/end - * state. Assert it is empty and conviert it to a 'hard' one. - */ - ASSERT (IM->SavedBeginState == 0); - - /* Push current beginstate, to be restored later. Don't worry - * about raising errors. + else { + /* Otherwise, need to do special processing to preserve the + * condition that these vertices will only be replayed outside + * future begin/end objects. */ - IM->SavedBeginState = IM->BeginState; + struct immediate *IM = TNL_CURRENT_IM(ctx); - /* FALLTHROUGH */ - case 0: - /* Unless we have fallen through, this is an immediate known to - * be outside begin/end objects. - */ - - IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1; - - - count = IM->Count; - last = IM->LastPrimitive; - - IM->Flag[count] |= VERT_BEGIN; - IM->Primitive[count] = p | PRIM_BEGIN; - IM->PrimitiveLength[last] = count - last; - IM->LastPrimitive = count; + if (ctx->NewState) + _mesa_update_state(ctx); - ASSERT (IM->FlushElt != FLUSH_ELT_EAGER); + if (IM->Count > IMM_MAXDATA-8) { + _tnl_flush_immediate( IM ); + IM = TNL_CURRENT_IM(ctx); + } - /* This is necessary as this immediate will not be flushed in - * _tnl_end() -- we leave it active, hoping to pick up more - * vertices before the next state change. + /* A lot depends on the degree to which the display list has + * constrained the possible begin/end states at this point: */ - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - - return GL_TRUE; - - default: - ASSERT (0); - return GL_TRUE; + switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) { + case VERT_BEGIN_0|VERT_BEGIN_1: + /* This is an immediate known to be inside a begin/end object. + */ + ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON); + IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0); + return GL_FALSE; + + case VERT_BEGIN_0: + case VERT_BEGIN_1: + /* This is a display-list immediate in an unknown begin/end + * state. Assert it is empty and convert it to a 'hard' one. + */ + ASSERT(IM->SavedBeginState == 0); + ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN); + + /* Push current beginstate, to be restored later. Don't worry + * about raising errors. + */ + IM->SavedBeginState = IM->BeginState; + + /* FALLTHROUGH */ + + case 0: + /* Unless we have fallen through, this is an immediate known to + * be outside begin/end objects. + */ + ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN || + ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END); + ASSERT (IM->FlushElt != FLUSH_ELT_EAGER); + + IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1; + IM->Flag[IM->Count] |= VERT_BEGIN; + IM->Primitive[IM->Count] = p | PRIM_BEGIN; + IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; + IM->LastPrimitive = IM->Count; + + /* This is necessary as this immediate will not be flushed in + * _tnl_end() -- we leave it active, hoping to pick up more + * vertices before the next state change. + */ + ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + return GL_TRUE; + + default: + ASSERT (0); + return GL_TRUE; + } } } -/* Need to do this to get the correct begin/end error behaviour from - * functions like ColorPointerEXT which are still active in - * SAVE_AND_EXEC modes. - */ -void -_tnl_save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - - if (mode > GL_POLYGON) { - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (ctx->ExecuteFlag) { - /* Preserve vtxfmt invarient: - */ - if (ctx->NewState) - _mesa_update_state( ctx ); - - /* Slot in geomexec: No need to call setdispatch as we know - * CurrentDispatch is Save. - */ - ASSERT(ctx->CurrentDispatch == ctx->Save); - } - - _tnl_begin( ctx, mode ); -} - @@ -317,8 +306,6 @@ _tnl_end( GLcontext *ctx ) if (!ctx->CompileFlag) { ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; -/* fprintf(stderr, "setting cep %x in %s\n", */ -/* ctx->Driver.CurrentExecPrimitive, __FUNCTION__); */ } /* You can set this flag to get the old 'flush_vb on glEnd()' @@ -1113,8 +1100,8 @@ _tnl_vertex2f( GLcontext *ctx, GLfloat x, GLfloat y ) /* Execute a glRectf() function. _tnl_hard_begin() ensures the check * on outside_begin_end is executed even in compiled lists. These - * vertices can now participate in the same VB as regular ones, even - * in most display lists. + * vertices can now participate in the same immediate as regular ones, + * even in most display lists. */ static void _tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) diff --git a/src/mesa/tnl/t_imm_dlist.c b/src/mesa/tnl/t_imm_dlist.c index cb7493c037..7cb947a72c 100644 --- a/src/mesa/tnl/t_imm_dlist.c +++ b/src/mesa/tnl/t_imm_dlist.c @@ -1,4 +1,4 @@ -/* $Id: t_imm_dlist.c,v 1.17 2001/05/11 08:11:31 keithw Exp $ */ +/* $Id: t_imm_dlist.c,v 1.18 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -82,6 +82,13 @@ _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ) } _tnl_compute_orflag( IM, IM->Start ); + + /* Need to clear this flag, or fixup gets confused. (The elements + * have been translated away by now.) + */ + IM->OrFlag &= ~VERT_ELT; + IM->AndFlag &= ~VERT_ELT; + _tnl_fixup_input( ctx, IM ); /* _tnl_print_cassette( IM ); */ diff --git a/src/mesa/tnl/t_imm_fixup.c b/src/mesa/tnl/t_imm_fixup.c index 979fc0cdab..5300585281 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.15 2001/05/11 08:11:31 keithw Exp $ */ +/* $Id: t_imm_fixup.c,v 1.16 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -290,9 +290,9 @@ void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) if (fixup & VERT_RGBA) { if (orflag & VERT_RGBA) _tnl_fixup_4f( IM->Color, IM->Flag, start, VERT_RGBA ); -/* else */ -/* fixup_first_4f( IM->Color, IM->Flag, VERT_END_VB, start, */ -/* IM->Color[start] ); */ + /* No need for else case as the drivers understand stride + * zero here. (TODO - propogate this) + */ } if (fixup & VERT_SPEC_RGB) { diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c index fc4fb95852..414c6bd34a 100644 --- a/src/mesa/tnl/t_vb_render.c +++ b/src/mesa/tnl/t_vb_render.c @@ -1,4 +1,4 @@ -/* $Id: t_vb_render.c,v 1.19 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: t_vb_render.c,v 1.20 2001/05/11 15:53:06 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -318,7 +318,8 @@ static GLboolean run_render( GLcontext *ctx, tnl->Driver.RenderFinish( ctx ); -/* usleep(100000); */ +/* _swrast_flush(ctx); */ +/* usleep(1000000); */ return GL_FALSE; /* finished the pipe */ } |