From: Brian Paul Date: Tue, 1 Apr 2003 16:41:50 +0000 (+0000) Subject: New device driver hooks for texture object and texture image creation to X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a3f137094cd965d27e1b088499dd609b81a91906;p=mesa.git New device driver hooks for texture object and texture image creation to allow drivers to implement C++-like inheritance via containment. Lots of assorted clean-ups related to texture objects. --- diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 0141bf1a34e..ba7500fd8d9 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.101 2003/03/04 19:16:47 brianp Exp $ */ +/* $Id: osmesa.c,v 1.102 2003/04/01 16:41:57 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -47,6 +47,7 @@ #include "matrix.h" #include "mtypes.h" #include "texformat.h" +#include "texobj.h" #include "texstore.h" #include "array_cache/acache.h" #include "swrast/swrast.h" @@ -648,7 +649,7 @@ hook_in_driver_functions( GLcontext *ctx ) ctx->Driver.Accum = _swrast_Accum; ctx->Driver.Bitmap = _swrast_Bitmap; - ctx->Driver.Clear = clear; /* = _swrast_Clear */ + ctx->Driver.Clear = clear; /* uses _swrast_Clear */ ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; @@ -670,6 +671,9 @@ hook_in_driver_functions( GLcontext *ctx ) ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + ctx->Driver.NewTextureObject = _mesa_new_texture_object; + ctx->Driver.DeleteTexture = _mesa_delete_texture_object; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 230bee3e02e..3aa33a58f36 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,4 +1,4 @@ -/* $Id: xm_dd.c,v 1.45 2003/03/27 17:51:33 brianp Exp $ */ +/* $Id: xm_dd.c,v 1.46 2003/04/01 16:41:58 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -965,6 +965,9 @@ void xmesa_init_pointers( GLcontext *ctx ) ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.NewTextureObject = _mesa_new_texture_object; + ctx->Driver.DeleteTexture = _mesa_delete_texture_object; + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b9bbe651933..7c8befc0a80 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.194 2003/03/01 01:50:20 brianp Exp $ */ +/* $Id: context.c,v 1.195 2003/04/01 16:41:50 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -637,15 +637,14 @@ free_matrix_stack( struct matrix_stack *stack ) /* * Allocate and initialize a shared context state structure. */ -static struct gl_shared_state * -alloc_shared_state( void ) +static GLboolean +alloc_shared_state( GLcontext *ctx ) { - struct gl_shared_state *ss; - GLboolean outOfMemory; - - ss = CALLOC_STRUCT(gl_shared_state); + struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state); if (!ss) - return NULL; + return GL_FALSE; + + ctx->Shared = ss; _glthread_INIT_MUTEX(ss->Mutex); @@ -655,64 +654,66 @@ alloc_shared_state( void ) ss->Programs = _mesa_NewHashTable(); #endif - /* Default Texture objects */ - outOfMemory = GL_FALSE; + ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); + if (!ss->Default1D) + goto cleanup; - ss->Default1D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_1D); - if (!ss->Default1D) { - outOfMemory = GL_TRUE; - } + ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); + if (!ss->Default2D) + goto cleanup; - ss->Default2D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_2D); - if (!ss->Default2D) { - outOfMemory = GL_TRUE; - } + ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); + if (!ss->Default3D) + goto cleanup; - ss->Default3D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_3D); - if (!ss->Default3D) { - outOfMemory = GL_TRUE; - } + ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); + if (!ss->DefaultCubeMap) + goto cleanup; - ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0, - GL_TEXTURE_CUBE_MAP_ARB); - if (!ss->DefaultCubeMap) { - outOfMemory = GL_TRUE; - } + ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); + if (!ss->DefaultRect) + goto cleanup; - ss->DefaultRect = _mesa_alloc_texture_object(ss, 0, - GL_TEXTURE_RECTANGLE_NV); - if (!ss->DefaultRect) { - outOfMemory = GL_TRUE; - } +#if 0 + _mesa_save_texture_object(ctx, ss->Default1D); + _mesa_save_texture_object(ctx, ss->Default2D); + _mesa_save_texture_object(ctx, ss->Default3D); + _mesa_save_texture_object(ctx, ss->DefaultCubeMap); + _mesa_save_texture_object(ctx, ss->DefaultRect); +#endif + + /* Effectively bind the default textures to all texture units */ + ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; + ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; + ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; + ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; + ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; - if (!ss->DisplayList || !ss->TexObjects + return GL_TRUE; + + cleanup: + /* Ran out of memory at some point. Free everything and return NULL */ + if (ss->DisplayList) + _mesa_DeleteHashTable(ss->DisplayList); + if (ss->TexObjects) + _mesa_DeleteHashTable(ss->TexObjects); #if FEATURE_NV_vertex_program - || !ss->Programs + if (ss->Programs) + _mesa_DeleteHashTable(ss->Programs); #endif - || outOfMemory) { - /* Ran out of memory at some point. Free everything and return NULL */ - if (ss->DisplayList) - _mesa_DeleteHashTable(ss->DisplayList); - if (ss->TexObjects) - _mesa_DeleteHashTable(ss->TexObjects); - if (ss->Programs) - _mesa_DeleteHashTable(ss->Programs); - if (ss->Default1D) - _mesa_free_texture_object(ss, ss->Default1D); - if (ss->Default2D) - _mesa_free_texture_object(ss, ss->Default2D); - if (ss->Default3D) - _mesa_free_texture_object(ss, ss->Default3D); - if (ss->DefaultCubeMap) - _mesa_free_texture_object(ss, ss->DefaultCubeMap); - if (ss->DefaultRect) - _mesa_free_texture_object(ss, ss->DefaultRect); - FREE(ss); - return NULL; - } - else { - return ss; - } + if (ss->Default1D) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D); + if (ss->Default2D) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D); + if (ss->Default3D) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D); + if (ss->DefaultCubeMap) + (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap); + if (ss->DefaultRect) + (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect); + if (ss) + _mesa_free(ss); + return GL_FALSE; } @@ -735,11 +736,19 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->DisplayList); /* Free texture objects */ - while (ss->TexObjectList) { - if (ctx->Driver.DeleteTexture) - (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList ); - /* this function removes from linked list too! */ - _mesa_free_texture_object(ss, ss->TexObjectList); + ASSERT(ctx->Driver.DeleteTexture); + while (1) { + GLuint texName = _mesa_HashFirstEntry(ss->TexObjects); + if (texName) { + struct gl_texture_object *texObj = (struct gl_texture_object *) + _mesa_HashLookup(ss->TexObjects, texName); + ASSERT(texObj); + (*ctx->Driver.DeleteTexture)(ctx, texObj); + _mesa_HashRemove(ss->TexObjects, texName); + } + else { + break; + } } _mesa_DeleteHashTable(ss->TexObjects); @@ -1529,99 +1538,48 @@ init_attrib_groups( GLcontext *ctx ) -/* - * Allocate the proxy textures. If we run out of memory part way through - * the allocations clean up and return GL_FALSE. - * Return: GL_TRUE=success, GL_FALSE=failure +/** + * Allocate the proxy textures for the given context. + * \param ctx the context to allocate proxies for. + * \return GL_TRUE if success, GL_FALSE if failure. */ static GLboolean alloc_proxy_textures( GLcontext *ctx ) { - GLboolean out_of_memory; - GLint i; + ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); + if (!ctx->Texture.Proxy1D) + goto cleanup; - ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_1D); - if (!ctx->Texture.Proxy1D) { - return GL_FALSE; - } + ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); + if (!ctx->Texture.Proxy2D) + goto cleanup; - ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_2D); - if (!ctx->Texture.Proxy2D) { - _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); - return GL_FALSE; - } + ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); + if (!ctx->Texture.Proxy3D) + goto cleanup; - ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_3D); - if (!ctx->Texture.Proxy3D) { - _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); - return GL_FALSE; - } - - ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0, - GL_TEXTURE_CUBE_MAP_ARB); - if (!ctx->Texture.ProxyCubeMap) { - _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); - return GL_FALSE; - } + ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); + if (!ctx->Texture.ProxyCubeMap) + goto cleanup; - ctx->Texture.ProxyRect = _mesa_alloc_texture_object(NULL, 0, - GL_TEXTURE_RECTANGLE_NV); - if (!ctx->Texture.ProxyRect) { - _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); - _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap); - return GL_FALSE; - } + ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); + if (!ctx->Texture.ProxyRect) + goto cleanup; - out_of_memory = GL_FALSE; - for (i=0;iTexture.Proxy1D->Image[i] = _mesa_alloc_texture_image(); - ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image(); - ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image(); - ctx->Texture.ProxyCubeMap->Image[i] = _mesa_alloc_texture_image(); - if (!ctx->Texture.Proxy1D->Image[i] - || !ctx->Texture.Proxy2D->Image[i] - || !ctx->Texture.Proxy3D->Image[i] - || !ctx->Texture.ProxyCubeMap->Image[i]) { - out_of_memory = GL_TRUE; - } - } - ctx->Texture.ProxyRect->Image[0] = _mesa_alloc_texture_image(); - if (!ctx->Texture.ProxyRect->Image[0]) - out_of_memory = GL_TRUE; + return GL_TRUE; - if (out_of_memory) { - for (i=0;iTexture.Proxy1D->Image[i]) { - _mesa_free_texture_image(ctx->Texture.Proxy1D->Image[i]); - } - if (ctx->Texture.Proxy2D->Image[i]) { - _mesa_free_texture_image(ctx->Texture.Proxy2D->Image[i]); - } - if (ctx->Texture.Proxy3D->Image[i]) { - _mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]); - } - if (ctx->Texture.ProxyCubeMap->Image[i]) { - _mesa_free_texture_image(ctx->Texture.ProxyCubeMap->Image[i]); - } - } - if (ctx->Texture.ProxyRect->Image[0]) { - _mesa_free_texture_image(ctx->Texture.ProxyRect->Image[0]); - } - _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); - _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); - _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap); - _mesa_free_texture_object(NULL, ctx->Texture.ProxyRect); - return GL_FALSE; - } - else { - return GL_TRUE; - } + cleanup: + if (ctx->Texture.Proxy1D) + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D); + if (ctx->Texture.Proxy2D) + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D); + if (ctx->Texture.Proxy3D) + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D); + if (ctx->Texture.ProxyCubeMap) + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap); + if (ctx->Texture.ProxyRect) + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect); + return GL_FALSE; } @@ -1695,14 +1653,23 @@ _mesa_initialize_context( GLcontext *ctx, ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; + /* Set these pointers to defaults now in case they're not set since + * we need them while creating the default textures. + */ + if (!ctx->Driver.NewTextureObject) + ctx->Driver.NewTextureObject = _mesa_new_texture_object; + if (!ctx->Driver.DeleteTexture) + ctx->Driver.DeleteTexture = _mesa_delete_texture_object; + if (!ctx->Driver.NewTextureImage) + ctx->Driver.NewTextureImage = _mesa_new_texture_image; + if (share_list) { /* share state with another context */ ctx->Shared = share_list->Shared; } else { /* allocate new, unshared state */ - ctx->Shared = alloc_shared_state(); - if (!ctx->Shared) { + if (!alloc_shared_state( ctx )) { return GL_FALSE; } } @@ -1710,13 +1677,6 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Shared->RefCount++; _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* Effectively bind the default textures to all texture units */ - ctx->Shared->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ctx->Shared->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ctx->Shared->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; - init_attrib_groups( ctx ); if (visual->doubleBufferMode) { @@ -1837,6 +1797,7 @@ _mesa_initialize_context( GLcontext *ctx, _glapi_add_entrypoint("glGetFenceivNV", 651); _glapi_add_entrypoint("glFinishFenceNV", 652); _glapi_add_entrypoint("glSetFenceNV", 653); + /* XXX add NV_fragment_program and ARB_vertex_program functions */ /* Find the larger of Mesa's dispatch table and libGL's dispatch table. * In practice, this'll be the same for stand-alone Mesa. But for DRI @@ -1997,11 +1958,11 @@ _mesa_free_context_data( GLcontext *ctx ) FREE( ctx->_ShineTabList ); /* Free proxy texture objects */ - _mesa_free_texture_object( NULL, ctx->Texture.Proxy1D ); - _mesa_free_texture_object( NULL, ctx->Texture.Proxy2D ); - _mesa_free_texture_object( NULL, ctx->Texture.Proxy3D ); - _mesa_free_texture_object( NULL, ctx->Texture.ProxyCubeMap ); - _mesa_free_texture_object( NULL, ctx->Texture.ProxyRect ); + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D ); + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap ); + (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect ); for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable ); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index d6f0da1c69e..59316ca0549 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.74 2002/10/11 17:41:04 brianp Exp $ */ +/* $Id: dd.h,v 1.75 2003/04/01 16:41:52 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -51,7 +51,6 @@ struct gl_pixelstore_attrib; * Device Driver function table. */ struct dd_function_table { - const GLubyte * (*GetString)( GLcontext *ctx, GLenum name ); /* Return a string as needed by glGetString(). * Only the GL_RENDERER token must be implemented. Otherwise, @@ -354,8 +353,12 @@ struct dd_function_table { /* Called by glBindTexture(). */ - void (*CreateTexture)( GLcontext *ctx, struct gl_texture_object *tObj ); - /* Called when a texture object is created. + struct gl_texture_object * (*NewTextureObject)( GLcontext *ctx, GLuint name, + GLenum target ); + /* Called to allocate a new texture object. + * NOTE: this function pointer should be initialized by drivers _BEFORE_ + * calling _mesa_initialize_context() since context initialization involves + * allocating some texture objects! */ void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj ); @@ -363,6 +366,10 @@ struct dd_function_table { * should free anything attached to the DriverData pointers. */ + struct gl_texture_image * (*NewTextureImage)( GLcontext *ctx ); + /* Called to allocate a new texture image object. + */ + GLboolean (*IsTextureResident)( GLcontext *ctx, struct gl_texture_object *t ); /* Called by glAreTextureResident(). diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 3397a865cd5..cef81cb670d 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.126 2003/03/01 01:50:22 brianp Exp $ */ +/* $Id: teximage.c,v 1.127 2003/04/01 16:41:53 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -415,19 +415,26 @@ _mesa_set_tex_image(struct gl_texture_object *tObj, -/* +/** * Return new gl_texture_image struct with all fields initialized to zero. + * Called via ctx->Driver.NewTextureImage() unless overriden by a device + * driver. */ struct gl_texture_image * -_mesa_alloc_texture_image( void ) +_mesa_new_texture_image( GLcontext *ctx ) { + (void) ctx; return CALLOC_STRUCT(gl_texture_image); } +/** + * Delete/free the given texture image and associated image data if it's not + * marked as client data. + */ void -_mesa_free_texture_image( struct gl_texture_image *teximage ) +_mesa_delete_texture_image( struct gl_texture_image *teximage ) { if (teximage->Data && !teximage->IsClientData) { MESA_PBUFFER_FREE( teximage->Data ); @@ -577,6 +584,118 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, } +/** + * Like _mesa_select_tex_image() but if the image doesn't exist, allocate + * it and install it. Only return NULL if passed a bad parameter or run + * out of memory. + */ +struct gl_texture_image * +_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target, GLint level) +{ + struct gl_texture_image *texImage; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + struct gl_texture_object *texObj; + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); + return NULL; + } + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + _mesa_set_tex_image(texObj, target, level, texImage); + } + return texImage; +} + + +/** + * Return pointer to the specified proxy texture image. + * Note that proxy textures are per-context, not per-texture unit. + * \return pointer to texture image or NULL if invalid target, invalid + * level, or out of memory. + */ +struct gl_texture_image * +_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level) +{ + struct gl_texture_image *texImage; + + if (level < 0 ) + return NULL; + + switch (target) { + case GL_PROXY_TEXTURE_1D: + if (level >= ctx->Const.MaxTextureLevels) + return NULL; + texImage = ctx->Texture.Proxy1D->Image[level]; + if (!texImage) { + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); + return NULL; + } + ctx->Texture.Proxy1D->Image[level] = texImage; + } + return texImage; + case GL_PROXY_TEXTURE_2D: + if (level >= ctx->Const.MaxTextureLevels) + return NULL; + texImage = ctx->Texture.Proxy2D->Image[level]; + if (!texImage) { + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); + return NULL; + } + ctx->Texture.Proxy2D->Image[level] = texImage; + } + return texImage; + case GL_PROXY_TEXTURE_3D: + if (level >= ctx->Const.Max3DTextureLevels) + return NULL; + texImage = ctx->Texture.Proxy3D->Image[level]; + if (!texImage) { + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); + return NULL; + } + ctx->Texture.Proxy3D->Image[level] = texImage; + } + return texImage; + case GL_PROXY_TEXTURE_CUBE_MAP: + if (level >= ctx->Const.MaxCubeTextureLevels) + return NULL; + texImage = ctx->Texture.ProxyCubeMap->Image[level]; + if (!texImage) { + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); + return NULL; + } + ctx->Texture.ProxyCubeMap->Image[level] = texImage; + } + return texImage; + case GL_PROXY_TEXTURE_RECTANGLE_NV: + if (level > 0) + return NULL; + texImage = ctx->Texture.ProxyRect->Image[level]; + if (!texImage) { + texImage = ctx->Driver.NewTextureImage(ctx); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); + return NULL; + } + ctx->Texture.ProxyRect->Image[level] = texImage; + } + return texImage; + default: + return NULL; + } +} + + /* * Return the maximum number of allows mipmap levels for the given * texture target. @@ -1167,10 +1286,8 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, if (destTex->IsCompressed) { const struct gl_texture_unit *texUnit; - const struct gl_texture_object *texObj; const struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); texImage = _mesa_select_tex_image(ctx, texUnit, target, level); if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { @@ -1637,15 +1754,11 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - texObj->Image[level] = texImage; - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; } else if (texImage->Data && !texImage->IsClientData) { /* free the old texture data */ @@ -1690,9 +1803,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, } if (error) { /* if error, clear all proxy texture image parameters */ - if (level >= 0 && level < ctx->Const.MaxTextureLevels) { - clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); - } + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) + clear_teximage_fields(texImage); } else { /* no error, set the tex image parameters */ @@ -1746,15 +1860,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - _mesa_set_tex_image(texObj, target, level, texImage); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; } else if (texImage->Data && !texImage->IsClientData) { /* free the old texture data */ @@ -1803,11 +1912,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } if (error) { /* if error, clear all proxy texture image parameters */ - const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? - ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; - if (level >= 0 && level < maxLevels) { + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); - } } else { /* no error, set the tex image parameters */ @@ -1852,15 +1960,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - texObj->Image[level] = texImage; - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + return; } else if (texImage->Data && !texImage->IsClientData) { MESA_PBUFFER_FREE(texImage->Data); @@ -1904,9 +2007,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } if (error) { /* if error, clear all proxy texture image parameters */ - if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { - clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); - } + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) + clear_teximage_fields(texImage); } else { /* no error, set the tex image parameters */ @@ -2102,14 +2206,10 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - _mesa_set_tex_image(texObj, target, level, texImage); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; } else if (texImage->Data && !texImage->IsClientData) { /* free the old texture data */ @@ -2166,14 +2266,10 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - _mesa_set_tex_image(texObj, target, level, texImage); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; } else if (texImage->Data && !texImage->IsClientData) { /* free the old texture data */ @@ -2228,6 +2324,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); /* If we have a border, xoffset=-1 is legal. Bias by border width */ xoffset += texImage->Border; @@ -2264,6 +2361,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); /* If we have a border, xoffset=-1 is legal. Bias by border width */ xoffset += texImage->Border; @@ -2302,6 +2400,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); /* If we have a border, xoffset=-1 is legal. Bias by border width */ xoffset += texImage->Border; @@ -2509,15 +2608,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - texObj->Image[level] = texImage; - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); + return; } else if (texImage->Data && !texImage->IsClientData) { MESA_PBUFFER_FREE(texImage->Data); @@ -2549,9 +2643,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, } if (error) { /* if error, clear all proxy texture image parameters */ - if (level >= 0 && level < ctx->Const.MaxTextureLevels) { - clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); - } + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) + clear_teximage_fields(texImage); } else { /* store the teximage parameters */ @@ -2595,15 +2690,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - texObj->Image[level] = texImage; - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; } else if (texImage->Data && !texImage->IsClientData) { MESA_PBUFFER_FREE(texImage->Data); @@ -2637,11 +2727,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, } if (error) { /* if error, clear all proxy texture image parameters */ - const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? - ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; - if (level >= 0 && level < maxLevels) { - clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); - } + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) + clear_teximage_fields(texImage); } else { /* store the teximage parameters */ @@ -2682,15 +2771,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - + texImage = _mesa_get_tex_image(ctx, texUnit, target, level); if (!texImage) { - texImage = _mesa_alloc_texture_image(); - texObj->Image[level] = texImage; - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); - return; - } + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); + return; } else if (texImage->Data && !texImage->IsClientData) { MESA_PBUFFER_FREE(texImage->Data); @@ -2723,9 +2807,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, } if (error) { /* if error, clear all proxy texture image parameters */ - if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { - clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); - } + struct gl_texture_image *texImage; + texImage = _mesa_get_proxy_tex_image(ctx, target, level); + if (texImage) + clear_teximage_fields(texImage); } else { /* store the teximage parameters */ diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 8cbc0d66152..7ab6810209d 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -1,4 +1,4 @@ -/* $Id: teximage.h,v 1.22 2002/10/18 18:03:07 brianp Exp $ */ +/* $Id: teximage.h,v 1.23 2003/04/01 16:41:54 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -40,11 +40,11 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format ); extern struct gl_texture_image * -_mesa_alloc_texture_image( void ); +_mesa_new_texture_image( GLcontext *ctx ); extern void -_mesa_free_texture_image( struct gl_texture_image *teximage ); +_mesa_delete_texture_image( struct gl_texture_image *teximage ); extern void @@ -70,6 +70,15 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, GLenum target, GLint level); +extern struct gl_texture_image * +_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target, GLint level); + + +extern struct gl_texture_image * +_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level); + + extern GLint _mesa_max_texture_levels(GLcontext *ctx, GLenum target); diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index c845e8c7a3a..864752b6d98 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -1,4 +1,4 @@ -/* $Id: texobj.c,v 1.66 2003/03/10 00:26:24 brianp Exp $ */ +/* $Id: texobj.c,v 1.67 2003/04/01 16:41:55 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -37,23 +37,37 @@ #include "mtypes.h" -/* - * Allocate a new texture object and add it to the linked list of texture - * objects. If name>0 then also insert the new texture object into the hash - * table. - * Input: shared - the shared GL state structure to contain the texture object - * name - integer name for the texture object - * target - either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, - * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV - * zero is ok for the sake of GenTextures() - * Return: pointer to new texture object +/** + * Allocate and initialize a new texture object + * Called via ctx->Driver.NewTextureObject, unless overridden by a device + * driver. + * \param ctx the rendering context + * \param name the integer name for the texture object + * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, + * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV + * zero is ok for the sake of GenTextures() + * \return pointer to new texture object */ struct gl_texture_object * -_mesa_alloc_texture_object( struct gl_shared_state *shared, - GLuint name, GLenum target ) +_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target ) { struct gl_texture_object *obj; + obj = CALLOC_STRUCT(gl_texture_object); + _mesa_initialize_texture_object(obj, name, target); + return obj; +} + +/** + * Initialize a texture object to default values. + * \param obj the texture object + * \param name the texture name + * \param target the texture target + */ +void +_mesa_initialize_texture_object( struct gl_texture_object *obj, + GLuint name, GLenum target ) +{ ASSERT(target == 0 || target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || @@ -61,114 +75,124 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared, target == GL_TEXTURE_CUBE_MAP_ARB || target == GL_TEXTURE_RECTANGLE_NV); - obj = CALLOC_STRUCT(gl_texture_object); - - if (obj) { - /* init the non-zero fields */ - _glthread_INIT_MUTEX(obj->Mutex); - obj->RefCount = 1; - obj->Name = name; - obj->Target = target; - obj->Priority = 1.0F; - if (target == GL_TEXTURE_RECTANGLE_NV) { - obj->WrapS = GL_CLAMP_TO_EDGE; - obj->WrapT = GL_CLAMP_TO_EDGE; - obj->WrapR = GL_CLAMP_TO_EDGE; - obj->MinFilter = GL_LINEAR; - } - else { - obj->WrapS = GL_REPEAT; - obj->WrapT = GL_REPEAT; - obj->WrapR = GL_REPEAT; - obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; - } - obj->MagFilter = GL_LINEAR; - obj->MinLod = -1000.0; - obj->MaxLod = 1000.0; - obj->BaseLevel = 0; - obj->MaxLevel = 1000; - obj->MaxAnisotropy = 1.0; - obj->CompareFlag = GL_FALSE; /* SGIX_shadow */ - obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */ - obj->CompareMode = GL_LUMINANCE; /* ARB_shadow */ - obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */ - obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */ - obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */ - _mesa_init_colortable(&obj->Palette); - - /* insert into linked list */ - if (shared) { - _glthread_LOCK_MUTEX(shared->Mutex); - obj->Next = shared->TexObjectList; - shared->TexObjectList = obj; - _glthread_UNLOCK_MUTEX(shared->Mutex); - } - - if (name > 0) { - /* insert into hash table */ - _mesa_HashInsert(shared->TexObjects, name, obj); - } + /* init the non-zero fields */ + _glthread_INIT_MUTEX(obj->Mutex); + obj->RefCount = 1; + obj->Name = name; + obj->Target = target; + obj->Priority = 1.0F; + if (target == GL_TEXTURE_RECTANGLE_NV) { + obj->WrapS = GL_CLAMP_TO_EDGE; + obj->WrapT = GL_CLAMP_TO_EDGE; + obj->WrapR = GL_CLAMP_TO_EDGE; + obj->MinFilter = GL_LINEAR; } - return obj; + else { + obj->WrapS = GL_REPEAT; + obj->WrapT = GL_REPEAT; + obj->WrapR = GL_REPEAT; + obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; + } + obj->MagFilter = GL_LINEAR; + obj->MinLod = -1000.0; + obj->MaxLod = 1000.0; + obj->BaseLevel = 0; + obj->MaxLevel = 1000; + obj->MaxAnisotropy = 1.0; + obj->CompareFlag = GL_FALSE; /* SGIX_shadow */ + obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */ + obj->CompareMode = GL_LUMINANCE; /* ARB_shadow */ + obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */ + obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */ + obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */ + _mesa_init_colortable(&obj->Palette); } /* - * Deallocate a texture object struct and remove it from the given - * shared GL state. - * Input: shared - the shared GL state to which the object belongs - * t - the texture object to delete + * Deallocate a texture object. It should have already been removed from + * the texture object pool. + * \param texObj the texture object to deallocate */ -void _mesa_free_texture_object( struct gl_shared_state *shared, - struct gl_texture_object *t ) +void +_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) { - struct gl_texture_object *tprev, *tcurr; + GLuint i; - assert(t); - - /* unlink t from the linked list */ - if (shared) { - _glthread_LOCK_MUTEX(shared->Mutex); - tprev = NULL; - tcurr = shared->TexObjectList; - while (tcurr) { - if (tcurr==t) { - if (tprev) { - tprev->Next = t->Next; - } - else { - shared->TexObjectList = t->Next; - } - break; - } - tprev = tcurr; - tcurr = tcurr->Next; + (void) ctx; + + assert(texObj); + + _mesa_free_colortable_data(&texObj->Palette); + + /* free the texture images */ + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + if (texObj->Image[i]) { + _mesa_delete_texture_image( texObj->Image[i] ); } - _glthread_UNLOCK_MUTEX(shared->Mutex); } - if (t->Name) { - /* remove from hash table */ - _mesa_HashRemove(shared->TexObjects, t->Name); + /* destroy the mutex -- it may have allocated memory (eg on bsd) */ + _glthread_DESTROY_MUTEX(texObj->Mutex); + + /* free this object */ + _mesa_free(texObj); +} + + +/** + * Add the given texture object to the texture object pool. + */ +void +_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) +{ + /* insert into linked list */ + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + texObj->Next = ctx->Shared->TexObjectList; + ctx->Shared->TexObjectList = texObj; + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + + if (texObj->Name > 0) { + /* insert into hash table */ + _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); } +} - _mesa_free_colortable_data(&t->Palette); - /* free the texture images */ - { - GLuint i; - for (i=0;iImage[i]) { - _mesa_free_texture_image( t->Image[i] ); +/** + * Remove the given texture object from the texture object pool. + * Do not deallocate the texture object though. + */ +void +_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) +{ + struct gl_texture_object *tprev, *tcurr; + + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + + /* unlink from the linked list */ + tprev = NULL; + tcurr = ctx->Shared->TexObjectList; + while (tcurr) { + if (tcurr == texObj) { + if (tprev) { + tprev->Next = texObj->Next; } + else { + ctx->Shared->TexObjectList = texObj->Next; + } + break; } + tprev = tcurr; + tcurr = tcurr->Next; } - /* destroy the mutex -- it may have allocated memory (eg on bsd) */ - _glthread_DESTROY_MUTEX(t->Mutex); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* free this object */ - FREE( t ); + if (texObj->Name > 0) { + /* remove from hash table */ + _mesa_HashRemove(ctx->Shared->TexObjects, texObj->Name); + } } @@ -531,10 +555,16 @@ _mesa_GenTextures( GLsizei n, GLuint *texName ) } /* Allocate new, empty texture objects */ - for (i=0;iShared, name, target); + texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target); + if (!texObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); + return; + } + _mesa_save_texture_object(ctx, texObj); } _glthread_UNLOCK_MUTEX(GenTexturesLock); @@ -610,9 +640,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *texName) if (delObj->RefCount == 0) { ASSERT(delObj->Name != 0); - if (ctx->Driver.DeleteTexture) - (*ctx->Driver.DeleteTexture)( ctx, delObj ); - _mesa_free_texture_object(ctx->Shared, delObj); + _mesa_remove_texture_object(ctx, delObj); + ASSERT(ctx->Driver.DeleteTexture); + (*ctx->Driver.DeleteTexture)(ctx, delObj); } } } @@ -717,12 +747,12 @@ _mesa_BindTexture( GLenum target, GLuint texName ) } else { /* if this is a new texture id, allocate a texture object now */ - newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName, - target); + newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target); if (!newTexObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture"); return; } + _mesa_save_texture_object(ctx, newTexObj); } newTexObj->Target = target; } @@ -762,10 +792,9 @@ _mesa_BindTexture( GLenum target, GLuint texName ) assert(oldTexObj->RefCount >= 0); if (oldTexObj->RefCount == 0) { assert(oldTexObj->Name != 0); - if (ctx->Driver.DeleteTexture) { - (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); - } - _mesa_free_texture_object(ctx->Shared, oldTexObj); + _mesa_remove_texture_object(ctx, oldTexObj); + ASSERT(ctx->Driver.DeleteTexture); + (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); } } diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 050caff23fd..ff46187809d 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -1,4 +1,4 @@ -/* $Id: texobj.h,v 1.8 2002/06/17 23:36:31 brianp Exp $ */ +/* $Id: texobj.h,v 1.9 2003/04/01 16:41:55 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -38,23 +38,28 @@ */ extern struct gl_texture_object * -_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name, - GLenum target ); +_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target ); +extern void +_mesa_initialize_texture_object( struct gl_texture_object *obj, + GLuint name, GLenum target ); extern void -_mesa_free_texture_object( struct gl_shared_state *shared, - struct gl_texture_object *t ); +_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *obj ); +extern void +_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *obj ); + +extern void +_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *obj ); extern void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ); - extern void _mesa_test_texobj_completeness( const GLcontext *ctx, - struct gl_texture_object *t ); + struct gl_texture_object *obj ); /* diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 117696896eb..08e625bc0d4 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,4 +1,4 @@ -/* $Id: texstore.c,v 1.54 2003/03/04 19:16:23 brianp Exp $ */ +/* $Id: texstore.c,v 1.55 2003/04/01 16:41:55 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -482,6 +482,7 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_RGB || baseInternalFormat == GL_RGBA || + baseInternalFormat == GL_COLOR_INDEX || baseInternalFormat == GL_DEPTH_COMPONENT); if (transferOps & IMAGE_CONVOLUTION_BIT) { @@ -1274,16 +1275,12 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, GLint depth, GLint border) { - struct gl_texture_unit *texUnit; - struct gl_texture_object *texObj; struct gl_texture_image *texImage; (void) format; (void) type; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_get_proxy_tex_image(ctx, target, level); /* We always pass. * The core Mesa code will have already tested the image size, etc. @@ -2011,14 +2008,10 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, } /* get dest gl_texture_image */ - dstImage = _mesa_select_tex_image(ctx, texUnit, target, level+1); + dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1); if (!dstImage) { - dstImage = _mesa_alloc_texture_image(); - if (!dstImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); - return; - } - _mesa_set_tex_image(texObj, target, level + 1, dstImage); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; } /* Free old image data */