Browse Source

Make sure vbo's are mapped before accessing their contents in

api_arrayelt.c.  Reported by Haihao Xiang.
tags/mesa_6_5_2
Keith Whitwell 19 years ago
parent
commit
b979479721

+ 8
- 0
src/mesa/drivers/dri/i965/brw_save_api.c View File

@@ -855,10 +855,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
return;

_ae_map_vbos( ctx );

brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );
for (i = 0; i < count; i++)
CALL_ArrayElement(GET_DISPATCH(), (start + i));
CALL_End(GET_DISPATCH(), ());

_ae_unmap_vbos( ctx );
}

/* Could do better by copying the arrays and element list intact and
@@ -873,6 +877,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
return;

_ae_map_vbos( ctx );

brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );

switch (type) {
@@ -894,6 +900,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
}

CALL_End(GET_DISPATCH(), ());

_ae_unmap_vbos( ctx );
}

static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,

+ 89
- 6
src/mesa/main/api_arrayelt.c View File

@@ -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;
}

+ 5
- 0
src/mesa/main/api_arrayelt.h View File

@@ -34,4 +34,9 @@ extern void _ae_destroy_context( GLcontext *ctx );
extern void _ae_invalidate_state( GLcontext *ctx, GLuint new_state );
extern void GLAPIENTRY _ae_loopback_array_elt( GLint elt );

/* May optionally be called before a batch of element calls:
*/
extern void _ae_map_vbos( GLcontext *ctx );
extern void _ae_unmap_vbos( GLcontext *ctx );

#endif

+ 8
- 0
src/mesa/tnl/t_save_api.c View File

@@ -1413,10 +1413,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
return;

_ae_map_vbos( ctx );

_save_NotifyBegin( ctx, mode | PRIM_WEAK );
for (i = 0; i < count; i++)
CALL_ArrayElement(GET_DISPATCH(), (start + i));
CALL_End(GET_DISPATCH(), ());

_ae_unmap_vbos( ctx );
}


@@ -1429,6 +1433,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
return;

_ae_map_vbos( ctx );

_save_NotifyBegin( ctx, mode | PRIM_WEAK );

switch (type) {
@@ -1450,6 +1456,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
}

CALL_End(GET_DISPATCH(), ());

_ae_unmap_vbos( ctx );
}

static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,

Loading…
Cancel
Save