diff options
-rw-r--r-- | src/mesa/main/bufferobj.c | 13 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 1 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 431eafd3879..4c77397d9dc 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -571,7 +571,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer) /* Get pointer to old buffer object (to be unbound) */ oldBufObj = *bindTarget; - if (oldBufObj && oldBufObj->Name == buffer) + if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending) return; /* rebinding the same buffer object- no change */ /* @@ -773,6 +773,17 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]); + /* Make sure we do not run into the classic ABA problem on bind. + * We don't want to allow re-binding a buffer object that's been + * "deleted" by glDeleteBuffers(). + * + * The explicit rebinding to the default object in the current context + * prevents the above in the current context, but another context + * sharing the same objects might suffer from this problem. + * The alternative would be to do the hash lookup in any case on bind + * which would introduce more runtime overhead than this. + */ + bufObj->DeletePending = GL_TRUE; _mesa_reference_buffer_object(ctx, &bufObj, NULL); } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d02bc167643..719dff3af2e 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1530,6 +1530,7 @@ struct gl_buffer_object GLintptr Offset; /**< Mapped offset */ GLsizeiptr Length; /**< Mapped length */ /*@}*/ + GLboolean DeletePending; /**< true if buffer object is removed from the hash */ GLboolean Written; /**< Ever written to? (for debugging) */ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ }; |