New device driver hooks for texture object and texture image creation to
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 1 Apr 2003 16:41:50 +0000 (16:41 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 1 Apr 2003 16:41:50 +0000 (16:41 +0000)
allow drivers to implement C++-like inheritance via containment.
Lots of assorted clean-ups related to texture objects.

src/mesa/drivers/osmesa/osmesa.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/main/context.c
src/mesa/main/dd.h
src/mesa/main/teximage.c
src/mesa/main/teximage.h
src/mesa/main/texobj.c
src/mesa/main/texobj.h
src/mesa/main/texstore.c

index 0141bf1..ba7500f 100644 (file)
@@ -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;
index 230bee3..3aa33a5 100644 (file)
@@ -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;
index b9bbe65..7c8befc 100644 (file)
@@ -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;i<MAX_TEXTURE_LEVELS;i++) {
-      ctx->Texture.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;i<MAX_TEXTURE_LEVELS;i++) {
-         if (ctx->Texture.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 );
index d6f0da1..59316ca 100644 (file)
@@ -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().
index 3397a86..cef81cb 100644 (file)
@@ -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 */
index 8cbc0d6..7ab6810 100644 (file)
@@ -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);
 
index c845e8c..864752b 100644 (file)
@@ -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
 #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;i<MAX_TEXTURE_LEVELS;i++) {
-         if (t->Image[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;i<n;i++) {
+   for (i = 0; i < n; i++) {
+      struct gl_texture_object *texObj;
       GLuint name = first + i;
       GLenum target = 0;
-      (void) _mesa_alloc_texture_object( ctx->Shared, 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 );
    }
 }
 
index 050caff..ff46187 100644 (file)
@@ -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
  */
 
 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 );
 
 
 /*
index 1176968..08e625b 100644 (file)
@@ -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 */