X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fbufferobj.c;h=9ad2dccc1243683d76f2e58a7322f2e54429a911;hb=aac367f48afc62176faf67aa6f329fbeae2004b4;hp=1d0f4b40679654efbe668ed62e30df5c249794ff;hpb=4d12a05e6c11ca8d7325503131b2594dfe304164;p=mesa.git diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 1d0f4b40679..9ad2dccc124 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.1 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -44,13 +44,11 @@ * \param ctx GL context * \param target Buffer object target to be retrieved. Currently this must * be either \c GL_ARRAY_BUFFER or \c GL_ELEMENT_ARRAY_BUFFER. - * \param caller Name of calling function for recording errors. * \return A pointer to the buffer object bound to \c target in the - * specified context or \c NULL if \c target is invalid or no - * buffer object is bound. + * specified context or \c NULL if \c target is invalid. */ static INLINE struct gl_buffer_object * -buffer_object_get_target(GLcontext *ctx, GLenum target, const char *caller) +get_buffer(GLcontext *ctx, GLenum target) { struct gl_buffer_object * bufObj = NULL; @@ -68,12 +66,12 @@ buffer_object_get_target(GLcontext *ctx, GLenum target, const char *caller) bufObj = ctx->Unpack.BufferObj; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(target)", caller); + /* error must be recorded by caller */ return NULL; } - if (bufObj->Name == 0) - return NULL; + /* bufObj should point to NullBufferObj or a user-created buffer object */ + ASSERT(bufObj); return bufObj; } @@ -112,17 +110,20 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target, return NULL; } - bufObj = buffer_object_get_target(ctx, target, caller); - if (!bufObj || bufObj->Name == 0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller); return NULL; } - - if ((GLuint) (offset + size) > bufObj->Size) { + if (bufObj->Name == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + return NULL; + } + if (offset + size > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size + offset > buffer size)", caller); return NULL; } - if (bufObj->Pointer) { /* Buffer is currently mapped */ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); @@ -295,7 +296,10 @@ _mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, { (void) ctx; (void) target; - if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) { + /* this should have been caught in _mesa_BufferSubData() */ + ASSERT(size + offset <= bufObj->Size); + + if (bufObj->Data) { _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size ); } } @@ -335,9 +339,9 @@ _mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, /** * Fallback function called via ctx->Driver.MapBuffer(). * Hardware drivers that really implement buffer objects should never use - * function. + * this function. * - * The input parameters will have been already tested for errors. + * The function parameters will have been already tested for errors. * * \param ctx GL context. * \param target Buffer object target on which to operate. @@ -405,6 +409,101 @@ _mesa_init_buffer_objects( GLcontext *ctx ) ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj; } +/** + * Bind the specified target to buffer for the specified context. + */ +static void +bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer) +{ + struct gl_buffer_object *oldBufObj; + struct gl_buffer_object *newBufObj = NULL; + struct gl_buffer_object **bindTarget = NULL; + + switch (target) { + case GL_ARRAY_BUFFER_ARB: + bindTarget = &ctx->Array.ArrayBufferObj; + break; + case GL_ELEMENT_ARRAY_BUFFER_ARB: + bindTarget = &ctx->Array.ElementArrayBufferObj; + break; + case GL_PIXEL_PACK_BUFFER_EXT: + bindTarget = &ctx->Pack.BufferObj; + break; + case GL_PIXEL_UNPACK_BUFFER_EXT: + bindTarget = &ctx->Unpack.BufferObj; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)"); + return; + } + + /* Get pointer to old buffer object (to be unbound) */ + oldBufObj = get_buffer(ctx, target); + if (oldBufObj && oldBufObj->Name == buffer) + return; /* rebinding the same buffer object- no change */ + + /* + * Get pointer to new buffer object (newBufObj) + */ + if (buffer == 0) { + /* The spec says there's not a buffer object named 0, but we use + * one internally because it simplifies things. + */ + newBufObj = ctx->Array.NullBufferObj; + } + else { + /* non-default buffer object */ + newBufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!newBufObj) { + /* if this is a new buffer object id, allocate a buffer object now */ + ASSERT(ctx->Driver.NewBufferObject); + newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target); + if (!newBufObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); + return; + } + _mesa_save_buffer_object(ctx, newBufObj); + } + } + + /* Make new binding */ + *bindTarget = newBufObj; + newBufObj->RefCount++; + + /* Pass BindBuffer call to device driver */ + if (ctx->Driver.BindBuffer && newBufObj) + ctx->Driver.BindBuffer( ctx, target, newBufObj ); + + /* decr ref count on old buffer obj, delete if needed */ + if (oldBufObj) { + oldBufObj->RefCount--; + assert(oldBufObj->RefCount >= 0); + if (oldBufObj->RefCount == 0) { + assert(oldBufObj->Name != 0); + ASSERT(ctx->Driver.DeleteBuffer); + ctx->Driver.DeleteBuffer( ctx, oldBufObj ); + } + } +} + + +/** + * Update the default buffer objects in the given context to reference those + * specified in the shared state and release those referencing the old + * shared state. + */ +void +_mesa_update_default_objects_buffer_objects(GLcontext *ctx) +{ + /* Bind the NullBufferObj to remove references to those + * in the shared context hash table. + */ + bind_buffer_object( ctx, GL_ARRAY_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_PIXEL_PACK_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_PIXEL_UNPACK_BUFFER_ARB, 0); +} + /** * When we're about to read pixel data out of a PBO (via glDrawPixels, @@ -489,70 +588,9 @@ void GLAPIENTRY _mesa_BindBufferARB(GLenum target, GLuint buffer) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object *oldBufObj; - struct gl_buffer_object *newBufObj = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); - oldBufObj = buffer_object_get_target( ctx, target, "BindBufferARB" ); - if (oldBufObj && oldBufObj->Name == buffer) - return; /* rebinding the same buffer object- no change */ - - /* - * Get pointer to new buffer object (newBufObj) - */ - if (buffer == 0) { - /* The spec says there's not a buffer object named 0, but we use - * one internally because it simplifies things. - */ - newBufObj = ctx->Array.NullBufferObj; - } - else { - /* non-default buffer object */ - newBufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!newBufObj) { - /* if this is a new buffer object id, allocate a buffer object now */ - ASSERT(ctx->Driver.NewBufferObject); - newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target); - if (!newBufObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); - return; - } - _mesa_save_buffer_object(ctx, newBufObj); - } - newBufObj->RefCount++; - } - - switch (target) { - case GL_ARRAY_BUFFER_ARB: - ctx->Array.ArrayBufferObj = newBufObj; - break; - case GL_ELEMENT_ARRAY_BUFFER_ARB: - ctx->Array.ElementArrayBufferObj = newBufObj; - break; - case GL_PIXEL_PACK_BUFFER_EXT: - ctx->Pack.BufferObj = newBufObj; - break; - case GL_PIXEL_UNPACK_BUFFER_EXT: - ctx->Unpack.BufferObj = newBufObj; - break; - default: - _mesa_problem(ctx, "Bad target in _mesa_BindBufferARB"); - return; - } - - /* Pass BindBuffer call to device driver */ - if (ctx->Driver.BindBuffer && newBufObj) - ctx->Driver.BindBuffer( ctx, target, newBufObj ); - - if (oldBufObj) { - oldBufObj->RefCount--; - assert(oldBufObj->RefCount >= 0); - if (oldBufObj->RefCount == 0) { - assert(oldBufObj->Name != 0); - ASSERT(ctx->Driver.DeleteBuffer); - ctx->Driver.DeleteBuffer( ctx, oldBufObj ); - } - } + bind_buffer_object(ctx, target, buffer); } @@ -648,9 +686,9 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 ); } - /* The ID is immediately freed for re-use */ - _mesa_remove_buffer_object(ctx, bufObj); - _mesa_unbind_buffer_object(ctx, bufObj); + /* The ID is immediately freed for re-use */ + _mesa_remove_buffer_object(ctx, bufObj); + _mesa_unbind_buffer_object(ctx, bufObj); } } @@ -759,8 +797,12 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, return; } - bufObj = buffer_object_get_target( ctx, target, "BufferDataARB" ); - if (!bufObj || bufObj->Name ==0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" ); + return; + } + if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB" ); return; } @@ -786,7 +828,7 @@ _mesa_BufferSubDataARB(GLenum target, GLintptrARB offset, ASSERT_OUTSIDE_BEGIN_END(ctx); bufObj = buffer_object_subdata_range_good( ctx, target, offset, size, - "BufferSubDataARB" ); + "glBufferSubDataARB" ); if (!bufObj) { /* error already recorded */ return; @@ -806,7 +848,7 @@ _mesa_GetBufferSubDataARB(GLenum target, GLintptrARB offset, ASSERT_OUTSIDE_BEGIN_END(ctx); bufObj = buffer_object_subdata_range_good( ctx, target, offset, size, - "GetBufferSubDataARB" ); + "glGetBufferSubDataARB" ); if (!bufObj) { /* error already recorded */ return; @@ -835,12 +877,15 @@ _mesa_MapBufferARB(GLenum target, GLenum access) return NULL; } - bufObj = buffer_object_get_target( ctx, target, "MapBufferARB" ); - if (!bufObj || bufObj->Name == 0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" ); + return NULL; + } + if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB" ); return NULL; } - if (bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)"); return NULL; @@ -866,12 +911,15 @@ _mesa_UnmapBufferARB(GLenum target) GLboolean status = GL_TRUE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - bufObj = buffer_object_get_target( ctx, target, "UnmapBufferARB" ); - if (!bufObj || bufObj->Name == 0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" ); + return GL_FALSE; + } + if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" ); return GL_FALSE; } - if (!bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB"); return GL_FALSE; @@ -895,8 +943,12 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params) struct gl_buffer_object *bufObj; ASSERT_OUTSIDE_BEGIN_END(ctx); - bufObj = buffer_object_get_target( ctx, target, "GetBufferParameterivARB" ); - if (!bufObj || bufObj->Name == 0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameterivARB(target)" ); + return; + } + if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" ); return; } @@ -933,8 +985,12 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params) return; } - bufObj = buffer_object_get_target( ctx, target, "GetBufferPointervARB" ); - if (!bufObj || bufObj->Name == 0) { + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" ); + return; + } + if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" ); return; }