mesa: Fix null buffer object reference counting.
Always use _mesa_reference_buffer_object, and never call ctx->Driver.DeleteBuffer() directly to prevent dangling pointers to the null buffer object. This fixes crash/assertions in sharedtex_mt and Autodesk Mudbox.
This commit is contained in:
@@ -93,12 +93,14 @@ _mesa_alloc_shared_state(GLcontext *ctx)
|
|||||||
shared->BufferObjects = _mesa_NewHashTable();
|
shared->BufferObjects = _mesa_NewHashTable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate the default buffer object and set refcount so high that
|
/* Allocate the default buffer object */
|
||||||
* it never gets deleted.
|
|
||||||
* XXX with recent/improved refcounting this may not longer be needed.
|
|
||||||
*/
|
|
||||||
shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
|
shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
|
||||||
|
#ifndef DEBUG
|
||||||
|
/* Set refcount so high that it never gets deleted.
|
||||||
|
* XXX with recent/improved refcounting this should be no longer be needed.
|
||||||
|
*/
|
||||||
shared->NullBufferObj->RefCount = 1000 * 1000 * 1000;
|
shared->NullBufferObj->RefCount = 1000 * 1000 * 1000;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create default texture objects */
|
/* Create default texture objects */
|
||||||
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
||||||
@@ -202,7 +204,7 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData)
|
|||||||
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
|
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
|
||||||
bufObj->Pointer = NULL;
|
bufObj->Pointer = NULL;
|
||||||
}
|
}
|
||||||
ctx->Driver.DeleteBuffer(ctx, bufObj);
|
_mesa_reference_buffer_object(ctx, &bufObj, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -335,7 +337,7 @@ free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FEATURE_ARB_vertex_buffer_object
|
#if FEATURE_ARB_vertex_buffer_object
|
||||||
ctx->Driver.DeleteBuffer(ctx, shared->NullBufferObj);
|
_mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FEATURE_ARB_sync
|
#if FEATURE_ARB_sync
|
||||||
|
@@ -58,8 +58,19 @@ void vbo_save_init( GLcontext *ctx )
|
|||||||
|
|
||||||
{
|
{
|
||||||
struct gl_client_array *arrays = save->arrays;
|
struct gl_client_array *arrays = save->arrays;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0]));
|
memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0]));
|
||||||
memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
|
memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i) {
|
||||||
|
arrays[i ].BufferObj = NULL;
|
||||||
|
arrays[i + 16].BufferObj = NULL;
|
||||||
|
_mesa_reference_buffer_object(ctx, &arrays[i ].BufferObj,
|
||||||
|
vbo->legacy_currval[i].BufferObj);
|
||||||
|
_mesa_reference_buffer_object(ctx, &arrays[i + 16].BufferObj,
|
||||||
|
vbo->generic_currval[i].BufferObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
|
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
|
||||||
|
Reference in New Issue
Block a user