aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/vbo
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/vbo')
-rw-r--r--mesalib/src/mesa/vbo/vbo.h1
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.h22
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c164
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c203
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_draw.c6
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_eval.c33
-rw-r--r--mesalib/src/mesa/vbo/vbo_rebase.c18
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c65
-rw-r--r--mesalib/src/mesa/vbo/vbo_split.c8
-rw-r--r--mesalib/src/mesa/vbo/vbo_split_copy.c52
10 files changed, 455 insertions, 117 deletions
diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h
index 5986e9357..b24ecfd7c 100644
--- a/mesalib/src/mesa/vbo/vbo.h
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h
index 7fb592616..98c1f363d 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.h
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c
index acc764790..f0a7eeadd 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_api.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 39c295763..6de8f059b 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c
index f41d62945..4f4385601 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_draw.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_exec_eval.c b/mesalib/src/mesa/vbo/vbo_exec_eval.c
index 0c691b3a5..a7846213d 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_eval.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_eval.c
@@ -35,17 +35,20 @@
static void clear_active_eval1( struct vbo_exec_context *exec, GLuint attr )
{
+ assert(attr < Elements(exec->eval.map1));
exec->eval.map1[attr].map = NULL;
}
static void clear_active_eval2( struct vbo_exec_context *exec, GLuint attr )
{
+ assert(attr < Elements(exec->eval.map2));
exec->eval.map2[attr].map = NULL;
}
static void set_active_eval1( struct vbo_exec_context *exec, GLuint attr, GLuint dim,
struct gl_1d_map *map )
{
+ assert(attr < Elements(exec->eval.map1));
if (!exec->eval.map1[attr].map) {
exec->eval.map1[attr].map = map;
exec->eval.map1[attr].sz = dim;
@@ -55,6 +58,7 @@ static void set_active_eval1( struct vbo_exec_context *exec, GLuint attr, GLuint
static void set_active_eval2( struct vbo_exec_context *exec, GLuint attr, GLuint dim,
struct gl_2d_map *map )
{
+ assert(attr < Elements(exec->eval.map2));
if (!exec->eval.map2[attr].map) {
exec->eval.map2[attr].map = map;
exec->eval.map2[attr].sz = dim;
@@ -73,18 +77,6 @@ void vbo_exec_eval_update( struct vbo_exec_context *exec )
clear_active_eval2( exec, attr );
}
- /* _NEW_PROGRAM */
- if (ctx->VertexProgram._Enabled) {
- for (attr = 0; attr < VBO_ATTRIB_FIRST_MATERIAL; attr++) {
- /* _NEW_EVAL */
- if (ctx->Eval.Map1Attrib[attr])
- set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
-
- if (ctx->Eval.Map2Attrib[attr])
- set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
- }
- }
-
if (ctx->Eval.Map1Color4)
set_active_eval1( exec, VBO_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 );
@@ -125,6 +117,23 @@ void vbo_exec_eval_update( struct vbo_exec_context *exec )
else if (ctx->Eval.Map2Vertex3)
set_active_eval2( exec, VBO_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 );
+ /* _NEW_PROGRAM */
+ if (ctx->VertexProgram._Enabled) {
+ /* These are the 16 evaluators which GL_NV_vertex_program defines.
+ * They alias and override the conventional vertex attributs.
+ */
+ for (attr = 0; attr < 16; attr++) {
+ /* _NEW_EVAL */
+ assert(attr < Elements(ctx->Eval.Map1Attrib));
+ if (ctx->Eval.Map1Attrib[attr])
+ set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
+
+ assert(attr < Elements(ctx->Eval.Map2Attrib));
+ if (ctx->Eval.Map2Attrib[attr])
+ set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
+ }
+ }
+
exec->eval.recalculate_maps = 0;
}
diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c
index 3bf7ef580..55a82ee36 100644
--- a/mesalib/src/mesa/vbo/vbo_rebase.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index 1771510d8..3f86c68b2 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_split.c b/mesalib/src/mesa/vbo/vbo_split.c
index 58e879628..c445acca7 100644
--- a/mesalib/src/mesa/vbo/vbo_split.c
+++ b/mesalib/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/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c
index 8ec180d55..c45190b9d 100644
--- a/mesalib/src/mesa/vbo/vbo_split_copy.c
+++ b/mesalib/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;
+
+ 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;
+ }
- memset(&copy, 0, sizeof(copy));
+ memset(&copy, 0, sizeof(copy));
- /* 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;
+ /* Require indexed primitives:
+ */
+ assert(ib);
- /* Clear the vertex cache:
- */
- for (i = 0; i < ELT_TABLE_SIZE; i++)
- copy.vert_cache[i].in = ~0;
+ 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(&copy);
- replay_elts(&copy);
- replay_finish(&copy);
+ /* Clear the vertex cache:
+ */
+ for (i = 0; i < ELT_TABLE_SIZE; i++)
+ copy.vert_cache[i].in = ~0;
+
+ replay_init(&copy);
+ replay_elts(&copy);
+ replay_finish(&copy);
+ }
}