summaryrefslogtreecommitdiff
path: root/src/mesa/main/api_arrayelt.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2006-11-16 02:33:38 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2006-11-16 02:33:38 +0000
commitb97947972193b6b004a0ee49da31146230d43dd8 (patch)
treedad15e47c8ceb15776e3295f2a25c097f0d60a45 /src/mesa/main/api_arrayelt.c
parent82eeb62a31ec96a55ba2349397b8e8549e07a6bb (diff)
Make sure vbo's are mapped before accessing their contents in
api_arrayelt.c. Reported by Haihao Xiang.
Diffstat (limited to 'src/mesa/main/api_arrayelt.c')
-rw-r--r--src/mesa/main/api_arrayelt.c95
1 files changed, 89 insertions, 6 deletions
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
index dda659bbc3..3c26c2c590 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -53,6 +53,11 @@ typedef struct {
AEarray arrays[32];
AEattrib attribs[VERT_ATTRIB_MAX + 1];
GLuint NewState;
+
+ struct gl_buffer_object *vbo[VERT_ATTRIB_MAX];
+ GLuint nr_vbos;
+ GLboolean mapped_vbos;
+
} AEcontext;
#define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
@@ -1063,6 +1068,18 @@ void _ae_destroy_context( GLcontext *ctx )
}
}
+static void check_vbo( AEcontext *actx,
+ struct gl_buffer_object *vbo )
+{
+ if (vbo->Name && !vbo->Pointer) {
+ GLuint i;
+ for (i = 0; i < actx->nr_vbos; i++)
+ if (actx->vbo[i] == vbo)
+ return;
+ actx->vbo[actx->nr_vbos++] = vbo;
+ }
+}
+
/**
* Make a list of per-vertex functions to call for each glArrayElement call.
@@ -1081,31 +1098,37 @@ static void _ae_update_state( GLcontext *ctx )
if (ctx->Array.ArrayObj->Index.Enabled) {
aa->array = &ctx->Array.ArrayObj->Index;
aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
if (ctx->Array.ArrayObj->EdgeFlag.Enabled) {
aa->array = &ctx->Array.ArrayObj->EdgeFlag;
aa->offset = _gloffset_EdgeFlagv;
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
if (ctx->Array.ArrayObj->Normal.Enabled) {
aa->array = &ctx->Array.ArrayObj->Normal;
aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
if (ctx->Array.ArrayObj->Color.Enabled) {
aa->array = &ctx->Array.ArrayObj->Color;
aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
if (ctx->Array.ArrayObj->SecondaryColor.Enabled) {
aa->array = &ctx->Array.ArrayObj->SecondaryColor;
aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
if (ctx->Array.ArrayObj->FogCoord.Enabled) {
aa->array = &ctx->Array.ArrayObj->FogCoord;
aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
@@ -1120,11 +1143,12 @@ static void _ae_update_state( GLcontext *ctx )
[at->array->Size-1]
[TYPE_IDX(at->array->Type)];
at->index = VERT_ATTRIB_TEX0 + i;
+ check_vbo(actx, aa->array->BufferObj);
at++;
}
}
- /* generic vertex attribute arrays */
+ /* generic vertex attribute arrays */
for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */
struct gl_client_array *attribArray = &ctx->Array.ArrayObj->VertexAttrib[i];
if (attribArray->Enabled) {
@@ -1146,6 +1170,7 @@ static void _ae_update_state( GLcontext *ctx )
[TYPE_IDX(at->array->Type)];
}
at->index = i;
+ check_vbo(actx, aa->array->BufferObj);
at++;
}
}
@@ -1158,14 +1183,18 @@ static void _ae_update_state( GLcontext *ctx )
aa->array = &ctx->Array.ArrayObj->VertexAttrib[0];
assert(aa->array->Size >= 2); /* XXX fix someday? */
aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
else if (ctx->Array.ArrayObj->Vertex.Enabled) {
aa->array = &ctx->Array.ArrayObj->Vertex;
aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ check_vbo(actx, aa->array->BufferObj);
aa++;
}
+ check_vbo(actx, ctx->Array.ElementArrayBufferObj);
+
ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
ASSERT(aa - actx->arrays < 32);
at->func = NULL; /* terminate the list */
@@ -1174,6 +1203,45 @@ static void _ae_update_state( GLcontext *ctx )
actx->NewState = 0;
}
+void _ae_map_vbos( GLcontext *ctx )
+{
+ AEcontext *actx = AE_CONTEXT(ctx);
+ GLuint i;
+
+ if (actx->mapped_vbos)
+ return;
+
+ if (actx->NewState)
+ _ae_update_state(ctx);
+
+ for (i = 0; i < actx->nr_vbos; i++)
+ ctx->Driver.MapBuffer(ctx,
+ GL_ARRAY_BUFFER_ARB,
+ GL_DYNAMIC_DRAW_ARB,
+ actx->vbo[i]);
+
+ actx->mapped_vbos = GL_TRUE;
+}
+
+void _ae_unmap_vbos( GLcontext *ctx )
+{
+ AEcontext *actx = AE_CONTEXT(ctx);
+ GLuint i;
+
+ if (actx->mapped_vbos)
+ return;
+
+ if (actx->NewState)
+ _ae_update_state(ctx);
+
+ for (i = 0; i < actx->nr_vbos; i++)
+ ctx->Driver.UnmapBuffer(ctx,
+ GL_ARRAY_BUFFER_ARB,
+ actx->vbo[i]);
+
+ actx->mapped_vbos = GL_TRUE;
+}
+
/**
* Called via glArrayElement() and glDrawArrays().
@@ -1188,15 +1256,24 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
const AEarray *aa;
const AEattrib *at;
const struct _glapi_table * const disp = GET_DISPATCH();
+ GLboolean do_map;
-
- if (actx->NewState)
+ if (actx->NewState) {
+ assert(!actx->mapped_vbos);
_ae_update_state( ctx );
+ }
+ do_map = actx->nr_vbos && !actx->mapped_vbos;
+
+ /*
+ */
+ if (do_map)
+ _ae_map_vbos(ctx);
+
/* generic attributes */
for (at = actx->attribs; at->func; at++) {
const GLubyte *src
- = ADD_POINTERS(at->array->BufferObj->Data, at->array->Ptr)
+ = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)
+ elt * at->array->StrideB;
at->func( at->index, src );
}
@@ -1204,15 +1281,21 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
/* conventional arrays */
for (aa = actx->arrays; aa->offset != -1 ; aa++) {
const GLubyte *src
- = ADD_POINTERS(aa->array->BufferObj->Data, aa->array->Ptr)
+ = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)
+ elt * aa->array->StrideB;
CALL_by_offset( disp, (array_func), aa->offset,
((const void *) src) );
}
+
+ if (do_map)
+ _ae_unmap_vbos(ctx);
}
void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
{
- AE_CONTEXT(ctx)->NewState |= new_state;
+ AEcontext *actx = AE_CONTEXT(ctx);
+
+ assert(!actx->mapped_vbos);
+ actx->NewState |= new_state;
}