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 | 195 | ||||
| -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, 140 insertions, 134 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. +   else { +      /* Otherwise, need to do special processing to preserve the +       * condition that these vertices will only be replayed outside +       * future begin/end objects.         */ -      IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0); -      return GL_FALSE; +      struct immediate *IM = TNL_CURRENT_IM(ctx); -   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); +      if (ctx->NewState) +	 _mesa_update_state(ctx); -      /* Push current beginstate, to be restored later.  Don't worry -       * about raising errors. -       */ -      IM->SavedBeginState = IM->BeginState; +      if (IM->Count > IMM_MAXDATA-8) { +	 _tnl_flush_immediate( IM ); +	 IM = TNL_CURRENT_IM(ctx); +      } -      /* FALLTHROUGH */ -   case 0: -      /* Unless we have fallen through, this is an immediate known to -       * be outside begin/end objects. +      /* A lot depends on the degree to which the display list has +       * constrained the possible begin/end states at this point:         */ +      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; -      IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1; +      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; -      count = IM->Count; -      last = IM->LastPrimitive; +	 /* FALLTHROUGH */ -      IM->Flag[count] |= VERT_BEGIN; -      IM->Primitive[count] = p | PRIM_BEGIN; -      IM->PrimitiveLength[last] = count - last; -      IM->LastPrimitive = count; +      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); -      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; +	 /* 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; +      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 */  }  | 
