diff options
Diffstat (limited to 'src/mesa/vbo')
| -rw-r--r-- | src/mesa/vbo/vbo.h | 1 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec.h | 22 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec_api.c | 164 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec_array.c | 203 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_exec_draw.c | 6 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_rebase.c | 18 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 65 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_split.c | 8 | ||||
| -rw-r--r-- | src/mesa/vbo/vbo_split_copy.c | 52 | 
9 files changed, 434 insertions, 105 deletions
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 5986e93576..b24ecfd7cd 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -44,6 +44,7 @@ struct _mesa_prim {     GLuint start;     GLuint count; +   GLint basevertex;  };  /* Would like to call this a "vbo_index_buffer", but this would be diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index 7fb5926160..98c1f363d9 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -138,6 +138,10 @@ struct vbo_exec_context         */        const struct gl_client_array *inputs[VERT_ATTRIB_MAX];     } array; + +#ifdef DEBUG +   GLint flush_call_depth; +#endif  }; @@ -161,8 +165,26 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec );  void vbo_exec_vtx_init( struct vbo_exec_context *exec );  void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); + +#if FEATURE_beginend +  void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap );  void vbo_exec_vtx_map( struct vbo_exec_context *exec ); + +#else /* FEATURE_beginend */ + +static INLINE void +vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ) +{ +} + +static INLINE void +vbo_exec_vtx_map( struct vbo_exec_context *exec ) +{ +} + +#endif /* FEATURE_beginend */ +  void vbo_exec_vtx_wrap( struct vbo_exec_context *exec );  void vbo_exec_eval_update( struct vbo_exec_context *exec ); diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index acc7647900..f0a7eeadd0 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -35,9 +35,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "main/context.h"  #include "main/macros.h"  #include "main/vtxfmt.h" -#if FEATURE_dlist  #include "main/dlist.h" -#endif +#include "main/eval.h"  #include "main/state.h"  #include "main/light.h"  #include "main/api_arrayelt.h" @@ -58,7 +57,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  static void reset_attrfv( struct vbo_exec_context *exec ); -/* Close off the last primitive, execute the buffer, restart the +/** + * Close off the last primitive, execute the buffer, restart the   * primitive.     */  static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec ) @@ -107,7 +107,8 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )  } -/* Deal with buffer wrapping where provoked by the vertex buffer +/** + * Deal with buffer wrapping where provoked by the vertex buffer   * filling up, as opposed to upgrade_vertex().   */  void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) @@ -136,7 +137,7 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )  } -/* +/**   * Copy the active vertex's values to the ctx->Current fields.   */  static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) @@ -209,7 +210,8 @@ static void vbo_exec_copy_from_current( struct vbo_exec_context *exec )  } -/* Flush existing data, set new attrib size, replay copied vertices. +/** + * Flush existing data, set new attrib size, replay copied vertices.   */   static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,  					  GLuint attr, @@ -349,7 +351,7 @@ static void vbo_exec_fixup_vertex( GLcontext *ctx,  } - +#if FEATURE_beginend  /*    */ @@ -392,8 +394,8 @@ do {								\ -/* Eval - */ +#if FEATURE_evaluators +  static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )  {     GET_CURRENT_CONTEXT( ctx ); @@ -485,9 +487,15 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )     vbo_exec_EvalCoord2f( u, v );  } +/* use noop eval mesh */ +#define vbo_exec_EvalMesh1 _mesa_noop_EvalMesh1 +#define vbo_exec_EvalMesh2 _mesa_noop_EvalMesh2 + +#endif /* FEATURE_evaluators */ -/* Build a list of primitives on the fly.  Keep - * ctx->Driver.CurrentExecPrimitive uptodate as well. + +/** + * Called via glBegin.   */  static void GLAPIENTRY vbo_exec_Begin( GLenum mode )  { @@ -531,6 +539,10 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )  } + +/** + * Called via glEnd. + */  static void GLAPIENTRY vbo_exec_End( void )  {     GET_CURRENT_CONTEXT( ctx );  @@ -557,24 +569,15 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )  {     GLvertexformat *vfmt = &exec->vtxfmt; -   vfmt->ArrayElement = _ae_loopback_array_elt;	        /* generic helper */ +   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_); +     vfmt->Begin = vbo_exec_Begin; -#if FEATURE_dlist -   vfmt->CallList = _mesa_CallList; -   vfmt->CallLists = _mesa_CallLists; -#endif     vfmt->End = vbo_exec_End; -   vfmt->EvalCoord1f = vbo_exec_EvalCoord1f; -   vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv; -   vfmt->EvalCoord2f = vbo_exec_EvalCoord2f; -   vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv; -   vfmt->EvalPoint1 = vbo_exec_EvalPoint1; -   vfmt->EvalPoint2 = vbo_exec_EvalPoint2; -   vfmt->Rectf = _mesa_noop_Rectf; -   vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; -   vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; +   _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_); +   _MESA_INIT_EVAL_VTXFMT(vfmt, vbo_exec_); +   vfmt->Rectf = _mesa_noop_Rectf;     /* from attrib_tmp.h:      */ @@ -638,6 +641,98 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )  } +#else /* FEATURE_beginend */ + + +#define ATTR( A, N, V0, V1, V2, V3 )				\ +do {								\ +   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;	\ +								\ +   /* FLUSH_UPDATE_CURRENT needs to be set manually */		\ +   exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;		\ +								\ +   if (exec->vtx.active_sz[A] != N)				\ +      vbo_exec_fixup_vertex(ctx, A, N);				\ +								\ +   {								\ +      GLfloat *dest = exec->vtx.attrptr[A];			\ +      if (N>0) dest[0] = V0;					\ +      if (N>1) dest[1] = V1;					\ +      if (N>2) dest[2] = V2;					\ +      if (N>3) dest[3] = V3;					\ +   }								\ +} while (0) + +#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) +#define TAG(x) vbo_##x + +#include "vbo_attrib_tmp.h" + +static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec ) +{ +   /* silence warnings */ +   (void) vbo_Color3f; +   (void) vbo_Color3fv; +   (void) vbo_Color4f; +   (void) vbo_Color4fv; +   (void) vbo_FogCoordfEXT; +   (void) vbo_FogCoordfvEXT; +   (void) vbo_MultiTexCoord1f; +   (void) vbo_MultiTexCoord1fv; +   (void) vbo_MultiTexCoord2f; +   (void) vbo_MultiTexCoord2fv; +   (void) vbo_MultiTexCoord3f; +   (void) vbo_MultiTexCoord3fv; +   (void) vbo_MultiTexCoord4f; +   (void) vbo_MultiTexCoord4fv; +   (void) vbo_Normal3f; +   (void) vbo_Normal3fv; +   (void) vbo_SecondaryColor3fEXT; +   (void) vbo_SecondaryColor3fvEXT; +   (void) vbo_TexCoord1f; +   (void) vbo_TexCoord1fv; +   (void) vbo_TexCoord2f; +   (void) vbo_TexCoord2fv; +   (void) vbo_TexCoord3f; +   (void) vbo_TexCoord3fv; +   (void) vbo_TexCoord4f; +   (void) vbo_TexCoord4fv; +   (void) vbo_Vertex2f; +   (void) vbo_Vertex2fv; +   (void) vbo_Vertex3f; +   (void) vbo_Vertex3fv; +   (void) vbo_Vertex4f; +   (void) vbo_Vertex4fv; + +   (void) vbo_VertexAttrib1fARB; +   (void) vbo_VertexAttrib1fvARB; +   (void) vbo_VertexAttrib2fARB; +   (void) vbo_VertexAttrib2fvARB; +   (void) vbo_VertexAttrib3fARB; +   (void) vbo_VertexAttrib3fvARB; +   (void) vbo_VertexAttrib4fARB; +   (void) vbo_VertexAttrib4fvARB; + +   (void) vbo_VertexAttrib1fNV; +   (void) vbo_VertexAttrib1fvNV; +   (void) vbo_VertexAttrib2fNV; +   (void) vbo_VertexAttrib2fvNV; +   (void) vbo_VertexAttrib3fNV; +   (void) vbo_VertexAttrib3fvNV; +   (void) vbo_VertexAttrib4fNV; +   (void) vbo_VertexAttrib4fvNV; + +   (void) vbo_Materialfv; + +   (void) vbo_EdgeFlag; +   (void) vbo_Indexf; +   (void) vbo_Indexfv; +} + + +#endif /* FEATURE_beginend */ + +  /**   * Tell the VBO module to use a real OpenGL vertex buffer object to   * store accumulated immediate-mode vertex data. @@ -772,15 +867,27 @@ void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap )  } - +/** + * \param flags  bitmask of FLUSH_STORED_VERTICES, FLUSH_UPDATE_CURRENT + */  void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )  {     struct vbo_exec_context *exec = &vbo_context(ctx)->exec; +#ifdef DEBUG +   /* debug check: make sure we don't get called recursively */ +   exec->flush_call_depth++; +   assert(exec->flush_call_depth == 1); +#endif +     if (0) _mesa_printf("%s\n", __FUNCTION__);     if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {        if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); +#ifdef DEBUG +      exec->flush_call_depth--; +      assert(exec->flush_call_depth == 0); +#endif        return;     } @@ -794,6 +901,11 @@ void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )     }     exec->ctx->Driver.NeedFlush &= ~flags; + +#ifdef DEBUG +   exec->flush_call_depth--; +   assert(exec->flush_call_depth == 0); +#endif  } diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 39c2957631..6de8f059b7 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -33,6 +33,7 @@  #include "main/api_noop.h"  #include "main/varray.h"  #include "main/bufferobj.h" +#include "main/enums.h"  #include "main/macros.h"  #include "glapi/dispatch.h" @@ -53,10 +54,9 @@ vbo_get_minmax_index(GLcontext *ctx,     const void *indices;     if (_mesa_is_bufferobj(ib->obj)) { -      const GLvoid *map = ctx->Driver.MapBuffer(ctx, -                                                GL_ELEMENT_ARRAY_BUFFER_ARB, -                                                GL_READ_ONLY, -                                                ib->obj); +      const GLvoid *map = +         ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, +                               GL_READ_ONLY, ib->obj);        indices = ADD_POINTERS(map, ib->ptr);     } else {        indices = ib->ptr; @@ -105,9 +105,7 @@ vbo_get_minmax_index(GLcontext *ctx,     }     if (_mesa_is_bufferobj(ib->obj)) { -      ctx->Driver.UnmapBuffer(ctx, -			      GL_ELEMENT_ARRAY_BUFFER_ARB, -			      ib->obj); +      ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, ib->obj);     }  } @@ -125,10 +123,9 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array,        if (_mesa_is_bufferobj(array->BufferObj)) {           if (!array->BufferObj->Pointer) {              /* need to map now */ -            array->BufferObj->Pointer = ctx->Driver.MapBuffer(ctx, -                                                              GL_ARRAY_BUFFER_ARB, -                                                              GL_READ_ONLY, -                                                              array->BufferObj); +            array->BufferObj->Pointer = +               ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, +                                     GL_READ_ONLY, array->BufferObj);           }           data = ADD_POINTERS(data, array->BufferObj->Pointer);        } @@ -149,7 +146,7 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array,                                 array->Ptr, array->BufferObj->Name);                    f[k] = 1.0; /* XXX replace the bad value! */                 } -               //assert(!IS_INF_OR_NAN(f[k])); +               /*assert(!IS_INF_OR_NAN(f[k]));*/              }           }           break; @@ -169,9 +166,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)     if (array->Enabled &&         _mesa_is_bufferobj(array->BufferObj) &&         _mesa_bufferobj_mapped(array->BufferObj)) { -      ctx->Driver.UnmapBuffer(ctx, -                              GL_ARRAY_BUFFER_ARB, -                              array->BufferObj); +      ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, array->BufferObj);     }  } @@ -181,7 +176,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)   */  static void  check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType, -                         const void *elements) +                         const void *elements, GLint basevertex)  {     struct gl_array_object *arrayObj = ctx->Array.ArrayObj;     const void *elemMap; @@ -222,13 +217,13 @@ check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,           check_array_data(ctx, &arrayObj->TexCoord[k], VERT_ATTRIB_TEX0 + k, j);        }        for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { -         check_array_data(ctx, &arrayObj->VertexAttrib[k], VERT_ATTRIB_GENERIC0 + k, j); +         check_array_data(ctx, &arrayObj->VertexAttrib[k], +                          VERT_ATTRIB_GENERIC0 + k, j);        }     }     if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { -      ctx->Driver.UnmapBuffer(ctx, -			      GL_ELEMENT_ARRAY_BUFFER_ARB, +      ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB,  			      ctx->Array.ElementArrayBufferObj);     } @@ -459,7 +454,6 @@ bind_arrays(GLcontext *ctx)     }     else if (exec->array.program_mode != get_program_mode(ctx) ||  	    exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) { -              recalculate_input_bindings(ctx);     }  #else @@ -482,6 +476,10 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)     struct vbo_exec_context *exec = &vbo->exec;     struct _mesa_prim prim[1]; +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", +                  _mesa_lookup_enum_by_nr(mode), start, count); +     if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))        return; @@ -518,6 +516,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)     prim[0].start = start;     prim[0].count = count;     prim[0].indexed = 0; +   prim[0].basevertex = 0;     vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,                      GL_TRUE, start, start + count - 1 ); @@ -581,18 +580,19 @@ dump_element_buffer(GLcontext *ctx, GLenum type)        ;     } -   ctx->Driver.UnmapBuffer(ctx, -                           GL_ELEMENT_ARRAY_BUFFER_ARB, +   ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB,                             ctx->Array.ElementArrayBufferObj);  } +  /* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */  static void  vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,  				GLboolean index_bounds_valid,  				GLuint start, GLuint end,  				GLsizei count, GLenum type, -				const GLvoid *indices) +				const GLvoid *indices, +				GLint basevertex)  {     struct vbo_context *vbo = vbo_context(ctx);     struct vbo_exec_context *exec = &vbo->exec; @@ -626,6 +626,7 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,     prim[0].start = 0;     prim[0].count = count;     prim[0].indexed = 1; +   prim[0].basevertex = basevertex;     /* Need to give special consideration to rendering a range of      * indices starting somewhere above zero.  Typically the @@ -663,17 +664,31 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,  }  static void GLAPIENTRY -vbo_exec_DrawRangeElements(GLenum mode, -			   GLuint start, GLuint end, -			   GLsizei count, GLenum type, const GLvoid *indices) +vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, +				     GLuint start, GLuint end, +				     GLsizei count, GLenum type, +				     const GLvoid *indices, +				     GLint basevertex)  {     static GLuint warnCount = 0;     GET_CURRENT_CONTEXT(ctx); +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, +                "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", +                _mesa_lookup_enum_by_nr(mode), start, end, count, +                _mesa_lookup_enum_by_nr(type), indices, basevertex); +     if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, -                                          type, indices )) +                                          type, indices, basevertex ))        return; +   /* NOTE: It's important that 'end' is a reasonable value. +    * in _tnl_draw_prims(), we use end to determine how many vertices +    * to transform.  If it's too large, we can unnecessarily split prims +    * or we can read/write out of memory in several different places! +    */ +     if (end >= ctx->Array.ArrayObj->_MaxElement) {        /* the max element is out of bounds of one or more enabled arrays */        warnCount++; @@ -726,10 +741,12 @@ vbo_exec_DrawRangeElements(GLenum mode,  #endif     }     else if (0) { -      _mesa_printf("glDraw[Range]Elements" -                   "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n", +      _mesa_printf("glDraw[Range]Elements{,BaseVertex}" +                   "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " +		   "base %d\n",                     start, end, type, count, -                   ctx->Array.ElementArrayBufferObj->Name); +                   ctx->Array.ElementArrayBufferObj->Name, +		   basevertex);     }  #if 0 @@ -739,7 +756,24 @@ vbo_exec_DrawRangeElements(GLenum mode,  #endif     vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end, -				   count, type, indices); +				   count, type, indices, basevertex); +} + + +static void GLAPIENTRY +vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, +                           GLsizei count, GLenum type, const GLvoid *indices) +{ +   GET_CURRENT_CONTEXT(ctx); + +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, +                  "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", +                  _mesa_lookup_enum_by_nr(mode), start, end, count, +                  _mesa_lookup_enum_by_nr(type), indices); + +   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, +					indices, 0);  } @@ -749,18 +783,45 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,  {     GET_CURRENT_CONTEXT(ctx); -   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", +                  _mesa_lookup_enum_by_nr(mode), count, +                  _mesa_lookup_enum_by_nr(type), indices); + +   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))        return;     vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, -				   count, type, indices); +				   count, type, indices, 0);  } -/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */ + +static void GLAPIENTRY +vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, +				const GLvoid *indices, GLint basevertex) +{ +   GET_CURRENT_CONTEXT(ctx); + +   if (MESA_VERBOSE & VERBOSE_DRAW) +      _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n", +                  _mesa_lookup_enum_by_nr(mode), count, +                  _mesa_lookup_enum_by_nr(type), indices, basevertex); + +   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, +				     basevertex )) +      return; + +   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, +				   count, type, indices, basevertex); +} + + +/** Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */  static void  vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,  				const GLsizei *count, GLenum type, -				const GLvoid **indices, GLsizei primcount) +				const GLvoid **indices, GLsizei primcount, +				const GLint *basevertex)  {     struct vbo_context *vbo = vbo_context(ctx);     struct vbo_exec_context *exec = &vbo->exec; @@ -854,6 +915,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,  	 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;  	 prim[i].count = count[i];  	 prim[i].indexed = 1; +	 if (basevertex != NULL) +	    prim[i].basevertex = basevertex[i]; +	 else +	    prim[i].basevertex = 0;        }        vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib, @@ -874,6 +939,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,  	 prim[0].start = 0;  	 prim[0].count = count[i];  	 prim[0].indexed = 1; +	 if (basevertex != NULL) +	    prim[0].basevertex = basevertex[i]; +	 else +	    prim[0].basevertex = 0;        }        vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, @@ -882,6 +951,7 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,     _mesa_free(prim);  } +  static void GLAPIENTRY  vbo_exec_MultiDrawElements(GLenum mode,  			   const GLsizei *count, GLenum type, @@ -894,14 +964,38 @@ vbo_exec_MultiDrawElements(GLenum mode,     ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);     for (i = 0; i < primcount; i++) { -      if (!_mesa_validate_DrawElements( ctx, mode, count[i], type, indices[i] )) +      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i], +				       0))  	 return;     } -   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount); +   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, +				   NULL);  } +static void GLAPIENTRY +vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, +				     const GLsizei *count, GLenum type, +				     const GLvoid **indices, +				     GLsizei primcount, +				     const GLsizei *basevertex) +{ +   GET_CURRENT_CONTEXT(ctx); +   GLint i; + +   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + +   for (i = 0; i < primcount; i++) { +      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i], +				       basevertex[i])) +	 return; +   } + +   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, +				   basevertex); +} +  /***********************************************************************   * Initialization @@ -915,11 +1009,17 @@ vbo_exec_array_init( struct vbo_exec_context *exec )     exec->vtxfmt.DrawElements = vbo_exec_DrawElements;     exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;     exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements; +   exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex; +   exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex; +   exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;  #else     exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;     exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;     exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;     exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; +   exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex; +   exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex; +   exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;  #endif  } @@ -947,6 +1047,13 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,     vbo_exec_DrawElements(mode, count, type, indices);  } +void GLAPIENTRY +_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, +			     const GLvoid *indices, GLint basevertex) +{ +   vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); +} +  /* This API entrypoint is not ordinarily used */  void GLAPIENTRY @@ -956,6 +1063,17 @@ _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,     vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);  } + +void GLAPIENTRY +_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, +				  GLsizei count, GLenum type, +				  const GLvoid *indices, GLint basevertex) +{ +   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, +					indices, basevertex); +} + +  /* GL_EXT_multi_draw_arrays */  void GLAPIENTRY  _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, @@ -963,3 +1081,14 @@ _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,  {     vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);  } + + +void GLAPIENTRY +_mesa_MultiDrawElementsBaseVertex(GLenum mode, +				  const GLsizei *count, GLenum type, +				  const GLvoid **indices, GLsizei primcount, +				  const GLint *basevertex) +{ +   vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, +					primcount, basevertex); +} diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index f41d629450..4f43856016 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -35,6 +35,9 @@  #include "vbo_context.h" +#if FEATURE_beginend + +  static void  vbo_exec_debug_verts( struct vbo_exec_context *exec )  { @@ -415,3 +418,6 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )     exec->vtx.prim_count = 0;     exec->vtx.vert_count = 0;  } + + +#endif /* FEATURE_beginend */ diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index 3bf7ef580f..55a82ee369 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -126,7 +126,23 @@ void vbo_rebase_prims( GLcontext *ctx,     if (0)        _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); -   if (ib) { + +   /* XXX this path is disabled for now. +    * There's rendering corruption in some apps when it's enabled. +    */ +   if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) { +      /* If we can just tell the hardware or the TNL to interpret our +       * indices with a different base, do so. +       */ +      tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims); + +      for (i = 0; i < nr_prims; i++) { +	 tmp_prims[i] = prim[i]; +	 tmp_prims[i].basevertex -= min_index; +      } + +      prim = tmp_prims; +   } else if (ib) {        /* Unfortunately need to adjust each index individually.         */        GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 1771510d84..3f86c68b24 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -72,6 +72,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "main/context.h"  #include "main/dlist.h"  #include "main/enums.h" +#include "main/eval.h"  #include "main/macros.h"  #include "main/api_noop.h"  #include "main/api_validate.h" @@ -269,7 +270,7 @@ static void _save_compile_vertex_list( GLcontext *ctx )      * being compiled.      */     node = (struct vbo_save_vertex_list *) -      _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); +      _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node));     if (!node)        return; @@ -826,6 +827,33 @@ static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,     _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );  } +static void GLAPIENTRY _save_DrawElementsBaseVertex(GLenum mode, +						    GLsizei count, +						    GLenum type, +						    const GLvoid *indices, +						    GLint basevertex) +{ +   GET_CURRENT_CONTEXT(ctx); +   (void) mode; (void) count; (void) type; (void) indices; (void)basevertex; + +   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); +} + +static void GLAPIENTRY _save_DrawRangeElementsBaseVertex(GLenum mode, +							 GLuint start, +							 GLuint end, +							 GLsizei count, +							 GLenum type, +							 const GLvoid *indices, +							 GLint basevertex) +{ +   GET_CURRENT_CONTEXT(ctx); +   (void) mode; (void) start; (void) end; (void) count; (void) type; +   (void) indices; (void)basevertex; + +   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); +} +  static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)  {     GET_CURRENT_CONTEXT(ctx); @@ -907,7 +935,7 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum     GET_CURRENT_CONTEXT(ctx);     GLint i; -   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) +   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))        return;     _ae_map_vbos( ctx ); @@ -948,7 +976,7 @@ static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,     GET_CURRENT_CONTEXT(ctx);     if (_mesa_validate_DrawRangeElements( ctx, mode,  					 start, end, -					 count, type, indices )) +					 count, type, indices, 0 ))        _save_OBE_DrawElements( mode, count, type, indices );  } @@ -961,7 +989,8 @@ static void _save_vtxfmt_init( GLcontext *ctx )     struct vbo_save_context *save = &vbo_context(ctx)->save;     GLvertexformat *vfmt = &save->vtxfmt; -   vfmt->ArrayElement = _ae_loopback_array_elt;	        /* generic helper */ +   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_); +     vfmt->Begin = _save_Begin;     vfmt->Color3f = _save_Color3f;     vfmt->Color3fv = _save_Color3fv; @@ -1020,28 +1049,23 @@ static void _save_vtxfmt_init( GLcontext *ctx )     /* This will all require us to fallback to saving the list as opcodes:      */  -   vfmt->CallList = _save_CallList; /* inside begin/end */ -   vfmt->CallLists = _save_CallLists; /* inside begin/end */ -   vfmt->EvalCoord1f = _save_EvalCoord1f; -   vfmt->EvalCoord1fv = _save_EvalCoord1fv; -   vfmt->EvalCoord2f = _save_EvalCoord2f; -   vfmt->EvalCoord2fv = _save_EvalCoord2fv; -   vfmt->EvalPoint1 = _save_EvalPoint1; -   vfmt->EvalPoint2 = _save_EvalPoint2; +   _MESA_INIT_DLIST_VTXFMT(vfmt, _save_); /* inside begin/end */ + +   _MESA_INIT_EVAL_VTXFMT(vfmt, _save_);     /* These are all errors as we at least know we are in some sort of      * begin/end pair:      */ -   vfmt->EvalMesh1 = _save_EvalMesh1;	 -   vfmt->EvalMesh2 = _save_EvalMesh2;     vfmt->Begin = _save_Begin;     vfmt->Rectf = _save_Rectf;     vfmt->DrawArrays = _save_DrawArrays;     vfmt->DrawElements = _save_DrawElements;     vfmt->DrawRangeElements = _save_DrawRangeElements; +   vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex; +   vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;     /* Loops back into vfmt->DrawElements */     vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; - +   vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;  } @@ -1209,11 +1233,11 @@ void vbo_save_api_init( struct vbo_save_context *save )     GLuint i;     save->opcode_vertex_list = -      _mesa_alloc_opcode( ctx, -			  sizeof(struct vbo_save_vertex_list), -			  vbo_save_playback_vertex_list, -			  vbo_destroy_vertex_list, -			  vbo_print_vertex_list ); +      _mesa_dlist_alloc_opcode( ctx, +                                sizeof(struct vbo_save_vertex_list), +                                vbo_save_playback_vertex_list, +                                vbo_destroy_vertex_list, +                                vbo_print_vertex_list );     ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; @@ -1233,6 +1257,7 @@ void vbo_save_api_init( struct vbo_save_context *save )     ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;     /* loops back into _save_OBE_DrawElements */     ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; +   ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;     _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );  } diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c index 58e879628d..c445acca7d 100644 --- a/src/mesa/vbo/vbo_split.c +++ b/src/mesa/vbo/vbo_split.c @@ -50,6 +50,7 @@  #include "main/glheader.h"  #include "main/imports.h"  #include "main/mtypes.h" +#include "main/macros.h"  #include "vbo_split.h"  #include "vbo.h" @@ -107,7 +108,12 @@ void vbo_split_prims( GLcontext *ctx,  		      vbo_draw_func draw,  		      const struct split_limits *limits )  { -   +   GLuint max_basevertex = prim->basevertex; +   GLuint i; + +   for (i = 1; i < nr_prims; i++) +      max_basevertex = MAX2(max_basevertex, prim[i].basevertex); +     if (ib) {        if (limits->max_indices == 0) {  	 /* Could traverse the indices, re-emitting vertices in turn. diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 8ec180d550..c45190b9dd 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -589,28 +589,40 @@ void vbo_split_copy( GLcontext *ctx,  		     const struct split_limits *limits )  {     struct copy_context copy; -   GLuint i; +   GLuint i, this_nr_prims; -   memset(©, 0, sizeof(copy)); +   for (i = 0; i < nr_prims;) { +      /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices +       * will rebase the elements to the basevertex, and we'll only +       * emit strings of prims with the same basevertex in one draw call. +       */ +      for (this_nr_prims = 1; i + this_nr_prims < nr_prims; +	   this_nr_prims++) { +	 if (prim[i].basevertex != prim[i + this_nr_prims].basevertex) +	    break; +      } -   /* Require indexed primitives: -    */ -   assert(ib); -    -   copy.ctx = ctx; -   copy.array = arrays; -   copy.prim = prim; -   copy.nr_prims = nr_prims; -   copy.ib = ib; -   copy.draw = draw; -   copy.limits = limits; +      memset(©, 0, sizeof(copy)); -   /* Clear the vertex cache: -    */ -   for (i = 0; i < ELT_TABLE_SIZE; i++) -      copy.vert_cache[i].in = ~0; +      /* Require indexed primitives: +       */ +      assert(ib); + +      copy.ctx = ctx; +      copy.array = arrays; +      copy.prim = &prim[i]; +      copy.nr_prims = this_nr_prims; +      copy.ib = ib; +      copy.draw = draw; +      copy.limits = limits; -   replay_init(©); -   replay_elts(©); -   replay_finish(©); +      /* Clear the vertex cache: +       */ +      for (i = 0; i < ELT_TABLE_SIZE; i++) +	 copy.vert_cache[i].in = ~0; + +      replay_init(©); +      replay_elts(©); +      replay_finish(©); +   }  }  | 
