add FreeTexImageData hook to help single-copy texturing in drivers
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 7ab5f48..69cc919 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -103,6 +103,7 @@
    driver->NewTextureObject = _mesa_new_texture_object;
    driver->DeleteTexture = _mesa_delete_texture_object;
    driver->NewTextureImage = _mesa_new_texture_image;
+   driver->FreeTexImageData = _mesa_free_texture_image_data; 
    driver->IsTextureResident = NULL;
    driver->PrioritizeTexture = NULL;
    driver->ActiveTexture = NULL;
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 69610e4..a1e40e9 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1536,6 +1536,7 @@
 {
    ASSERT(driverContext);
    assert(driverFunctions->NewTextureObject);
+   assert(driverFunctions->FreeTexImageData);
 
    /* If the driver wants core Mesa to use special imports, it'll have to
     * override these defaults.
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 312631a..1d9d366 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -511,6 +511,11 @@
     */
    struct gl_texture_image * (*NewTextureImage)( GLcontext *ctx );
 
+   /** 
+    * Called to free tImage->Data.
+    */
+   void (*FreeTexImageData)( GLcontext *ctx, struct gl_texture_image *tImage );
+
    /**
     * Called by glAreTextureResident().
     */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index ac9d92c..38c7d6b 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -571,21 +571,39 @@
 
 
 /**
+ * Free texture image data.
+ *
+ * \param teximage texture image.
+ *
+ * Free the texture image data if it's not marked as client data.
+ */
+void
+_mesa_free_texture_image_data( GLcontext *ctx, struct gl_texture_image *texImage )
+{
+   if (texImage->Data && !texImage->IsClientData) {
+      /* free the old texture data */
+      MESA_PBUFFER_FREE(texImage->Data);
+   }
+
+   texImage->Data = NULL;
+}
+
+
+/**
  * Free texture image.
  *
  * \param teximage texture image.
  *
- * Free the texture image structure and the associated image data if it's not
- * marked as client data.
+ * Free the texture image structure and the associated image data.
  */
 void
-_mesa_delete_texture_image( struct gl_texture_image *teximage )
+_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
 {
-   if (teximage->Data && !teximage->IsClientData) {
-      MESA_PBUFFER_FREE( teximage->Data );
-      teximage->Data = NULL;
+   if (texImage->Data) {
+      ctx->Driver.FreeTexImageData( ctx, texImage );
    }
-   FREE( teximage );
+   ASSERT(texImage->Data == NULL);
+   FREE( texImage );
 }
 
 
@@ -2024,11 +2042,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         /* free the old texture data */
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
       clear_teximage_fields(texImage); /* not really needed, but helpful */
       _mesa_init_teximage_fields(ctx, target, texImage,
                                  postConvWidth, 1, 1,
@@ -2124,11 +2141,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         /* free the old texture data */
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
       clear_teximage_fields(texImage); /* not really needed, but helpful */
       _mesa_init_teximage_fields(ctx, target, texImage,
                                  postConvWidth, postConvHeight, 1,
@@ -2220,10 +2236,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
       clear_teximage_fields(texImage); /* not really needed, but helpful */
       _mesa_init_teximage_fields(ctx, target, texImage,
                                  width, height, depth,
@@ -2460,11 +2476,10 @@
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
       return;
    }
-   else if (texImage->Data && !texImage->IsClientData) {
-      /* free the old texture data */
-      MESA_PBUFFER_FREE(texImage->Data);
+   else if (texImage->Data) {
+      ctx->Driver.FreeTexImageData( ctx, texImage );
    }
-   texImage->Data = NULL;
+   ASSERT(texImage->Data == NULL);
 
    clear_teximage_fields(texImage); /* not really needed, but helpful */
    _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
@@ -2523,11 +2538,10 @@
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
       return;
    }
-   else if (texImage->Data && !texImage->IsClientData) {
-      /* free the old texture data */
-      MESA_PBUFFER_FREE(texImage->Data);
+   else if (texImage->Data) {
+      ctx->Driver.FreeTexImageData( ctx, texImage );
    }
-   texImage->Data = NULL;
+   ASSERT(texImage->Data == NULL);
 
    clear_teximage_fields(texImage); /* not really needed, but helpful */
    _mesa_init_teximage_fields(ctx, target, texImage,
@@ -2873,10 +2887,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
 
       _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
                                  border, internalFormat);
@@ -2956,10 +2970,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
 
       _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
                                  border, internalFormat);
@@ -3038,10 +3052,10 @@
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
          return;
       }
-      else if (texImage->Data && !texImage->IsClientData) {
-         MESA_PBUFFER_FREE(texImage->Data);
+      else if (texImage->Data) {
+	 ctx->Driver.FreeTexImageData( ctx, texImage );
       }
-      texImage->Data = NULL;
+      ASSERT(texImage->Data == NULL);
 
       _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
                                  border, internalFormat);
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index d7b927f..5fb696a 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -47,7 +47,12 @@
 
 
 extern void
-_mesa_delete_texture_image( struct gl_texture_image *teximage );
+_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *teximage );
+
+
+extern void
+_mesa_free_texture_image_data( GLcontext *ctx, 
+			       struct gl_texture_image *texImage );
 
 
 extern void
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 488edab..5594cd9 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -144,7 +144,7 @@
    for (face = 0; face < 6; face++) {
       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
 	 if (texObj->Image[face][i]) {
-	    _mesa_delete_texture_image( texObj->Image[face][i] );
+	    _mesa_delete_texture_image( ctx, texObj->Image[face][i] );
 	 }
       }
    }