diff options
Diffstat (limited to 'mesalib/src/mesa/main/bufferobj.c')
-rw-r--r-- | mesalib/src/mesa/main/bufferobj.c | 553 |
1 files changed, 497 insertions, 56 deletions
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 52c4995b0..71d1514fe 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -37,6 +37,8 @@ #include "image.h" #include "context.h" #include "bufferobj.h" +#include "fbobject.h" +#include "texobj.h" /* Debug flags */ @@ -208,13 +210,14 @@ _mesa_delete_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) (void) ctx; if (bufObj->Data) - _mesa_free(bufObj->Data); + free(bufObj->Data); /* assign strange values here to help w/ debugging */ bufObj->RefCount = -1000; bufObj->Name = ~0; - _mesa_free(bufObj); + _glthread_DESTROY_MUTEX(bufObj->Mutex); + free(bufObj); } @@ -235,7 +238,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, GLboolean deleteFlag = GL_FALSE; struct gl_buffer_object *oldObj = *ptr; - /*_glthread_LOCK_MUTEX(oldObj->Mutex);*/ + _glthread_LOCK_MUTEX(oldObj->Mutex); ASSERT(oldObj->RefCount > 0); oldObj->RefCount--; #if 0 @@ -243,7 +246,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, (void *) oldObj, oldObj->Name, oldObj->RefCount); #endif deleteFlag = (oldObj->RefCount == 0); - /*_glthread_UNLOCK_MUTEX(oldObj->Mutex);*/ + _glthread_UNLOCK_MUTEX(oldObj->Mutex); if (deleteFlag) { @@ -265,7 +268,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, if (bufObj) { /* reference new buffer */ - /*_glthread_LOCK_MUTEX(tex->Mutex);*/ + _glthread_LOCK_MUTEX(bufObj->Mutex); if (bufObj->RefCount == 0) { /* this buffer's being deleted (look just above) */ /* Not sure this can every really happen. Warn if it does. */ @@ -280,7 +283,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, #endif *ptr = bufObj; } - /*_glthread_UNLOCK_MUTEX(tex->Mutex);*/ + _glthread_UNLOCK_MUTEX(bufObj->Mutex); } } @@ -294,7 +297,8 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj, { (void) target; - _mesa_bzero(obj, sizeof(struct gl_buffer_object)); + memset(obj, 0, sizeof(struct gl_buffer_object)); + _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Usage = GL_STATIC_DRAW_ARB; @@ -337,7 +341,7 @@ _mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size, bufObj->Usage = usage; if (data) { - _mesa_memcpy( bufObj->Data, data, size ); + memcpy( bufObj->Data, data, size ); } return GL_TRUE; @@ -376,7 +380,7 @@ _mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, ASSERT(size + offset <= bufObj->Size); if (bufObj->Data) { - _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size ); + memcpy( (GLubyte *) bufObj->Data + offset, data, size ); } } @@ -406,7 +410,7 @@ _mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, (void) ctx; (void) target; if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) { - _mesa_memcpy( data, (GLubyte *) bufObj->Data + offset, size ); + memcpy( data, (GLubyte *) bufObj->Data + offset, size ); } } @@ -528,7 +532,7 @@ _mesa_copy_buffer_subdata(GLcontext *ctx, GL_WRITE_ONLY, dst); if (srcPtr && dstPtr) - _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size); + memcpy(dstPtr + writeOffset, srcPtr + readOffset, size); ctx->Driver.UnmapBuffer(ctx, GL_COPY_READ_BUFFER, src); ctx->Driver.UnmapBuffer(ctx, GL_COPY_WRITE_BUFFER, dst); @@ -554,6 +558,17 @@ _mesa_init_buffer_objects( GLcontext *ctx ) } +void +_mesa_free_buffer_objects( GLcontext *ctx ) +{ + _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); + _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL); + + _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL); + _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL); +} + + /** * Bind the specified target to buffer for the specified context. * Called by glBindBuffer() and other functions. @@ -1104,20 +1119,20 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, } switch (usage) { - case GL_STREAM_DRAW_ARB: - case GL_STREAM_READ_ARB: - case GL_STREAM_COPY_ARB: - case GL_STATIC_DRAW_ARB: - case GL_STATIC_READ_ARB: - case GL_STATIC_COPY_ARB: - case GL_DYNAMIC_DRAW_ARB: - case GL_DYNAMIC_READ_ARB: - case GL_DYNAMIC_COPY_ARB: - /* OK */ - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(usage)"); - return; + case GL_STREAM_DRAW_ARB: + case GL_STREAM_READ_ARB: + case GL_STREAM_COPY_ARB: + case GL_STATIC_DRAW_ARB: + case GL_STATIC_READ_ARB: + case GL_STATIC_COPY_ARB: + case GL_DYNAMIC_DRAW_ARB: + case GL_DYNAMIC_READ_ARB: + case GL_DYNAMIC_COPY_ARB: + /* OK */ + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(usage)"); + return; } bufObj = get_buffer(ctx, target); @@ -1142,7 +1157,7 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, bufObj->Written = GL_TRUE; #ifdef VBO_DEBUG - _mesa_printf("glBufferDataARB(%u, sz %ld, from %p, usage 0x%x)\n", + printf("glBufferDataARB(%u, sz %ld, from %p, usage 0x%x)\n", bufObj->Name, size, data, usage); #endif @@ -1210,18 +1225,18 @@ _mesa_MapBufferARB(GLenum target, GLenum access) ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); switch (access) { - case GL_READ_ONLY_ARB: - accessFlags = GL_MAP_READ_BIT; - break; - case GL_WRITE_ONLY_ARB: - accessFlags = GL_MAP_WRITE_BIT; - break; - case GL_READ_WRITE_ARB: - accessFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)"); - return NULL; + case GL_READ_ONLY_ARB: + accessFlags = GL_MAP_READ_BIT; + break; + case GL_WRITE_ONLY_ARB: + accessFlags = GL_MAP_WRITE_BIT; + break; + case GL_READ_WRITE_ARB: + accessFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)"); + return NULL; } bufObj = get_buffer(ctx, target); @@ -1259,8 +1274,8 @@ _mesa_MapBufferARB(GLenum target, GLenum access) bufObj->Written = GL_TRUE; #ifdef VBO_DEBUG - _mesa_printf("glMapBufferARB(%u, sz %ld, access 0x%x)\n", - bufObj->Name, bufObj->Size, access); + printf("glMapBufferARB(%u, sz %ld, access 0x%x)\n", + bufObj->Name, bufObj->Size, access); if (access == GL_WRITE_ONLY_ARB) { GLuint i; GLubyte *b = (GLubyte *) bufObj->Pointer; @@ -1336,7 +1351,7 @@ _mesa_UnmapBufferARB(GLenum target) } } if (unchanged) { - _mesa_printf("glUnmapBufferARB(%u): %u of %ld unchanged, starting at %d\n", + printf("glUnmapBufferARB(%u): %u of %ld unchanged, starting at %d\n", bufObj->Name, unchanged, bufObj->Size, pos); } } @@ -1370,21 +1385,63 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params) } switch (pname) { - case GL_BUFFER_SIZE_ARB: - *params = (GLint) bufObj->Size; - break; - case GL_BUFFER_USAGE_ARB: - *params = bufObj->Usage; - break; - case GL_BUFFER_ACCESS_ARB: - *params = simplified_access_mode(bufObj->AccessFlags); - break; - case GL_BUFFER_MAPPED_ARB: - *params = _mesa_bufferobj_mapped(bufObj); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)"); - return; + case GL_BUFFER_SIZE_ARB: + *params = (GLint) bufObj->Size; + break; + case GL_BUFFER_USAGE_ARB: + *params = bufObj->Usage; + break; + case GL_BUFFER_ACCESS_ARB: + *params = simplified_access_mode(bufObj->AccessFlags); + break; + case GL_BUFFER_MAPPED_ARB: + *params = _mesa_bufferobj_mapped(bufObj); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)"); + return; + } +} + + +/** + * New in GL 3.2 + * This is pretty much a duplicate of GetBufferParameteriv() but the + * GL_BUFFER_SIZE_ARB attribute will be 64-bits on a 64-bit system. + */ +void GLAPIENTRY +_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + bufObj = get_buffer(ctx, target); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameteri64v(target)" ); + return; + } + if (!_mesa_is_bufferobj(bufObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameteri64v" ); + return; + } + + switch (pname) { + case GL_BUFFER_SIZE_ARB: + *params = bufObj->Size; + break; + case GL_BUFFER_USAGE_ARB: + *params = bufObj->Usage; + break; + case GL_BUFFER_ACCESS_ARB: + *params = simplified_access_mode(bufObj->AccessFlags); + break; + case GL_BUFFER_MAPPED_ARB: + *params = _mesa_bufferobj_mapped(bufObj); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameteri64v(pname)"); + return; } } @@ -1655,3 +1712,387 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) if (ctx->Driver.FlushMappedBufferRange) ctx->Driver.FlushMappedBufferRange(ctx, target, offset, length, bufObj); } + + +#if FEATURE_APPLE_object_purgeable +static GLenum +_mesa_BufferObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_buffer_object *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_bufferobj(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectPurgeable(name = 0x%x)", name); + return 0; + } + if (!_mesa_is_bufferobj(bufObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glObjectPurgeable(buffer 0)" ); + return 0; + } + + if (bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectPurgeable(name = 0x%x) is already purgeable", name); + return GL_VOLATILE_APPLE; + } + + bufObj->Purgeable = GL_TRUE; + + retval = GL_VOLATILE_APPLE; + if (ctx->Driver.BufferObjectPurgeable) + retval = ctx->Driver.BufferObjectPurgeable(ctx, bufObj, option); + + return retval; +} + + +static GLenum +_mesa_RenderObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_renderbuffer *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_renderbuffer(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return 0; + } + + if (bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectPurgeable(name = 0x%x) is already purgeable", name); + return GL_VOLATILE_APPLE; + } + + bufObj->Purgeable = GL_TRUE; + + retval = GL_VOLATILE_APPLE; + if (ctx->Driver.RenderObjectPurgeable) + retval = ctx->Driver.RenderObjectPurgeable(ctx, bufObj, option); + + return retval; +} + + +static GLenum +_mesa_TextureObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_texture_object *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_texture(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectPurgeable(name = 0x%x)", name); + return 0; + } + + if (bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectPurgeable(name = 0x%x) is already purgeable", name); + return GL_VOLATILE_APPLE; + } + + bufObj->Purgeable = GL_TRUE; + + retval = GL_VOLATILE_APPLE; + if (ctx->Driver.TextureObjectPurgeable) + retval = ctx->Driver.TextureObjectPurgeable(ctx, bufObj, option); + + return retval; +} + + +GLenum GLAPIENTRY +_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) +{ + GLenum retval; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + if (name == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectPurgeable(name = 0x%x)", name); + return 0; + } + + switch (option) { + case GL_VOLATILE_APPLE: + case GL_RELEASED_APPLE: + /* legal */ + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glObjectPurgeable(name = 0x%x) invalid option: %d", + name, option); + return 0; + } + + switch (objectType) { + case GL_TEXTURE: + retval = _mesa_TextureObjectPurgeable (ctx, name, option); + break; + case GL_RENDERBUFFER_EXT: + retval = _mesa_RenderObjectPurgeable (ctx, name, option); + break; + case GL_BUFFER_OBJECT_APPLE: + retval = _mesa_BufferObjectPurgeable (ctx, name, option); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glObjectPurgeable(name = 0x%x) invalid type: %d", + name, objectType); + return 0; + } + + /* In strict conformance to the spec, we must only return VOLATILE when + * when passed the VOLATILE option. Madness. + * + * XXX First fix the spec, then fix me. + */ + return option == GL_VOLATILE_APPLE ? GL_VOLATILE_APPLE : retval; +} + + +static GLenum +_mesa_BufferObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_buffer_object *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_bufferobj(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return 0; + } + + if (! bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectUnpurgeable(name = 0x%x) object is " + " already \"unpurged\"", name); + return 0; + } + + bufObj->Purgeable = GL_FALSE; + + retval = GL_RETAINED_APPLE; + if (ctx->Driver.BufferObjectUnpurgeable) + retval = ctx->Driver.BufferObjectUnpurgeable(ctx, bufObj, option); + + return retval; +} + + +static GLenum +_mesa_RenderObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_renderbuffer *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_renderbuffer(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return 0; + } + + if (! bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectUnpurgeable(name = 0x%x) object is " + " already \"unpurged\"", name); + return 0; + } + + bufObj->Purgeable = GL_FALSE; + + retval = GL_RETAINED_APPLE; + if (ctx->Driver.RenderObjectUnpurgeable) + retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option); + + return option; +} + + +static GLenum +_mesa_TextureObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option) +{ + struct gl_texture_object *bufObj; + GLenum retval; + + bufObj = _mesa_lookup_texture(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return 0; + } + + if (! bufObj->Purgeable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glObjectUnpurgeable(name = 0x%x) object is" + " already \"unpurged\"", name); + return 0; + } + + bufObj->Purgeable = GL_FALSE; + + retval = GL_RETAINED_APPLE; + if (ctx->Driver.TextureObjectUnpurgeable) + retval = ctx->Driver.TextureObjectUnpurgeable(ctx, bufObj, option); + + return retval; +} + + +GLenum GLAPIENTRY +_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + if (name == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return 0; + } + + switch (option) { + case GL_RETAINED_APPLE: + case GL_UNDEFINED_APPLE: + /* legal */ + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glObjectUnpurgeable(name = 0x%x) invalid option: %d", + name, option); + return 0; + } + + switch (objectType) { + case GL_BUFFER_OBJECT_APPLE: + return _mesa_BufferObjectUnpurgeable(ctx, name, option); + case GL_TEXTURE: + return _mesa_TextureObjectUnpurgeable(ctx, name, option); + case GL_RENDERBUFFER_EXT: + return _mesa_RenderObjectUnpurgeable(ctx, name, option); + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glObjectUnpurgeable(name = 0x%x) invalid type: %d", + name, objectType); + return 0; + } +} + + +static void +_mesa_GetBufferObjectParameterivAPPLE(GLcontext *ctx, GLuint name, + GLenum pname, GLint* params) +{ + struct gl_buffer_object *bufObj; + + bufObj = _mesa_lookup_bufferobj(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetObjectParameteriv(name = 0x%x) invalid object", name); + return; + } + + switch (pname) { + case GL_PURGEABLE_APPLE: + *params = bufObj->Purgeable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", + name, pname); + break; + } +} + + +static void +_mesa_GetRenderObjectParameterivAPPLE(GLcontext *ctx, GLuint name, + GLenum pname, GLint* params) +{ + struct gl_renderbuffer *bufObj; + + bufObj = _mesa_lookup_renderbuffer(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return; + } + + switch (pname) { + case GL_PURGEABLE_APPLE: + *params = bufObj->Purgeable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", + name, pname); + break; + } +} + + +static void +_mesa_GetTextureObjectParameterivAPPLE(GLcontext *ctx, GLuint name, + GLenum pname, GLint* params) +{ + struct gl_texture_object *bufObj; + + bufObj = _mesa_lookup_texture(ctx, name); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glObjectUnpurgeable(name = 0x%x)", name); + return; + } + + switch (pname) { + case GL_PURGEABLE_APPLE: + *params = bufObj->Purgeable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", + name, pname); + break; + } +} + + +void GLAPIENTRY +_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, + GLint* params) +{ + GET_CURRENT_CONTEXT(ctx); + + if (name == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetObjectParameteriv(name = 0x%x)", name); + return; + } + + switch (objectType) { + case GL_TEXTURE: + _mesa_GetTextureObjectParameterivAPPLE (ctx, name, pname, params); + break; + case GL_BUFFER_OBJECT_APPLE: + _mesa_GetBufferObjectParameterivAPPLE (ctx, name, pname, params); + break; + case GL_RENDERBUFFER_EXT: + _mesa_GetRenderObjectParameterivAPPLE (ctx, name, pname, params); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetObjectParameteriv(name = 0x%x) invalid type: %d", + name, objectType); + } +} + +#endif /* FEATURE_APPLE_object_purgeable */ |