Bring over the texobj refcounting changes from mesa_7_0_branch
authorBrian <brian.paul@tungstengraphics.com>
Thu, 16 Aug 2007 09:05:00 +0000 (10:05 +0100)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 16 Aug 2007 09:05:00 +0000 (10:05 +0100)
src/mesa/main/attrib.c
src/mesa/main/attrib.h
src/mesa/main/context.c
src/mesa/main/texobj.c
src/mesa/main/texstate.c

index 36e438a53cc4cd8f448860e3e45aaa388faf356f..52e3f22adcfda340da57edf804a149ca830ea06b 100644 (file)
 #include "math/m_xform.h"
 
 
+/**
+ * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
+ */
+struct texture_state
+{
+   struct gl_texture_attrib Texture;  /**< The usual context state */
+
+   /** to save per texture object state (wrap modes, filters, etc): */
+   struct gl_texture_object Saved1D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved2D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved3D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object SavedCube[MAX_TEXTURE_UNITS];
+   struct gl_texture_object SavedRect[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved1DArray[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved2DArray[MAX_TEXTURE_UNITS];
+
+   /**
+    * To save references to texture objects (so they don't get accidentally
+    * deleted while saved in the attribute stack).
+    */
+   struct gl_texture_object *SavedRef1D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef2D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef3D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRefCube[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRefRect[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef1DArray[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef2DArray[MAX_TEXTURE_UNITS];
+};
+
+
 /**
  * Allocate a new attribute state node.  These nodes have a
  * "kind" value and a pointer to a struct of state data.
@@ -339,47 +369,54 @@ _mesa_PushAttrib(GLbitfield mask)
    }
 
    if (mask & GL_TEXTURE_BIT) {
-      struct gl_texture_attrib *attr;
+      struct texture_state *texstate = CALLOC_STRUCT(texture_state);
       GLuint u;
 
+      if (!texstate) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
+         goto end;
+      }
+
       _mesa_lock_context_textures(ctx);
-      /* Bump the texture object reference counts so that they don't
-       * inadvertantly get deleted.
+
+      /* copy/save the bulk of texture state here */
+      _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
+
+      /* Save references to the currently bound texture objects so they don't
+       * accidentally get deleted while referenced in the attribute stack.
        */
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-        ctx->Texture.Unit[u].Current1D->RefCount++;
-        ctx->Texture.Unit[u].Current2D->RefCount++;
-        ctx->Texture.Unit[u].Current3D->RefCount++;
-        ctx->Texture.Unit[u].CurrentCubeMap->RefCount++;
-        ctx->Texture.Unit[u].CurrentRect->RefCount++;
-        ctx->Texture.Unit[u].Current1DArray->RefCount++;
-        ctx->Texture.Unit[u].Current2DArray->RefCount++;
+         _mesa_reference_texobj(&texstate->SavedRef1D[u], ctx->Texture.Unit[u].Current1D);
+         _mesa_reference_texobj(&texstate->SavedRef2D[u], ctx->Texture.Unit[u].Current2D);
+         _mesa_reference_texobj(&texstate->SavedRef3D[u], ctx->Texture.Unit[u].Current3D);
+         _mesa_reference_texobj(&texstate->SavedRefCube[u], ctx->Texture.Unit[u].CurrentCubeMap);
+         _mesa_reference_texobj(&texstate->SavedRefRect[u], ctx->Texture.Unit[u].CurrentRect);
+         _mesa_reference_texobj(&texstate->SavedRef1DArray[u], ctx->Texture.Unit[u].Current1DArray);
+         _mesa_reference_texobj(&texstate->SavedRef2DArray[u], ctx->Texture.Unit[u].Current2DArray);
       }
 
-      attr = MALLOC_STRUCT( gl_texture_attrib );
-      MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
-      /* copy state of the currently bound texture objects */
+      /* copy state/contents of the currently bound texture objects */
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-         _mesa_copy_texture_object(&attr->Unit[u].Saved1D,
-                                   attr->Unit[u].Current1D);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved2D,
-                                   attr->Unit[u].Current2D);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved3D,
-                                   attr->Unit[u].Current3D);
-         _mesa_copy_texture_object(&attr->Unit[u].SavedCubeMap,
-                                   attr->Unit[u].CurrentCubeMap);
-         _mesa_copy_texture_object(&attr->Unit[u].SavedRect,
-                                   attr->Unit[u].CurrentRect);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved1DArray,
-                                   attr->Unit[u].Current1DArray);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved2DArray,
-                                   attr->Unit[u].Current2DArray);
+         _mesa_copy_texture_object(&texstate->Saved1D[u],
+                                   ctx->Texture.Unit[u].Current1D);
+         _mesa_copy_texture_object(&texstate->Saved2D[u],
+                                   ctx->Texture.Unit[u].Current2D);
+         _mesa_copy_texture_object(&texstate->Saved3D[u],
+                                   ctx->Texture.Unit[u].Current3D);
+         _mesa_copy_texture_object(&texstate->SavedCube[u],
+                                   ctx->Texture.Unit[u].CurrentCubeMap);
+         _mesa_copy_texture_object(&texstate->SavedRect[u],
+                                   ctx->Texture.Unit[u].CurrentRect);
+         _mesa_copy_texture_object(&texstate->Saved1DArray[u],
+                                   ctx->Texture.Unit[u].Current1DArray);
+         _mesa_copy_texture_object(&texstate->Saved2DArray[u],
+                                   ctx->Texture.Unit[u].Current2DArray);
       }
 
       _mesa_unlock_context_textures(ctx);
 
       newnode = new_attrib_node( GL_TEXTURE_BIT );
-      newnode->data = attr;
+      newnode->data = texstate;
       newnode->next = head;
       head = newnode;
    }
@@ -415,6 +452,7 @@ _mesa_PushAttrib(GLbitfield mask)
       head = newnode;
    }
 
+end:
    ctx->AttribStack[ctx->AttribStackDepth] = head;
    ctx->AttribStackDepth++;
 }
@@ -624,14 +662,19 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
 }
 
 
+/**
+ * Pop/restore texture attribute/group state.
+ */
 static void
-pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
+pop_texture_group(GLcontext *ctx, struct texture_state *texstate)
 {
    GLuint u;
 
+   _mesa_lock_context_textures(ctx);
+
    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-      const struct gl_texture_unit *unit = &texAttrib->Unit[u];
-      GLuint i;
+      const struct gl_texture_unit *unit = &texstate->Texture.Unit[u];
+      GLuint tgt;
 
       _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
       _mesa_set_enable(ctx, GL_TEXTURE_1D,
@@ -724,53 +767,56 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
                        1 << unit->Combine.ScaleShiftA);
       }
 
-      /* Restore texture object state */
-      for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
-         GLenum target = 0;
+      /* Restore texture object state for each target */
+      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
          const struct gl_texture_object *obj = NULL;
          GLfloat bordColor[4];
+         GLenum target;
 
-         switch (i) {
-         case 0:
-            target = GL_TEXTURE_1D;
-            obj = &unit->Saved1D;
+         switch (tgt) {
+         case TEXTURE_1D_INDEX:
+            obj = &texstate->Saved1D[u];
+            ASSERT(obj->Target == GL_TEXTURE_1D);
             break;
-         case 1:
-            target = GL_TEXTURE_2D;
-            obj = &unit->Saved2D;
+         case TEXTURE_2D_INDEX:
+            obj = &texstate->Saved2D[u];
+            ASSERT(obj->Target == GL_TEXTURE_2D);
             break;
-         case 2:
-            target = GL_TEXTURE_3D;
-            obj = &unit->Saved3D;
+         case TEXTURE_3D_INDEX:
+            obj = &texstate->Saved3D[u];
+            ASSERT(obj->Target == GL_TEXTURE_3D);
             break;
-         case 3:
+         case TEXTURE_CUBE_INDEX:
             if (!ctx->Extensions.ARB_texture_cube_map)
                continue;
-            target = GL_TEXTURE_CUBE_MAP_ARB;
-            obj = &unit->SavedCubeMap;
+            obj = &texstate->SavedCube[u];
+            ASSERT(obj->Target == GL_TEXTURE_CUBE_MAP_ARB);
             break;
-         case 4:
+         case TEXTURE_RECT_INDEX:
             if (!ctx->Extensions.NV_texture_rectangle)
                continue;
-            target = GL_TEXTURE_RECTANGLE_NV;
-            obj = &unit->SavedRect;
+            obj = &texstate->SavedRect[u];
+            ASSERT(obj->Target == GL_TEXTURE_RECTANGLE_NV);
             break;
-         case 5:
+         case TEXTURE_1D_ARRAY_INDEX:
             if (!ctx->Extensions.MESA_texture_array)
                continue;
-            target = GL_TEXTURE_1D_ARRAY_EXT;
-            obj = &unit->Saved1DArray;
+            obj = &texstate->Saved1DArray[u];
+            ASSERT(obj->Target == GL_TEXTURE_1D_ARRAY_EXT);
             break;
-         case 6:
+         case TEXTURE_2D_ARRAY_INDEX:
             if (!ctx->Extensions.MESA_texture_array)
                continue;
-            target = GL_TEXTURE_2D_ARRAY_EXT;
-            obj = &unit->Saved2DArray;
+            obj = &texstate->Saved2DArray[u];
+            ASSERT(obj->Target == GL_TEXTURE_2D_ARRAY_EXT);
             break;
          default:
-            ; /* silence warnings */
+            _mesa_problem(ctx, "bad texture index in pop_texture_group");
+            continue;
          }
 
+         target = obj->Target;
+
          _mesa_BindTexture(target, obj->Name);
 
          bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
@@ -778,8 +824,8 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
          bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]);
          bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]);
 
-         _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
          _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor);
+         _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
@@ -805,25 +851,21 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
             _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
                                 obj->ShadowAmbient);
          }
-
       }
-   }
-   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB
-                          + texAttrib->CurrentUnit);
 
-   /* "un-bump" the texture object reference counts.  We did that so they
-    * wouldn't inadvertantly get deleted while they were still referenced
-    * inside the attribute state stack.
-    */
-   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-      ctx->Texture.Unit[u].Current1D->RefCount--;
-      ctx->Texture.Unit[u].Current2D->RefCount--;
-      ctx->Texture.Unit[u].Current3D->RefCount--;
-      ctx->Texture.Unit[u].CurrentCubeMap->RefCount--;
-      ctx->Texture.Unit[u].CurrentRect->RefCount--;
-      ctx->Texture.Unit[u].Current1DArray->RefCount--;
-      ctx->Texture.Unit[u].Current2DArray->RefCount--;
+      /* remove saved references to the texture objects */
+      _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL);
    }
+
+   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
+
+   _mesa_unlock_context_textures(ctx);
 }
 
 
@@ -1202,9 +1244,9 @@ _mesa_PopAttrib(void)
          case GL_TEXTURE_BIT:
             /* Take care of texture object reference counters */
             {
-               const struct gl_texture_attrib *texture;
-               texture = (const struct gl_texture_attrib *) attr->data;
-               pop_texture_group(ctx, texture);
+               struct texture_state *texstate
+                  = (struct texture_state *) attr->data;
+               pop_texture_group(ctx, texstate);
               ctx->NewState |= _NEW_TEXTURE;
             }
             break;
@@ -1426,6 +1468,46 @@ _mesa_PopClientAttrib(void)
 }
 
 
+/**
+ * Free any attribute state data that might be attached to the context.
+ */
+void
+_mesa_free_attrib_data(GLcontext *ctx)
+{
+   while (ctx->AttribStackDepth > 0) {
+      struct gl_attrib_node *attr, *next;
+
+      ctx->AttribStackDepth--;
+      attr = ctx->AttribStack[ctx->AttribStackDepth];
+
+      while (attr) {
+         if (attr->kind == GL_TEXTURE_BIT) {
+            struct texture_state *texstate = (struct texture_state*)attr->data;
+            GLuint u;
+            /* clear references to the saved texture objects */
+            for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+               _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL);
+            }
+         }
+         else {
+            /* any other chunks of state that requires special handling? */
+         }
+
+         next = attr->next;
+         _mesa_free(attr->data);
+         _mesa_free(attr);
+         attr = next;
+      }
+   }
+}
+
+
 void _mesa_init_attrib( GLcontext *ctx )
 {
    /* Renderer and client attribute stacks */
index 09d75196b23b294237e496b0c3aca2c86a0a84a9..2cf8fe693453a12414cb468f85be3714c966d3ab 100644 (file)
@@ -1,18 +1,8 @@
-/**
- * \file attrib.h
- * Attribute stacks.
- * 
- * \if subset
- * (No-op)
- *
- * \endif
- */
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -32,8 +22,6 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-
-
 #ifndef ATTRIB_H
 #define ATTRIB_H
 
@@ -58,10 +46,14 @@ _mesa_PopClientAttrib( void );
 extern void 
 _mesa_init_attrib( GLcontext *ctx );
 
+extern void 
+_mesa_free_attrib_data( GLcontext *ctx );
+
 #else
 
 /** No-op */
 #define _mesa_init_attrib( c ) ((void)0)
+#define _mesa_free_attrib_data( c ) ((void)0)
 
 #endif
 
index 37a14d3004263e771ef76c1182517093119ac98c..f3141fe63e8baccd96e8e3bc59deb2f0d9eaf7fe 100644 (file)
@@ -6,9 +6,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1209,6 +1209,7 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_unreference_framebuffer(&ctx->DrawBuffer);
    _mesa_unreference_framebuffer(&ctx->ReadBuffer);
 
+   _mesa_free_attrib_data(ctx);
    _mesa_free_lighting_data( ctx );
    _mesa_free_eval_data( ctx );
    _mesa_free_texture_data( ctx );
index ea3328a047ec0e812e880afe82097a2adbe175b4..3e017c1eda1548d379c2bd44eea8dac9909d489d 100644 (file)
@@ -5,9 +5,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -152,10 +152,6 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
 {
    GLuint i, face;
 
-   /*
-   printf("TEX DELETE %p (%u)\n", (void*) texObj, texObj->Name);
-   */
-
    (void) ctx;
 
    /* Set Target to an invalid value.  With some assertions elsewhere
@@ -195,6 +191,7 @@ void
 _mesa_copy_texture_object( struct gl_texture_object *dest,
                            const struct gl_texture_object *src )
 {
+   dest->Target = src->Target;
    dest->Name = src->Name;
    dest->Priority = src->Priority;
    dest->BorderColor[0] = src->BorderColor[0];
@@ -278,10 +275,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
       _glthread_LOCK_MUTEX(oldTex->Mutex);
       ASSERT(oldTex->RefCount > 0);
       oldTex->RefCount--;
-      /*
-      printf("TEX DECR %p (%u) to %d\n",
-             (void*) oldTex, oldTex->Name, oldTex->RefCount);
-      */
+
       deleteFlag = (oldTex->RefCount == 0);
       _glthread_UNLOCK_MUTEX(oldTex->Mutex);
 
@@ -309,10 +303,6 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
       }
       else {
          tex->RefCount++;
-         /*
-           printf("TEX INCR %p (%u) to %d\n",
-           (void*) tex, tex->Name, tex->RefCount);
-         */
          *ptr = tex;
       }
       _glthread_UNLOCK_MUTEX(tex->Mutex);
@@ -805,7 +795,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
             _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
 
-            /* Unrefernce the texobj.  If refcount hits zero, the texture
+            /* Unreference the texobj.  If refcount hits zero, the texture
              * will be deleted.
              */
             _mesa_reference_texobj(&delObj, NULL);
index 08d083d201b68bf57541a472636563a17cc8ff11..91ee6513dcf56026adcef41f2c0c57253a87755a 100644 (file)
@@ -119,20 +119,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
       /* copy texture object bindings, not contents of texture objects */
       _mesa_lock_context_textures(dst);
 
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
-                              src->Texture.Unit[i].Current1D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
-                              src->Texture.Unit[i].Current2D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
-                              src->Texture.Unit[i].Current3D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
-                              src->Texture.Unit[i].CurrentCubeMap);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
-                              src->Texture.Unit[i].CurrentRect);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray,
-                              src->Texture.Unit[i].Current1DArray);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray,
-                              src->Texture.Unit[i].Current2DArray);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
+                             src->Texture.Unit[i].Current1D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
+                             src->Texture.Unit[i].Current2D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
+                             src->Texture.Unit[i].Current3D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
+                             src->Texture.Unit[i].CurrentCubeMap);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
+                             src->Texture.Unit[i].CurrentRect);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray,
+                             src->Texture.Unit[i].Current1DArray);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray,
+                             src->Texture.Unit[i].Current2DArray);
 
       _mesa_unlock_context_textures(dst);
    }
@@ -3201,7 +3201,19 @@ _mesa_init_texture(GLcontext *ctx)
 void
 _mesa_free_texture_data(GLcontext *ctx)
 {
-   GLuint i;
+   GLuint u;
+
+   /* unreference current textures */
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+      struct gl_texture_unit *unit = ctx->Texture.Unit + u;
+      _mesa_reference_texobj(&unit->Current1D, NULL);
+      _mesa_reference_texobj(&unit->Current2D, NULL);
+      _mesa_reference_texobj(&unit->Current3D, NULL);
+      _mesa_reference_texobj(&unit->CurrentCubeMap, NULL);
+      _mesa_reference_texobj(&unit->CurrentRect, NULL);
+      _mesa_reference_texobj(&unit->Current1DArray, NULL);
+      _mesa_reference_texobj(&unit->Current2DArray, NULL);
+   }
 
    /* Free proxy texture objects */
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
@@ -3212,8 +3224,8 @@ _mesa_free_texture_data(GLcontext *ctx)
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1DArray );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2DArray );
 
-   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
-      _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
+      _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable );
 
    _mesa_TexEnvProgramCacheDestroy( ctx );
 }