Overhaul of texture image handling.
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 6 Feb 2001 21:42:48 +0000 (21:42 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 6 Feb 2001 21:42:48 +0000 (21:42 +0000)
1. gl_texture_image struct's Data pointer points to images in driver's format.
2. Added FetchTexel() function pointer to struct gl_texture_image.
3. Changed Driver Tex[Sub]Image functions, return void now.
4. Texture storage/fetch code in new texstore.c file.
5. Removed texture.[ch] - functions moved to state.c

Note: FX driver updates not finished yet.

23 files changed:
src/mesa/Makefile.X11
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxddtex.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/osmesa/osmesa.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/main/Makefile.X11
src/mesa/main/context.c
src/mesa/main/dd.h
src/mesa/main/dlist.c
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/main/teximage.c
src/mesa/main/teximage.h
src/mesa/main/texstate.c
src/mesa/main/texstate.h
src/mesa/main/texstore.c [new file with mode: 0644]
src/mesa/main/texstore.h [new file with mode: 0644]
src/mesa/swrast/s_texture.c
src/mesa/swrast/s_triangle.c
src/mesa/swrast/s_tritemp.h
src/mesa/tnl/t_imm_exec.c
src/mesa/tnl/t_imm_fixup.c

index fe57194..f764cac 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.42 2001/02/03 08:41:03 gareth Exp $
+# $Id: Makefile.X11,v 1.43 2001/02/06 21:42:48 brianp Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -103,7 +103,7 @@ CORE_SOURCES = \
        teximage.c \
        texobj.c \
        texstate.c \
-       texture.c \
+       texstore.c \
        texutil.c \
        varray.c \
        vtxfmt.c \
index 1750778..d6ba79b 100644 (file)
@@ -1108,12 +1108,11 @@ void fxSetupDDPointers(GLcontext *ctx)
 
    ctx->Driver.TexImage2D = fxDDTexImage2D;
    ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
-   ctx->Driver.GetTexImage = fxDDGetTexImage;
-   ctx->Driver.TexEnv=fxDDTexEnv;
-   ctx->Driver.TexParameter=fxDDTexParam;
-   ctx->Driver.BindTexture=fxDDTexBind;
-   ctx->Driver.DeleteTexture=fxDDTexDel;
-   ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
+   ctx->Driver.TexEnv = fxDDTexEnv;
+   ctx->Driver.TexParameter = fxDDTexParam;
+   ctx->Driver.BindTexture = fxDDTexBind;
+   ctx->Driver.DeleteTexture = fxDDTexDel;
+   ctx->Driver.UpdateTexturePalette = fxDDTexPalette;
 
    ctx->Driver.AlphaFunc=fxDDAlphaFunc;
    ctx->Driver.BlendFunc=fxDDBlendFunc;
index 7c101e8..bc89917 100644 (file)
@@ -836,31 +836,29 @@ static void PrintTexture(int w, int h, int c, const GLubyte *data)
 }
 
 
-GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
-                         GLenum format, GLenum type, const GLvoid *pixels,
-                         const struct gl_pixelstore_attrib *packing,
-                         struct gl_texture_object *texObj,
-                         struct gl_texture_image *texImage,
-                         GLboolean *retainInternalCopy)
+void
+fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+               GLint internalFormat, GLint width, GLint height, GLint border,
+               GLenum format, GLenum type, const GLvoid *pixels,
+               const struct gl_pixelstore_attrib *packing,
+               struct gl_texture_object *texObj,
+               struct gl_texture_image *texImage)
 {
   fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
 
-  if (target != GL_TEXTURE_2D)
-    return GL_FALSE;
-
   if (!texObj->DriverData)
     texObj->DriverData = fxAllocTexObjData(fxMesa);
 
-  if (fxIsTexSupported(target, texImage->IntFormat, texImage)) {
+  if (fxIsTexSupported(target, internalFormat, texImage)) {
     GrTextureFormat_t gldformat;
     tfxTexInfo *ti = fxTMGetTexInfo(texObj);
     tfxMipMapLevel *mml = &ti->mipmapLevel[level];
     GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
     MesaIntTexFormat intFormat;
 
-    fxTexGetFormat(texImage->IntFormat, &gldformat, NULL);
+    fxTexGetFormat(internalFormat, &gldformat, NULL);
 
-    fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
+    fxTexGetInfo(width, height, NULL,NULL,NULL,NULL,
                  NULL,NULL, &wScale, &hScale);
     
     dstWidth = texImage->Width * wScale;
@@ -942,7 +940,7 @@ GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
         break;
       default:
         gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
-        return GL_FALSE;
+        return;
     }
 
     _mesa_set_teximage_component_sizes(intFormat, texImage);
@@ -955,7 +953,7 @@ GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
         FREE(mml->data);
       mml->data = MALLOC(dstWidth * dstHeight * texelSize);
       if (!mml->data)
-        return GL_FALSE;
+        return;
       mml->glideFormat = gldformat;
       mml->width = dstWidth;
       mml->height = dstHeight;
@@ -967,9 +965,9 @@ GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
     /* store the texture image */
     if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data,
                                 dstStride,
-                                texImage->Width, texImage->Height,
+                                width, height,
                                 format, type, pixels, packing)) {
-      return GL_FALSE;
+      return;
     }
     
 
@@ -981,24 +979,21 @@ GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
       /*printf("invalidate2\n");*/
       fxTexInvalidate(ctx,texObj);
     }
-
-    *retainInternalCopy = GL_FALSE;
-    return GL_TRUE;
   }
   else {
     gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
-    return GL_FALSE;
   }
 }
 
 
-GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
-                            GLint xoffset, GLint yoffset,
-                            GLsizei width, GLsizei height,
-                            GLenum format, GLenum type, const GLvoid *pixels,
-                            const struct gl_pixelstore_attrib *packing,
-                            struct gl_texture_object *texObj,
-                            struct gl_texture_image *texImage)
+void
+fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+                  GLint xoffset, GLint yoffset,
+                  GLsizei width, GLsizei height,
+                  GLenum format, GLenum type, const GLvoid *pixels,
+                  const struct gl_pixelstore_attrib *packing,
+                  struct gl_texture_object *texObj,
+                  struct gl_texture_image *texImage)
 {
   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
   tfxTexInfo *ti;
@@ -1006,11 +1001,10 @@ GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
   tfxMipMapLevel *mml;
   GLboolean result;
 
-  if (target != GL_TEXTURE_2D)
-    return GL_FALSE;
-
-  if (!texObj->DriverData)
-    return GL_FALSE;
+  if (!texObj->DriverData) {
+     gl_problem(ctx, "problem in fxDDTexSubImage2D");
+     return;
+  }
 
   ti = fxTMGetTexInfo(texObj);
   mml = &ti->mipmapLevel[level];
@@ -1083,7 +1077,7 @@ GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
   }
 
   if (!result) {
-    return GL_FALSE;
+     return;
   }
 
   if (ti->validated && ti->isInTM)
@@ -1091,11 +1085,10 @@ GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
   else
     fxTexInvalidate(ctx, texObj);
 
-  return GL_TRUE;
 }
 
 
-
+#if 000
 GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
                         const struct gl_texture_object *texObj,
                         GLenum *formatOut, GLenum *typeOut,
@@ -1174,6 +1167,8 @@ GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
     return NULL;
   }
 }
+#endif
+
 
 
 #else
index 6861160..c8876f7 100644 (file)
@@ -60,7 +60,6 @@
 #include "macros.h"
 #include "matrix.h"
 #include "mem.h"
-#include "texture.h"
 #include "mtypes.h"
 
 #include "GL/fxmesa.h"
@@ -541,23 +540,20 @@ extern void fxUpdateDDSpanPointers(GLcontext *);
 extern void fxSetupDDSpanPointers(GLcontext *);
 
 extern void fxPrintTextureData(tfxTexInfo *ti);
-extern GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
-                              GLenum format, GLenum type, const GLvoid *pixels,
-                              const struct gl_pixelstore_attrib *packing,
-                              struct gl_texture_object *texObj,
-                              struct gl_texture_image *texImage,
-                              GLboolean *retainInternalCopy);
-extern GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+extern void fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+               GLint internalFormat, GLint width, GLint height, GLint border,
+               GLenum format, GLenum type, const GLvoid *pixels,
+               const struct gl_pixelstore_attrib *packing,
+               struct gl_texture_object *texObj,
+               struct gl_texture_image *texImage);
+
+extern void fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
                               GLint xoffset, GLint yoffset,
                               GLsizei width, GLsizei height,
                               GLenum format, GLenum type, const GLvoid *pixels,
                               const struct gl_pixelstore_attrib *packing,
                               struct gl_texture_object *texObj,
                               struct gl_texture_image *texImage);
-extern GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
-                               const struct gl_texture_object *texObj,
-                               GLenum *formatOut, GLenum *typeOut,
-                               GLboolean *freeImageOut );
 extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *);
 extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *,
                         GLenum, const GLfloat *);
index ac155a8..2656b55 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: osmesa.c,v 1.43 2001/01/29 20:56:32 keithw Exp $ */
+/* $Id: osmesa.c,v 1.44 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  */
 
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
 #include "glheader.h"
 #include "GL/osmesa.h"
 #include "context.h"
 #include "colormac.h"
 #include "depth.h"
+#include "extensions.h"
 #include "macros.h"
-#include "mem.h"
 #include "matrix.h"
+#include "mem.h"
 #include "mmath.h"
 #include "mtypes.h"
-#include "extensions.h"
+#include "texstore.h"
+#include "array_cache/acache.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "swrast/s_context.h"
@@ -56,9 +55,6 @@
 #include "swrast/s_lines.h"
 #include "swrast/s_triangle.h"
 #include "tnl/tnl.h"
-#include "array_cache/acache.h"
-#endif
-
 
 
 
@@ -1784,6 +1780,14 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
 
    ctx->Driver.GetBufferSize = buffer_size;
 
+   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+   ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
    ctx->Driver.PointsFunc = _swsetup_Points;
    ctx->Driver.LineFunc = _swsetup_Line;
    ctx->Driver.TriangleFunc = _swsetup_Triangle;
index f7530d9..424d0fb 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: xm_dd.c,v 1.13 2001/01/29 20:56:32 keithw Exp $ */
+/* $Id: xm_dd.c,v 1.14 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  3.5
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  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"),
 
 #include "glxheader.h"
 #include "context.h"
-#include "drawpix.h"
-#include "mem.h"
-#include "state.h"
 #include "depth.h"
+#include "drawpix.h"
+#include "extensions.h"
 #include "macros.h"
+#include "mem.h"
 #include "mtypes.h"
+#include "state.h"
+#include "texstore.h"
 #include "xmesaP.h"
-#include "extensions.h"
+#include "array_cache/acache.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
-#include "array_cache/acache.h"
+
 
 /*
  * Return the size (width,height of the current color buffer.
@@ -955,7 +957,16 @@ void xmesa_init_pointers( GLcontext *ctx )
    ctx->Driver.DrawPixels = _swrast_DrawPixels;
    ctx->Driver.ReadPixels = _swrast_ReadPixels;
 
-   
+   /* Software texture functions:
+    */
+   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+   ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
    /* 
     */
    ctx->Driver.SetDrawBuffer = set_draw_buffer;
index fe57194..f764cac 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.42 2001/02/03 08:41:03 gareth Exp $
+# $Id: Makefile.X11,v 1.43 2001/02/06 21:42:48 brianp Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -103,7 +103,7 @@ CORE_SOURCES = \
        teximage.c \
        texobj.c \
        texstate.c \
-       texture.c \
+       texstore.c \
        texutil.c \
        varray.c \
        vtxfmt.c \
index da765e2..c044a6a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.119 2001/01/24 04:56:19 brianp Exp $ */
+/* $Id: context.c,v 1.120 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -51,7 +51,6 @@
 #include "state.h"
 #include "teximage.h"
 #include "texobj.h"
-#include "texture.h"
 #include "mtypes.h"
 #include "varray.h"
 
index 417beed..4d42649 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dd.h,v 1.50 2001/02/06 04:06:34 keithw Exp $ */
+/* $Id: dd.h,v 1.51 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -447,24 +447,27 @@ struct dd_function_table {
    /***
     *** Texture image functions:
     ***/
-   GLboolean (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level,
-                            GLenum format, GLenum type, const GLvoid *pixels,
-                            const struct gl_pixelstore_attrib *packing,
-                            struct gl_texture_object *texObj,
-                            struct gl_texture_image *texImage,
-                            GLboolean *retainInternalCopy );
-   GLboolean (*TexImage2D)( GLcontext *ctx, GLenum target, GLint level,
-                            GLenum format, GLenum type, const GLvoid *pixels,
-                            const struct gl_pixelstore_attrib *packing,
-                            struct gl_texture_object *texObj,
-                            struct gl_texture_image *texImage,
-                            GLboolean *retainInternalCopy );
-   GLboolean (*TexImage3D)( GLcontext *ctx, GLenum target, GLint level,
-                            GLenum format, GLenum type, const GLvoid *pixels,
-                            const struct gl_pixelstore_attrib *packing,
-                            struct gl_texture_object *texObj,
-                            struct gl_texture_image *texImage,
-                            GLboolean *retainInternalCopy );
+   void (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint border,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage );
+   void (*TexImage2D)( GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint border,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage );
+   void (*TexImage3D)( GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint depth, GLint border,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage );
    /* Called by glTexImage1/2/3D.
     * Will not be called if any glPixelTransfer operations are enabled.
     * Arguments:
@@ -481,29 +484,29 @@ struct dd_function_table {
     * GLubytes.  It may be easier for the driver to handle then.
     */
 
-   GLboolean (*TexSubImage1D)( GLcontext *ctx, GLenum target, GLint level,
-                               GLint xoffset, GLsizei width,
-                               GLenum format, GLenum type,
-                               const GLvoid *pixels,
-                               const struct gl_pixelstore_attrib *packing,
-                               struct gl_texture_object *texObj,
-                               struct gl_texture_image *texImage );
-   GLboolean (*TexSubImage2D)( GLcontext *ctx, GLenum target, GLint level,
-                               GLint xoffset, GLint yoffset,
-                               GLsizei width, GLsizei height,
-                               GLenum format, GLenum type,
-                               const GLvoid *pixels,
-                               const struct gl_pixelstore_attrib *packing,
-                               struct gl_texture_object *texObj,
-                               struct gl_texture_image *texImage );
-   GLboolean (*TexSubImage3D)( GLcontext *ctx, GLenum target, GLint level,
-                               GLint xoffset, GLint yoffset, GLint zoffset,
-                               GLsizei width, GLsizei height, GLint depth,
-                               GLenum format, GLenum type,
-                               const GLvoid *pixels,
-                               const struct gl_pixelstore_attrib *packing,
-                               struct gl_texture_object *texObj,
-                               struct gl_texture_image *texImage );
+   void (*TexSubImage1D)( GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLsizei width,
+                          GLenum format, GLenum type,
+                          const GLvoid *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage );
+   void (*TexSubImage2D)( GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset,
+                          GLsizei width, GLsizei height,
+                          GLenum format, GLenum type,
+                          const GLvoid *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage );
+   void (*TexSubImage3D)( GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLsizei width, GLsizei height, GLint depth,
+                          GLenum format, GLenum type,
+                          const GLvoid *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage );
    /* Called by glTexSubImage1/2/3D.
     * Will not be called if any glPixelTransfer operations are enabled.
     * Arguments:
@@ -547,22 +550,6 @@ struct dd_function_table {
     * should do the job.
     */
 
-   GLvoid *(*GetTexImage)( GLcontext *ctx, GLenum target, GLint level,
-                           const struct gl_texture_object *texObj,
-                           GLenum *formatOut, GLenum *typeOut,
-                           GLboolean *freeImageOut );
-   /* Called by glGetTexImage or by core Mesa when a texture image
-    * is needed for software fallback rendering.
-    * Return the address of the texture image or NULL if failure.
-    * The image must be tightly packed (i.e. row stride = image width)
-    * Return the image's format and type in formatOut and typeOut.
-    * The format and type must be values which are accepted by glTexImage.
-    * Set the freeImageOut flag if the returned image should be deallocated
-    * with FREE() when finished.
-    * The size of the image can be deduced from the target and level.
-    * Core Mesa will perform any image format/type conversions that are needed.
-    */
-
    GLboolean (*TestProxyTexImage)(GLcontext *ctx, GLenum target,
                                   GLint level, GLint internalFormat,
                                   GLenum format, GLenum type,
@@ -577,24 +564,25 @@ struct dd_function_table {
     *** Compressed texture functions:
     ***/
 
-   GLboolean (*CompressedTexImage1D)( GLcontext *ctx, GLenum target,
-                                      GLint level, GLsizei imageSize,
-                                      const GLvoid *data,
-                                      struct gl_texture_object *texObj,
-                                      struct gl_texture_image *texImage,
-                                      GLboolean *retainInternalCopy);
-   GLboolean (*CompressedTexImage2D)( GLcontext *ctx, GLenum target,
-                                      GLint level, GLsizei imageSize,
-                                      const GLvoid *data,
-                                      struct gl_texture_object *texObj,
-                                      struct gl_texture_image *texImage,
-                                      GLboolean *retainInternalCopy);
-   GLboolean (*CompressedTexImage3D)( GLcontext *ctx, GLenum target,
-                                      GLint level, GLsizei imageSize,
-                                      const GLvoid *data,
-                                      struct gl_texture_object *texObj,
-                                      struct gl_texture_image *texImage,
-                                      GLboolean *retainInternalCopy);
+   void (*CompressedTexImage1D)( GLcontext *ctx, GLenum target,
+                                 GLint level, GLint internalFormat,
+                                 GLsizei width, GLint border,
+                                 GLsizei imageSize, const GLvoid *data,
+                                 struct gl_texture_object *texObj,
+                                 struct gl_texture_image *texImage );
+   void (*CompressedTexImage2D)( GLcontext *ctx, GLenum target,
+                                 GLint level, GLint internalFormat,
+                                 GLsizei width, GLsizei height, GLint border,
+                                 GLsizei imageSize, const GLvoid *data,
+                                 struct gl_texture_object *texObj,
+                                 struct gl_texture_image *texImage );
+   void (*CompressedTexImage3D)( GLcontext *ctx, GLenum target,
+                                 GLint level, GLint internalFormat,
+                                 GLsizei width, GLsizei height, GLsizei depth,
+                                 GLint border,
+                                 GLsizei imageSize, const GLvoid *data,
+                                 struct gl_texture_object *texObj,
+                                 struct gl_texture_image *texImage );
    /* Called by glCompressedTexImage1/2/3D.
     * Arguments:
     *   <target>, <level>, <internalFormat>, <data> are user specified.
@@ -607,27 +595,26 @@ struct dd_function_table {
     * should do the job.
     */
 
-   GLboolean (*CompressedTexSubImage1D)( GLcontext *ctx, GLenum target,
-                                         GLint level, GLint xoffset,
-                                         GLsizei width, GLenum format,
-                                         GLsizei imageSize, const GLvoid *data,
-                                         struct gl_texture_object *texObj,
-                                         struct gl_texture_image *texImage );
-   GLboolean (*CompressedTexSubImage2D)( GLcontext *ctx, GLenum target,
-                                         GLint level, GLint xoffset,
-                                         GLint yoffset, GLsizei width,
-                                         GLint height, GLenum format,
-                                         GLsizei imageSize, const GLvoid *data,
-                                         struct gl_texture_object *texObj,
-                                         struct gl_texture_image *texImage );
-   GLboolean (*CompressedTexSubImage3D)( GLcontext *ctx, GLenum target,
-                                         GLint level, GLint xoffset,
-                                         GLint yoffset, GLint zoffset,
-                                         GLsizei width, GLint height,
-                                         GLint depth, GLenum format,
-                                         GLsizei imageSize, const GLvoid *data,
-                                         struct gl_texture_object *texObj,
-                                         struct gl_texture_image *texImage );
+   void (*CompressedTexSubImage1D)(GLcontext *ctx, GLenum target, GLint level,
+                                   GLint xoffset, GLsizei width,
+                                   GLenum format,
+                                   GLsizei imageSize, const GLvoid *data,
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage);
+   void (*CompressedTexSubImage2D)(GLcontext *ctx, GLenum target, GLint level,
+                                   GLint xoffset, GLint yoffset,
+                                   GLsizei width, GLint height,
+                                   GLenum format,
+                                   GLsizei imageSize, const GLvoid *data,
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage);
+   void (*CompressedTexSubImage3D)(GLcontext *ctx, GLenum target, GLint level,
+                                   GLint xoffset, GLint yoffset, GLint zoffset,
+                                   GLsizei width, GLint height, GLint depth,
+                                   GLenum format,
+                                   GLsizei imageSize, const GLvoid *data,
+                                   struct gl_texture_object *texObj,
+                                   struct gl_texture_image *texImage);
    /* Called by glCompressedTexSubImage1/2/3D.
     * Arguments:
     *   <target>, <level>, <x/z/zoffset>, <width>, <height>, <depth>,
@@ -639,11 +626,30 @@ struct dd_function_table {
     * should do the job.
     */
 
+   GLboolean (*IsCompressedFormat)(GLcontext *ctx, GLint internalFormat);
+   /* Called to tell if a format is a compressed format.
+    */
+
+   void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target,
+                                  GLint lod, void *image,
+                                  const struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage );
+   /* Called by glGetCompressedTexImageARB.
+    * <target>, <lod>, <image> are specified by user.
+    * <texObj> is the source texture object.
+    * <texImage> is the source texture image.
+    */
+
    GLint (*BaseCompressedTexFormat)(GLcontext *ctx,
                                     GLint internalFormat);
    /* Called to compute the base format for a specific compressed
     * format.  Return -1 if the internalFormat is not a specific
-    * compressed format that the driver recognizes.  Note the
+    * compressed format that the driver recognizes.
+    * Example: if internalFormat==GL_COMPRESSED_RGB_FXT1_3DFX, return GL_RGB.
+    */
+
+#if 000
+   /* ... Note the
     * return value differences between this function and
     * SpecificCompressedTexFormat below.
     */
@@ -668,10 +674,6 @@ struct dd_function_table {
     * do the right thing with it.
     */
 
-   GLboolean (*IsCompressedFormat)(GLcontext *ctx, GLint internalFormat);
-   /* Called to tell if a format is a compressed format.
-    */
-
    GLsizei (*CompressedImageSize)(GLcontext *ctx,
                                   GLenum internalFormat,
                                   GLuint numDimensions,
@@ -681,16 +683,7 @@ struct dd_function_table {
    /* Calculate the size of a compressed image, given the image's
     * format and dimensions.
     */
-
-   void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target,
-                                  GLint lod, void *image,
-                                  const struct gl_texture_object *texObj,
-                                  struct gl_texture_image *texImage );
-   /* Called by glGetCompressedTexImageARB.
-    * <target>, <lod>, <image> are specified by user.
-    * <texObj> is the source texture object.
-    * <texImage> is the source texture image.
-    */
+#endif
 
    /***
     *** Texture object functions:
index 79ac03e..b979171 100644 (file)
@@ -1,8 +1,8 @@
-/* $Id: dlist.c,v 1.63 2001/01/24 04:56:20 brianp Exp $ */
+/* $Id: dlist.c,v 1.64 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.3
+ * Version:  3.5
  *
  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  *
@@ -1062,7 +1062,8 @@ static void save_ColorTable( GLenum target, GLenum internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    if (target == GL_PROXY_TEXTURE_1D ||
        target == GL_PROXY_TEXTURE_2D ||
-       target == GL_PROXY_TEXTURE_3D) {
+       target == GL_PROXY_TEXTURE_3D ||
+       target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
       /* execute immediately */
       (*ctx->Exec->ColorTable)( target, internalFormat, width,
                                 format, type, table );
index bc9eee7..2e0c1d1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.17 2001/01/29 20:47:39 keithw Exp $ */
+/* $Id: mtypes.h,v 1.18 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -116,6 +116,7 @@ typedef int GLfixed;
  * Some forward type declarations
  */
 struct _mesa_HashTable;
+struct gl_texture_image;
 struct gl_texture_object;
 typedef struct __GLcontextRec GLcontext;
 typedef struct __GLcontextModesRec GLvisual;
@@ -764,12 +765,21 @@ struct gl_stencil_attrib {
 #define ENABLE_TEXGEN(i) (ENABLE_TEXGEN0 << (i))
 #define ENABLE_TEXMAT(i) (ENABLE_TEXMAT0 << (i))
 
+
+typedef void (*FetchTexelFunc)( GLcontext *ctx,
+                                const struct gl_texture_object *texObject,
+                                const struct gl_texture_image *texImage,
+                                GLint col, GLint row, GLint img,
+                                GLchan texel[] );
+
+
 /* Texture image record */
 struct gl_texture_image {
    GLenum Format;              /* GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
                                 * GL_INTENSITY, GL_RGB, GL_RGBA, or
                                 * GL_COLOR_INDEX only
                                 */
+   GLenum Type;                        /* Texel type: GL_UNSIGNED_BYTE, etc. */
    GLenum IntFormat;           /* Internal format as given by the user */
    GLubyte RedBits;            /* Bits per texel component              */
    GLubyte GreenBits;          /*   These are initialized by Mesa but   */
@@ -789,7 +799,9 @@ struct gl_texture_image {
    GLuint HeightLog2;          /* = log2(Height2) */
    GLuint DepthLog2;           /* = log2(Depth2) */
    GLuint MaxLog2;             /* = MAX(WidthLog2, HeightLog2) */
-   GLchan *Data;               /* Image data as GLchan's */
+   GLvoid *Data;               /* Image data, accessed via FetchTexel() */
+
+   FetchTexelFunc FetchTexel;  /* texel fetch function pointer */
 
    GLboolean IsCompressed;     /* GL_ARB_texture_compression */
    GLuint CompressedSize;      /* GL_ARB_texture_compression */
index cdfce63..f52fba3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: state.c,v 1.55 2001/01/24 04:56:20 brianp Exp $ */
+/* $Id: state.c,v 1.56 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -74,7 +74,6 @@
 #include "teximage.h"
 #include "texobj.h"
 #include "texstate.h"
-#include "texture.h"
 #include "mtypes.h"
 #include "varray.h"
 #include "winpos.h"
@@ -697,6 +696,159 @@ update_image_transfer_state(GLcontext *ctx)
 }
 
 
+
+
+/* Note: This routine refers to derived texture attribute values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_textures(), below.
+ *
+ * If both TEXTURE and TEXTURE_MATRIX change at once, these values
+ * will be computed twice.
+ */
+static void
+update_texture_matrices( GLcontext *ctx )
+{
+   GLuint i;
+
+   ctx->_Enabled &= ~ENABLE_TEXMAT_ANY;
+
+   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+      if (ctx->TextureMatrix[i].flags & MAT_DIRTY) {
+        _math_matrix_analyse( &ctx->TextureMatrix[i] );
+
+        if (ctx->Driver.TextureMatrix)
+           ctx->Driver.TextureMatrix( ctx, i, &ctx->TextureMatrix[i] );
+
+        if (ctx->Texture.Unit[i]._ReallyEnabled &&
+            ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+           ctx->_Enabled |= ENABLE_TEXMAT0 << i;
+      }
+   }
+}
+
+
+/* Note: This routine refers to derived texture matrix values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_texture_matrices, above.
+ *
+ * If both TEXTURE and TEXTURE_MATRIX change at once, these values
+ * will be computed twice.
+ */
+static void
+update_texture_state( GLcontext *ctx )
+{
+   GLuint i;
+
+   ctx->Texture._ReallyEnabled = 0;
+   ctx->Texture._GenFlags = 0;
+   ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN;
+   ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN;
+   ctx->_Enabled &= ~(ENABLE_TEXGEN_ANY |
+                     ENABLE_TEXMAT_ANY);
+
+   /* Update texture unit state.
+    */
+   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+
+      texUnit->_ReallyEnabled = 0;
+      texUnit->_GenFlags = 0;
+
+      if (!texUnit->Enabled)
+        continue;
+
+      /* Find the texture of highest dimensionality that is enabled
+       * and complete.  We'll use it for texturing.
+       */
+      if (texUnit->Enabled & TEXTURE0_CUBE) {
+         struct gl_texture_object *texObj = texUnit->CurrentCubeMap;
+         if (!texObj->Complete) {
+            _mesa_test_texobj_completeness(ctx, texObj);
+         }
+         if (texObj->Complete) {
+            texUnit->_ReallyEnabled = TEXTURE0_CUBE;
+            texUnit->_Current = texObj;
+         }
+      }
+
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_3D)) {
+         struct gl_texture_object *texObj = texUnit->Current3D;
+         if (!texObj->Complete) {
+            _mesa_test_texobj_completeness(ctx, texObj);
+         }
+         if (texObj->Complete) {
+            texUnit->_ReallyEnabled = TEXTURE0_3D;
+            texUnit->_Current = texObj;
+         }
+      }
+
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_2D)) {
+         struct gl_texture_object *texObj = texUnit->Current2D;
+         if (!texObj->Complete) {
+            _mesa_test_texobj_completeness(ctx, texObj);
+         }
+         if (texObj->Complete) {
+            texUnit->_ReallyEnabled = TEXTURE0_2D;
+            texUnit->_Current = texObj;
+         }
+      }
+
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_1D)) {
+         struct gl_texture_object *texObj = texUnit->Current1D;
+         if (!texObj->Complete) {
+            _mesa_test_texobj_completeness(ctx, texObj);
+         }
+         if (texObj->Complete) {
+            texUnit->_ReallyEnabled = TEXTURE0_1D;
+            texUnit->_Current = texObj;
+         }
+      }
+
+      if (!texUnit->_ReallyEnabled) {
+        texUnit->_Current = NULL;
+        continue;
+      }
+
+      {
+        GLuint flag = texUnit->_ReallyEnabled << (i * 4);
+        ctx->Texture._ReallyEnabled |= flag;
+      }
+
+      if (texUnit->TexGenEnabled) {
+        if (texUnit->TexGenEnabled & S_BIT) {
+           texUnit->_GenFlags |= texUnit->_GenBitS;
+        }
+        if (texUnit->TexGenEnabled & T_BIT) {
+           texUnit->_GenFlags |= texUnit->_GenBitT;
+        }
+        if (texUnit->TexGenEnabled & Q_BIT) {
+           texUnit->_GenFlags |= texUnit->_GenBitQ;
+        }
+        if (texUnit->TexGenEnabled & R_BIT) {
+           texUnit->_GenFlags |= texUnit->_GenBitR;
+        }
+
+        ctx->_Enabled |= ENABLE_TEXGEN0 << i;
+        ctx->Texture._GenFlags |= texUnit->_GenFlags;
+      }
+
+      if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+        ctx->_Enabled |= ENABLE_TEXMAT0 << i;
+   }
+
+   if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) {
+      ctx->_NeedNormals |= NEED_NORMALS_TEXGEN;
+      ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
+   }
+
+   if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) {
+      ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
+   }
+}
+
+
 /*
  * If ctx->NewState is non-zero then this function MUST be called before
  * rendering any primitive.  Basically, function pointers and miscellaneous
@@ -729,7 +881,7 @@ void gl_update_state( GLcontext *ctx )
       update_projection( ctx );
 
    if (new_state & _NEW_TEXTURE_MATRIX)
-      _mesa_update_texture_matrices( ctx );
+      update_texture_matrices( ctx );
 
    if (new_state & _NEW_COLOR_MATRIX)
       _math_matrix_analyse( &ctx->ColorMatrix );
@@ -742,7 +894,7 @@ void gl_update_state( GLcontext *ctx )
    /* Contributes to NeedEyeCoords, NeedNormals.
     */
    if (new_state & _NEW_TEXTURE)
-      _mesa_update_texture_state( ctx );
+      update_texture_state( ctx );
 
    if (new_state & (_NEW_BUFFERS|_NEW_SCISSOR))
       update_drawbuffer( ctx );
index 9e2609d..b75eb6a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teximage.c,v 1.70 2001/01/23 23:35:23 brianp Exp $ */
+/* $Id: teximage.c,v 1.71 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -218,78 +218,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
 
 
 /*
- * Given an internal texture format enum or 1, 2, 3, 4 return the
- * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
- * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
- * number of components for the format.  Return -1 if invalid enum.
- */
-static GLint
-components_in_intformat( GLint format )
-{
-   switch (format) {
-      case GL_ALPHA:
-      case GL_ALPHA4:
-      case GL_ALPHA8:
-      case GL_ALPHA12:
-      case GL_ALPHA16:
-         return 1;
-      case 1:
-      case GL_LUMINANCE:
-      case GL_LUMINANCE4:
-      case GL_LUMINANCE8:
-      case GL_LUMINANCE12:
-      case GL_LUMINANCE16:
-         return 1;
-      case 2:
-      case GL_LUMINANCE_ALPHA:
-      case GL_LUMINANCE4_ALPHA4:
-      case GL_LUMINANCE6_ALPHA2:
-      case GL_LUMINANCE8_ALPHA8:
-      case GL_LUMINANCE12_ALPHA4:
-      case GL_LUMINANCE12_ALPHA12:
-      case GL_LUMINANCE16_ALPHA16:
-         return 2;
-      case GL_INTENSITY:
-      case GL_INTENSITY4:
-      case GL_INTENSITY8:
-      case GL_INTENSITY12:
-      case GL_INTENSITY16:
-         return 1;
-      case 3:
-      case GL_RGB:
-      case GL_R3_G3_B2:
-      case GL_RGB4:
-      case GL_RGB5:
-      case GL_RGB8:
-      case GL_RGB10:
-      case GL_RGB12:
-      case GL_RGB16:
-         return 3;
-      case 4:
-      case GL_RGBA:
-      case GL_RGBA2:
-      case GL_RGBA4:
-      case GL_RGB5_A1:
-      case GL_RGBA8:
-      case GL_RGB10_A2:
-      case GL_RGBA12:
-      case GL_RGBA16:
-         return 4;
-      case GL_COLOR_INDEX:
-      case GL_COLOR_INDEX1_EXT:
-      case GL_COLOR_INDEX2_EXT:
-      case GL_COLOR_INDEX4_EXT:
-      case GL_COLOR_INDEX8_EXT:
-      case GL_COLOR_INDEX12_EXT:
-      case GL_COLOR_INDEX16_EXT:
-         return 1;
-      default:
-         return -1;  /* error */
-   }
-}
-
-
-/*
  * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
  * otherwise.
  */
@@ -305,115 +233,11 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat)
 
 
 /*
- * Examine the texImage->Format field and set the Red, Green, Blue, etc
- * texel component sizes to default values.
- * These fields are set only here by core Mesa but device drivers may
- * overwritting these fields to indicate true texel resolution.
+ * Store a gl_texture_image pointer in a gl_texture_object structure
+ * according to the target and level parameters.
+ * This was basically prompted by the introduction of cube maps.
  */
 static void
-set_teximage_component_sizes( struct gl_texture_image *texImage )
-{
-   switch (texImage->Format) {
-      case GL_ALPHA:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 8;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_LUMINANCE:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 8;
-         texImage->IndexBits = 0;
-         break;
-      case GL_LUMINANCE_ALPHA:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 8;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 8;
-         texImage->IndexBits = 0;
-         break;
-      case GL_INTENSITY:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 8;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_RED:
-         texImage->RedBits = 8;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_GREEN:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 8;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_BLUE:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 8;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_RGB:
-      case GL_BGR:
-         texImage->RedBits = 8;
-         texImage->GreenBits = 8;
-         texImage->BlueBits = 8;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_RGBA:
-      case GL_BGRA:
-      case GL_ABGR_EXT:
-         texImage->RedBits = 8;
-         texImage->GreenBits = 8;
-         texImage->BlueBits = 8;
-         texImage->AlphaBits = 8;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 0;
-         break;
-      case GL_COLOR_INDEX:
-         texImage->RedBits = 0;
-         texImage->GreenBits = 0;
-         texImage->BlueBits = 0;
-         texImage->AlphaBits = 0;
-         texImage->IntensityBits = 0;
-         texImage->LuminanceBits = 0;
-         texImage->IndexBits = 8;
-         break;
-      default:
-         gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
-   }
-}
-
-
-static void
 set_tex_image(struct gl_texture_object *tObj,
               GLenum target, GLint level,
               struct gl_texture_image *texImage)
@@ -449,6 +273,7 @@ set_tex_image(struct gl_texture_object *tObj,
 }
 
 
+
 /*
  * Return new gl_texture_image struct with all fields initialized to zero.
  */
@@ -460,42 +285,6 @@ _mesa_alloc_texture_image( void )
 
 
 
-/*
- * Initialize most fields of a gl_texture_image struct.
- */
-static void
-init_texture_image( GLcontext *ctx,
-                    struct gl_texture_image *img,
-                    GLsizei width, GLsizei height, GLsizei depth,
-                    GLint border, GLenum internalFormat )
-{
-   ASSERT(img);
-   ASSERT(!img->Data);
-   img->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
-   set_teximage_component_sizes( img );
-   img->IntFormat = (GLenum) internalFormat;
-   img->Border = border;
-   img->Width = width;
-   img->Height = height;
-   img->Depth = depth;
-   img->WidthLog2 = logbase2(width - 2 * border);
-   if (height == 1)  /* 1-D texture */
-      img->HeightLog2 = 0;
-   else
-      img->HeightLog2 = logbase2(height - 2 * border);
-   if (depth == 1)   /* 2-D texture */
-      img->DepthLog2 = 0;
-   else
-      img->DepthLog2 = logbase2(depth - 2 * border);
-   img->Width2 = 1 << img->WidthLog2;
-   img->Height2 = 1 << img->HeightLog2;
-   img->Depth2 = 1 << img->DepthLog2;
-   img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
-   img->IsCompressed = is_compressed_format(ctx, internalFormat);
-}
-
-
-
 void
 _mesa_free_texture_image( struct gl_texture_image *teximage )
 {
@@ -507,33 +296,19 @@ _mesa_free_texture_image( struct gl_texture_image *teximage )
 }
 
 
-
 /*
- * Return number of bytes of storage needed to store a compressed texture
- * image.  Only the driver knows for sure.  If the driver can't help us,
- * we must return 0.
+ * Return GL_TRUE if the target is a proxy target.
  */
-GLuint
-_mesa_compressed_image_size(GLcontext *ctx,
-                            GLenum internalFormat,
-                            GLint numDimensions,
-                            GLint width,
-                            GLint height,
-                            GLint depth)
+static GLboolean
+is_proxy_target(GLenum target)
 {
-   if (ctx->Driver.CompressedImageSize) {
-      return (*ctx->Driver.CompressedImageSize)(ctx, internalFormat,
-                                                numDimensions,
-                                                width, height, depth);
-   }
-   else {
-      /* Shouldn't this be an internal error of some sort? */
-      return 0;
-   }
+   return (target == GL_PROXY_TEXTURE_1D ||
+           target == GL_PROXY_TEXTURE_2D ||
+           target == GL_PROXY_TEXTURE_3D ||
+           target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
 }
 
 
-
 /*
  * Given a texture unit and a texture target, return the corresponding
  * texture object.
@@ -639,339 +414,23 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
 
 
 /*
- * Calling glTexImage and related functions when convolution is enabled
- * with GL_REDUCE border mode causes some complications.
- * The incoming image must be extra large so that the post-convolution
- * image size is reduced to a power of two size (plus 2 * border).
- * This function adjusts a texture width and height accordingly if
- * convolution with GL_REDUCE is enabled.
- */
-static void
-adjust_texture_size_for_convolution(const GLcontext *ctx, GLuint dimensions,
-                                    GLsizei *width, GLsizei *height)
-{
-   if (ctx->Pixel.Convolution1DEnabled
-       && dimensions == 1
-       && ctx->Pixel.ConvolutionBorderMode[0] == GL_REDUCE) {
-      *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1);
-   }
-   else if (ctx->Pixel.Convolution2DEnabled
-            && dimensions > 1
-            && ctx->Pixel.ConvolutionBorderMode[1] == GL_REDUCE) {
-      *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1);
-      *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1);
-   }
-   else if (ctx->Pixel.Separable2DEnabled
-            && dimensions > 1
-            && ctx->Pixel.ConvolutionBorderMode[2] == GL_REDUCE) {
-      *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1);
-      *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
-   }
-}
-
-
-
-/*
- * This function is used to move user image data into a texture image.
- * We handle full texture images and subtexture images.  We also take
- * care of all image transfer operations here, including convolution.
- * Input:
- *         dstXoffset, dstYoffset, dstZoffset - offsets in pixels
- *         dstRowStride, dstImageStride - strides in GLchan's
- */
-static void
-fill_texture_image( GLcontext *ctx, GLuint dimensions,
-                    GLenum texFormat, GLchan *texAddr,
-                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                    GLint dstRowStride, GLint dstImageStride,
-                    GLenum srcFormat, GLenum srcType, const GLvoid *srcAddr,
-                    const struct gl_pixelstore_attrib *srcPacking)
-{
-   GLint texComponents;
-
-   ASSERT(ctx);
-   ASSERT(dimensions >= 1 && dimensions <= 3);
-   ASSERT(texAddr);
-   ASSERT(srcWidth >= 1);
-   ASSERT(srcHeight >= 1);
-   ASSERT(srcDepth >= 1);
-   ASSERT(dstXoffset >= 0);
-   ASSERT(dstYoffset >= 0);
-   ASSERT(dstZoffset >= 0);
-   ASSERT(dstRowStride >= 0);
-   ASSERT(dstImageStride >= 0);
-   ASSERT(srcAddr);
-   ASSERT(srcPacking);
-
-   texComponents = components_in_intformat(texFormat);
-
-   /* try common 2D texture cases first */
-   if (!ctx->_ImageTransferState && dimensions == 2
-       && srcType == GL_UNSIGNED_BYTE) {
-
-      if (srcFormat == texFormat) {
-         /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
-          * GL_LUMINANCE_ALPHA, etc. texture formats.  Use memcpy().
-          */
-         const GLchan *src = (const GLchan *) _mesa_image_address(
-                                   srcPacking, srcAddr, srcWidth, srcHeight,
-                                   srcFormat, srcType, 0, 0, 0);
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                               srcWidth, srcFormat, srcType);
-         const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
-         GLchan *dst = texAddr + dstYoffset * dstRowStride
-                      + dstXoffset * texComponents;
-         if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
-            MEMCPY(dst, src, srcHeight * widthInBytes);
-         }
-         else {
-            GLint i;
-            for (i = 0; i < srcHeight; i++) {
-               MEMCPY(dst, src, widthInBytes);
-               src += srcRowStride;
-               dst += dstRowStride;
-            }
-         }
-         return;  /* all done */
-      }
-      else if (srcFormat == GL_RGBA && texFormat == GL_RGB) {
-         /* commonly used by Quake */
-         const GLchan *src = (const GLchan *) _mesa_image_address(
-                                   srcPacking, srcAddr, srcWidth, srcHeight,
-                                   srcFormat, srcType, 0, 0, 0);
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                               srcWidth, srcFormat, srcType);
-         GLchan *dst = texAddr + dstYoffset * dstRowStride
-                      + dstXoffset * texComponents;
-         GLint i, j;
-         for (i = 0; i < srcHeight; i++) {
-            const GLchan *s = src;
-            GLchan *d = dst;
-            for (j = 0; j < srcWidth; j++) {
-               *d++ = *s++;  /*red*/
-               *d++ = *s++;  /*green*/
-               *d++ = *s++;  /*blue*/
-               s++;          /*alpha*/
-            }
-            src += srcRowStride;
-            dst += dstRowStride;
-         }
-         return;  /* all done */
-      }
-   }
-
-   /*
-    * General case solutions
-    */
-   if (texFormat == GL_COLOR_INDEX) {
-      /* color index texture */
-      const GLenum texType = GL_UNSIGNED_BYTE;
-      GLint img, row;
-      GLchan *dest = texAddr + dstZoffset * dstImageStride
-                    + dstYoffset * dstRowStride
-                    + dstXoffset * texComponents;
-      for (img = 0; img < srcDepth; img++) {
-         GLchan *destRow = dest;
-         for (row = 0; row < srcHeight; row++) {
-            const GLvoid *src = _mesa_image_address(srcPacking,
-                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
-            _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
-                                    srcType, src, srcPacking,
-                                    ctx->_ImageTransferState);
-            destRow += dstRowStride;
-         }
-         dest += dstImageStride;
-      }
-   }
-   else {
-      /* regular, color texture */
-      if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
-          (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
-          (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
-         /*
-          * Fill texture image with convolution
-          */
-         GLint img, row;
-         GLint convWidth = srcWidth, convHeight = srcHeight;
-         GLfloat *tmpImage, *convImage;
-         tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
-         if (!tmpImage) {
-            gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
-            return;
-         }
-         convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
-         if (!convImage) {
-            gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
-            FREE(tmpImage);
-            return;
-         }
-
-         for (img = 0; img < srcDepth; img++) {
-            const GLfloat *srcf;
-            GLfloat *dstf = tmpImage;
-            GLchan *dest;
-
-            /* unpack and do transfer ops up to convolution */
-            for (row = 0; row < srcHeight; row++) {
-               const GLvoid *src = _mesa_image_address(srcPacking,
-                                              srcAddr, srcWidth, srcHeight,
-                                              srcFormat, srcType, img, row, 0);
-               _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
-                          srcFormat, srcType, src, srcPacking,
-                          ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
-                          GL_TRUE);
-               dstf += srcWidth * 4;
-            }
-
-            /* convolve */
-            if (dimensions == 1) {
-               ASSERT(ctx->Pixel.Convolution1DEnabled);
-               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
-            }
-            else {
-               if (ctx->Pixel.Convolution2DEnabled) {
-                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
-                                          tmpImage, convImage);
-               }
-               else {
-                  ASSERT(ctx->Pixel.Separable2DEnabled);
-                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
-                                           tmpImage, convImage);
-               }
-            }
-
-            /* packing and transfer ops after convolution */
-            srcf = convImage;
-            dest = texAddr + (dstZoffset + img) * dstImageStride
-                 + dstYoffset * dstRowStride;
-            for (row = 0; row < convHeight; row++) {
-               _mesa_pack_float_rgba_span(ctx, convWidth,
-                                          (const GLfloat (*)[4]) srcf,
-                                          texFormat, GL_UNSIGNED_BYTE,
-                                          dest, &_mesa_native_packing,
-                                          ctx->_ImageTransferState
-                                          & IMAGE_POST_CONVOLUTION_BITS);
-               srcf += convWidth * 4;
-               dest += dstRowStride;
-            }
-         }
-
-         FREE(convImage);
-         FREE(tmpImage);
-      }
-      else {
-         /*
-          * no convolution
-          */
-         GLint img, row;
-         GLchan *dest = texAddr + dstZoffset * dstImageStride
-                       + dstYoffset * dstRowStride
-                       + dstXoffset * texComponents;
-         for (img = 0; img < srcDepth; img++) {
-            GLchan *destRow = dest;
-            for (row = 0; row < srcHeight; row++) {
-               const GLvoid *srcRow = _mesa_image_address(srcPacking,
-                                              srcAddr, srcWidth, srcHeight,
-                                              srcFormat, srcType, img, row, 0);
-               _mesa_unpack_chan_color_span(ctx, srcWidth, texFormat, destRow,
-                                       srcFormat, srcType, srcRow, srcPacking,
-                                       ctx->_ImageTransferState);
-               destRow += dstRowStride;
-            }
-            dest += dstImageStride;
-         }
-      }
-   }
-}
-
-
-
-/* Need this to prevent an out-of-bounds memory access when using
- * X86 optimized code.
- */
-#ifdef USE_X86_ASM
-#  define EXTRA_BYTE sizeof(GLchan)
-#else
-#  define EXTRA_BYTE 0
-#endif
-
-
-
-/*
- * Called by glTexImage[123]D.  Fill in a texture image with data given
- * by the client.  All pixel transfer and unpack modes are handled here.
- * Input:  dimensions (1, 2, or 3)
- *         texImage - destination texture image (we'll malloc the memory)
- *         width, height, depth - size of source image
- *         srcFormat, srcType - source image format and type
- *         pixels - source image data
- *         srcPacking - source image packing parameters
- *
- * NOTE: All texture image parameters should have already been error checked.
- *
- * NOTE: the texImage dimensions and source image dimensions must be correct
- * with respect to convolution with border mode = reduce.
- */
-static void
-make_texture_image( GLcontext *ctx, GLuint dimensions,
-                    struct gl_texture_image *texImage,
-                    GLint width, GLint height, GLint depth,
-                    GLenum srcFormat, GLenum srcType, const GLvoid *pixels,
-                    const struct gl_pixelstore_attrib *srcPacking)
-{
-   const GLint internalFormat = texImage->IntFormat;
-   const GLint components = components_in_intformat(internalFormat);
-   GLint convWidth = width, convHeight = height;
-
-   if (ctx->NewState & _NEW_PIXEL)
-      gl_update_state(ctx);
-
-   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
-      adjust_texture_size_for_convolution(ctx, dimensions,
-                                          &convWidth, &convHeight);
-   }
-
-   texImage->Data = (GLchan *) MALLOC(convWidth * convHeight * depth
-                                 * components * sizeof(GLchan) + EXTRA_BYTE);
-   if (!texImage->Data)
-      return;      /* out of memory */
-
-   fill_texture_image(ctx, dimensions, texImage->Format, texImage->Data,
-                      width, height, depth, 0, 0, 0,
-                      convWidth * components * sizeof(GLchan),
-                      convWidth * convHeight * components * sizeof(GLchan),
-                      srcFormat, srcType, pixels, srcPacking);
-}
-
-
-
-/*
  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  * create a texture image with unspecified image contents per the OpenGL
- * spec.  This function creates an empty image for the given texture image.
+ * spec.
  */
-static void
-make_null_texture( struct gl_texture_image *texImage )
+static GLubyte *
+make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
 {
-   GLint components;
-   GLint numPixels;
-
-   ASSERT(texImage);
-   ASSERT(!texImage->Data);
-
-   components = components_in_intformat(texImage->IntFormat);
-   numPixels = texImage->Width * texImage->Height * texImage->Depth;
-
-   texImage->Data = (GLchan *) MALLOC( numPixels * components * sizeof(GLchan)
-                                       + EXTRA_BYTE );
+   const GLint components = _mesa_components_in_format(format);
+   const GLint numPixels = width * height * depth;
+   GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
 
    /*
     * Let's see if anyone finds this.  If glTexImage2D() is called with
     * a NULL image pointer then load the texture image with something
     * interesting instead of leaving it indeterminate.
     */
-   if (texImage->Data) {
+   if (data) {
       static const char message[8][32] = {
          "   X   X  XXXXX   XXX     X    ",
          "   XX XX  X      X   X   X X   ",
@@ -983,19 +442,23 @@ make_null_texture( struct gl_texture_image *texImage )
          "                               "
       };
 
-      GLchan *imgPtr = texImage->Data;
-      GLint i, j, k;
-      for (i = 0; i < texImage->Height; i++) {
-         GLint srcRow = 7 - i % 8;
-         for (j = 0; j < texImage->Width; j++) {
-            GLint srcCol = j % 32;
-            GLint texel = (message[srcRow][srcCol]=='X') ? CHAN_MAX : 70;
-            for (k=0;k<components;k++) {
-               *imgPtr++ = (GLchan) texel;
+      GLubyte *imgPtr = data;
+      GLint h, i, j, k;
+      for (h = 0; h < depth; h++) {
+         for (i = 0; i < height; i++) {
+            GLint srcRow = 7 - (i % 8);
+            for (j = 0; j < width; j++) {
+               GLint srcCol = j % 32;
+               GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
+               for (k = 0; k < components; k++) {
+                  *imgPtr++ = texel;
+               }
             }
          }
       }
    }
+
+   return data;
 }
 
 
@@ -1059,7 +522,8 @@ texture_error_check( GLcontext *ctx, GLenum target,
       }
    }
    else if (dimensions == 2) {
-      isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D);
+      isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D ||
+                             target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
       if (target != GL_TEXTURE_2D && !isProxy &&
           !(ctx->Extensions.ARB_texture_cube_map &&
             target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
@@ -1505,104 +969,163 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
 
 
 
-
-/*
- * Turn generic compressed formats into specific compressed format.
- * Some of the compressed formats we don't support, so we
- * fall back to the uncompressed format.  (See issue 15 of
- * the GL_ARB_texture_compression specification.)
- */
-static GLint
-get_specific_compressed_tex_format(GLcontext *ctx,
-                                   GLint ifmt, GLint numDimensions,
-                                   GLint     *levelp,
-                                   GLsizei   *widthp,
-                                   GLsizei   *heightp,
-                                   GLsizei   *depthp,
-                                   GLint     *borderp,
-                                   GLenum    *formatp,
-                                   GLenum    *typep)
+void
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+                   GLenum type, GLvoid *pixels )
 {
-   char message[100];
-   GLint internalFormat = ifmt;
-
-   if (ctx->Extensions.ARB_texture_compression
-       && ctx->Driver.SpecificCompressedTexFormat) {
-      /*
-       * First, ask the driver for the specific format.
-       * We do this for all formats, since we may want to
-       * fake one compressed format for another.
-       */
-       internalFormat = (*ctx->Driver.SpecificCompressedTexFormat)
-                               (ctx, internalFormat, numDimensions,
-                                levelp,
-                                widthp, heightp, depthp,
-                                borderp, formatp, typep);
+   GET_CURRENT_CONTEXT(ctx);
+   const struct gl_texture_unit *texUnit;
+   const struct gl_texture_object *texObj;
+   struct gl_texture_image *texImage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+      return;
    }
 
-   /*
-    * Now, convert any generic format left to an uncompressed
-    * specific format.  If the driver does not support compression
-    * of the format, we must drop back to the uncompressed format.
-    * See issue 15 of the GL_ARB_texture_compression specification.
-    */
-   switch (internalFormat) {
-      case GL_COMPRESSED_ALPHA_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
-         }
-         internalFormat = GL_ALPHA;
-         break;
-      case GL_COMPRESSED_LUMINANCE_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
-         }
-         internalFormat = GL_LUMINANCE;
-         break;
-      case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
+   if (_mesa_sizeof_type(type) <= 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+      return;
+   }
+
+   if (_mesa_components_in_format(format) <= 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+      return;
+   }
+
+   if (!pixels)
+      return;
+
+   texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+   texObj = _mesa_select_tex_object(ctx, texUnit, target);
+   if (!texObj || is_proxy_target(target)) {
+      gl_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+      return;
+   }
+
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+   if (!texImage) {
+      /* invalid mipmap level, not an error */
+      return;
+   }
+
+   if (!texImage->Data) {
+      /* no image data, not an error */
+      return;
+   }
+
+   if (ctx->NewState & _NEW_PIXEL)
+      gl_update_state(ctx);
+
+   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+      /* convert texture image to GL_RGBA, GL_FLOAT */
+      GLint width = texImage->Width;
+      GLint height = texImage->Height;
+      GLint depth = texImage->Depth;
+      GLint img, row;
+      GLfloat *tmpImage, *convImage;
+      tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      if (!tmpImage) {
+         gl_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+         return;
+      }
+      convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
+      if (!convImage) {
+         FREE(tmpImage);
+         gl_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+         return;
+      }
+
+      for (img = 0; img < depth; img++) {
+         GLint convWidth, convHeight;
+
+         /* convert texture data to GLfloat/GL_RGBA */
+         for (row = 0; row < height; row++) {
+            GLchan texels[1 << MAX_TEXTURE_LEVELS][4];
+            GLint col;
+            GLfloat *dst = tmpImage + row * width * 4;
+            for (col = 0; col < width; col++) {
+               (*texImage->FetchTexel)(ctx, texObj, texImage, col, row, img,
+                                       texels[col]);
+            }
+            _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst,
+                         GL_RGBA, CHAN_TYPE, texels,
+                         &_mesa_native_packing,
+                         ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
+                         GL_FALSE);
          }
-         internalFormat = GL_LUMINANCE_ALPHA;
-         break;
-      case GL_COMPRESSED_INTENSITY_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
+
+         convWidth = width;
+         convHeight = height;
+
+         /* convolve */
+         if (target == GL_TEXTURE_1D) {
+            if (ctx->Pixel.Convolution1DEnabled) {
+               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
+            }
          }
-         internalFormat = GL_INTENSITY;
-         break;
-      case GL_COMPRESSED_RGB_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
+         else {
+            if (ctx->Pixel.Convolution2DEnabled) {
+               _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
+                                       tmpImage, convImage);
+            }
+            else if (ctx->Pixel.Separable2DEnabled) {
+               _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
+                                        tmpImage, convImage);
+            }
          }
-         internalFormat = GL_RGB;
-         break;
-      case GL_COMPRESSED_RGBA_ARB:
-         if (ctx && !ctx->Extensions.ARB_texture_compression) {
-            sprintf(message, "glTexImage%dD(internalFormat)", numDimensions);
-            gl_error(ctx, GL_INVALID_VALUE, message);
-            return -1;
+
+         /* pack convolved image */
+         for (row = 0; row < convHeight; row++) {
+            const GLfloat *src = convImage + row * convWidth * 4;
+            GLvoid *dest = _mesa_image_address(&ctx->Pack, pixels,
+                                               convWidth, convHeight,
+                                               format, type, img, row, 0);
+            _mesa_pack_float_rgba_span(ctx, convWidth,
+                       (const GLfloat(*)[4]) src,
+                       format, type, dest, &ctx->Pack,
+                       ctx->_ImageTransferState & IMAGE_POST_CONVOLUTION_BITS);
          }
-         internalFormat = GL_RGBA;
-         break;
-      default:
-         /* silence compiler warning */
-         ;
+      }
+
+      FREE(tmpImage);
+      FREE(convImage);
    }
-   return internalFormat;
+   else {
+      /* no convolution */
+      GLint width = texImage->Width;
+      GLint height = texImage->Height;
+      GLint depth = texImage->Depth;
+      GLint img, row;
+      for (img = 0; img < depth; img++) {
+         for (row = 0; row < height; row++) {
+            /* compute destination address in client memory */
+            GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels,
+                                    width, height, format, type, img, row, 0);
+            assert(dest);
+
+            {
+               /* general case:  convert row to RGBA format */
+               GLchan rgba[MAX_WIDTH][4];
+               GLint col;
+               for (col = 0; col < width; col++) {
+                  (*texImage->FetchTexel)(ctx, texObj, texImage,
+                                          img, row, col, rgba[col]);
+               }
+
+               _mesa_pack_rgba_span( ctx, width, (const GLchan (*)[4])rgba,
+                                     format, type, dest, &ctx->Pack,
+                                     ctx->_ImageTransferState );
+            } /* format */
+         } /* row */
+      } /* img */
+   } /* convolution */
 }
 
 
+
 /*
  * Called from the API.  Note that width includes the border.
  */
@@ -1615,37 +1138,21 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 1, &postConvWidth, NULL);
+   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
 
-   if (target==GL_TEXTURE_1D) {
+   if (target == GL_TEXTURE_1D) {
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLint ifmt;
-
-      ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 1,
-                                                &level,
-                                                &width, 0, 0,
-                                                &border, &format, &type);
-      if (ifmt < 0) {
-         /*
-          * The error here is that we were sent a generic compressed
-          * format, but the extension is not supported.
-          */
-         return;
-      }
-      else {
-         internalFormat = ifmt;
-      }
 
       if (texture_error_check(ctx, target, level, internalFormat,
                               format, type, 1, postConvWidth, 1, 1, border)) {
-         return;   /* error in texture image was detected */
+         return;   /* error was recorded */
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-      texObj = texUnit->Current1D;
-      texImage = texObj->Image[level];
+      texObj = _mesa_select_tex_object(ctx, texUnit, target);
+      texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
@@ -1656,51 +1163,28 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
          }
       }
       else if (texImage->Data) {
+         /* free the old texture data */
          FREE(texImage->Data);
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, postConvWidth, 1, 1, border, internalFormat);
-
       if (ctx->NewState & _NEW_PIXEL)
          gl_update_state(ctx);
 
-      /* process the texture image */
+      ASSERT(ctx->Driver.TexImage1D);
       if (pixels) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (!ctx->_ImageTransferState && ctx->Driver.TexImage1D) {
-            /* let device driver try to use raw image */
-            success = (*ctx->Driver.TexImage1D)( ctx, target, level, format,
-                                                 type, pixels, &ctx->Unpack,
-                                                 texObj, texImage, &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            make_texture_image(ctx, 1, texImage, width, 1, 1,
-                               format, type, pixels, &ctx->Unpack);
-            if (!success && ctx->Driver.TexImage1D) {
-               /* let device driver try to use unpacked image */
-               (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
-                                          GL_UNSIGNED_BYTE, texImage->Data,
-                                          &_mesa_native_packing,
-                                          texObj, texImage, &retain);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
+         (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
+                                   width, border, format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage);
       }
       else {
-         make_null_texture(texImage);
-         if (ctx->Driver.TexImage1D) {
-            GLboolean retain;
-            (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
-                                       GL_UNSIGNED_BYTE, texImage->Data,
-                                       &_mesa_native_packing,
-                                       texObj, texImage, &retain);
+         GLubyte *dummy = make_null_texture(width, 1, 1, format);
+         if (dummy) {
+            (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
+                                      width, border,
+                                      format, GL_UNSIGNED_BYTE, dummy,
+                                      &_mesa_native_packing, texObj, texImage);
+            FREE(dummy);
          }
       }
 
@@ -1711,23 +1195,20 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
    else if (target == GL_PROXY_TEXTURE_1D) {
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
-                                         format, type, 1, width, 1, 1, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+                                         format, type, 1,
+                                         postConvWidth, 1, 1, border);
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                                   internalFormat, format, type,
-                                                  width, 1, 1, border);
+                                                  postConvWidth, 1, 1, border);
       }
       if (error) {
          /* if error, clear all proxy texture image parameters */
-         if (level>=0 && level<ctx->Const.MaxTextureLevels) {
+         if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
             clear_proxy_teximage(ctx->Texture.Proxy1D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx, ctx->Texture.Proxy1D->Image[level],
-                            width, 1, 1, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
@@ -1746,36 +1227,21 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
+   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
 
-   if (target==GL_TEXTURE_2D ||
+   if (target == GL_TEXTURE_2D ||
        (ctx->Extensions.ARB_texture_cube_map &&
         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
+      /* non-proxy target */
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLint ifmt;
-
-      ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 2,
-                                                &level,
-                                                &width, &height, 0,
-                                                &border, &format, &type);
-      if (ifmt < 0) {
-         /*
-          * The error here is that we were sent a generic compressed
-          * format, but the extension is not supported.
-          */
-         return;
-      }
-      else {
-         internalFormat = ifmt;
-      }
 
       if (texture_error_check(ctx, target, level, internalFormat,
                               format, type, 2, postConvWidth, postConvHeight,
                               1, border)) {
-         return;   /* error in texture image was detected */
+         return;   /* error was recorded */
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
@@ -1785,59 +1251,34 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
          set_tex_image(texObj, target, level, texImage);
-         /*texObj->Image[level] = texImage;*/
          if (!texImage) {
             gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
             return;
          }
       }
       else if (texImage->Data) {
+         /* free the old texture data */
          FREE(texImage->Data);
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, postConvWidth, postConvHeight,
-                         1, border, internalFormat);
-
       if (ctx->NewState & _NEW_PIXEL)
          gl_update_state(ctx);
 
-      /* process the texture image */
+      ASSERT(ctx->Driver.TexImage2D);
       if (pixels) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (!ctx->_ImageTransferState && ctx->Driver.TexImage2D) {
-            /* let device driver try to use raw image */
-            success = (*ctx->Driver.TexImage2D)( ctx, target, level, format,
-                                                 type, pixels, &ctx->Unpack,
-                                                 texObj, texImage, &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            make_texture_image(ctx, 2, texImage, width, height, 1,
-                               format, type, pixels, &ctx->Unpack);
-            if (!success && ctx->Driver.TexImage2D) {
-               /* let device driver try to use unpacked image */
-               (*ctx->Driver.TexImage2D)( ctx, target, level, texImage->Format,
-                                          GL_UNSIGNED_BYTE, texImage->Data,
-                                          &_mesa_native_packing,
-                                          texObj, texImage, &retain);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
+         (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
+                                   width, height, border, format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage);
       }
       else {
-         make_null_texture(texImage);
-         if (ctx->Driver.TexImage2D) {
-            GLboolean retain;
-            (*ctx->Driver.TexImage2D)( ctx, target, level, texImage->Format,
-                                       GL_UNSIGNED_BYTE, texImage->Data,
-                                       &_mesa_native_packing,
-                                       texObj, texImage, &retain);
+         GLubyte *dummy = make_null_texture(width, height, 1, format);
+         if (dummy) {
+            (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
+                                      width, height, border,
+                                      format, GL_UNSIGNED_BYTE, dummy,
+                                      &_mesa_native_packing, texObj, texImage);
+            FREE(dummy);
          }
       }
 
@@ -1848,24 +1289,20 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
    else if (target == GL_PROXY_TEXTURE_2D) {
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
-                                    format, type, 2, width, height, 1, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+                                    format, type, 2,
+                                    postConvWidth, postConvHeight, 1, border);
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
-                                                  internalFormat, format, type,
-                                                  width, height, 1, border);
+                                    internalFormat, format, type,
+                                    postConvWidth, postConvHeight, 1, border);
       }
       if (error) {
          /* if error, clear all proxy texture image parameters */
-         if (level>=0 && level<ctx->Const.MaxTextureLevels) {
+         if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
             clear_proxy_teximage(ctx->Texture.Proxy2D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx,
-                            ctx->Texture.Proxy2D->Image[level],
-                            width, height, 1, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
@@ -1887,35 +1324,19 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (target==GL_TEXTURE_3D_EXT) {
+   if (target == GL_TEXTURE_3D) {
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLint ifmt;
-
-      ifmt = get_specific_compressed_tex_format(ctx, internalFormat, 3,
-                                                &level,
-                                                &width, &height, &depth,
-                                                &border, &format, &type);
-      if (ifmt < 0) {
-         /*
-          * The error here is that we were sent a generic compressed
-          * format, but the extension is not supported.
-          */
-         return;
-      }
-      else {
-         internalFormat = ifmt;
-      }
 
       if (texture_error_check(ctx, target, level, internalFormat,
                               format, type, 3, width, height, depth, border)) {
-         return;   /* error in texture image was detected */
+         return;   /* error was recorded */
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-      texObj = texUnit->Current3D;
-      texImage = texObj->Image[level];
+      texObj = _mesa_select_tex_object(ctx, texUnit, target);
+      texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
@@ -1930,48 +1351,24 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, width, height, depth,
-                         border, internalFormat);
-
       if (ctx->NewState & _NEW_PIXEL)
          gl_update_state(ctx);
 
-      /* process the texture image */
+      ASSERT(ctx->Driver.TexImage3D);
       if (pixels) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (!ctx->_ImageTransferState && ctx->Driver.TexImage3D) {
-            /* let device driver try to use raw image */
-            success = (*ctx->Driver.TexImage3D)( ctx, target, level, format,
-                                                 type, pixels, &ctx->Unpack,
-                                                 texObj, texImage, &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            make_texture_image(ctx, 3, texImage, width, height, depth,
-                               format, type, pixels, &ctx->Unpack);
-            if (!success && ctx->Driver.TexImage3D) {
-               /* let device driver try to use unpacked image */
-               (*ctx->Driver.TexImage3D)( ctx, target, level, texImage->Format,
-                                          GL_UNSIGNED_BYTE, texImage->Data,
-                                          &_mesa_native_packing,
-                                          texObj, texImage, &retain);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
+         (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
+                                   width, height, depth, border,
+                                   format, type, pixels,
+                                   &ctx->Unpack, texObj, texImage);
       }
       else {
-         make_null_texture(texImage);
-         if (ctx->Driver.TexImage3D) {
-            GLboolean retain;
-            (*ctx->Driver.TexImage3D)( ctx, target, level, texImage->Format,
-                                       GL_UNSIGNED_BYTE, texImage->Data,
-                                       &_mesa_native_packing,
-                                       texObj, texImage, &retain);
+         GLubyte *dummy = make_null_texture(width, height, depth, format);
+         if (dummy) {
+            (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
+                                      width, height, depth, border,
+                                      format, GL_UNSIGNED_BYTE, dummy,
+                                      &_mesa_native_packing, texObj, texImage);
+            FREE(dummy);
          }
       }
 
@@ -1983,7 +1380,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
                                 format, type, 3, width, height, depth, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                                  internalFormat, format, type,
                                                  width, height, depth, border);
@@ -1994,11 +1392,6 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
             clear_proxy_teximage(ctx->Texture.Proxy3D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx, ctx->Texture.Proxy3D->Image[level],
-                            width, height, depth, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
@@ -2018,371 +1411,6 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
 }
 
 
-/*
- * Fetch a texture image from the device driver.
- * Store the results in the given texture object at the given mipmap level.
- */
-void
-_mesa_get_teximage_from_driver( GLcontext *ctx, GLenum target, GLint level,
-                                const struct gl_texture_object *texObj )
-{
-   GLvoid *image;
-   GLenum imgFormat, imgType;
-   GLboolean freeImage;
-   struct gl_texture_image *texImage;
-   GLint destComponents, numPixels, srcBytesPerTexel;
-
-   if (!ctx->Driver.GetTexImage)
-      return;
-
-   image = (*ctx->Driver.GetTexImage)( ctx, target, level, texObj,
-                                       &imgFormat, &imgType, &freeImage);
-   if (!image)
-      return;
-
-   texImage = texObj->Image[level];
-   ASSERT(texImage);
-   if (!texImage)
-      return;
-
-   destComponents = components_in_intformat(texImage->Format);
-   assert(destComponents > 0);
-   numPixels = texImage->Width * texImage->Height * texImage->Depth;
-   assert(numPixels > 0);
-   srcBytesPerTexel = _mesa_bytes_per_pixel(imgFormat, imgType);
-   assert(srcBytesPerTexel > 0);
-
-   if (!texImage->Data) {
-      /* Allocate memory for the texture image data */
-      texImage->Data = (GLchan *) MALLOC(numPixels * destComponents
-                                         * sizeof(GLchan) + EXTRA_BYTE);
-   }
-
-   if (imgFormat == texImage->Format && imgType == GL_UNSIGNED_BYTE) {
-      /* We got lucky!  The driver's format and type match Mesa's format. */
-      if (texImage->Data) {
-         MEMCPY(texImage->Data, image, numPixels * destComponents);
-      }
-   }
-   else {
-      /* Convert the texture image from the driver's format to Mesa's
-       * internal format.
-       */
-      const GLint width = texImage->Width;
-      const GLint height = texImage->Height;
-      const GLint depth = texImage->Depth;
-      const GLint destBytesPerRow = width * destComponents * sizeof(GLchan);
-      const GLint srcBytesPerRow = width * srcBytesPerTexel;
-      const GLenum dstType = GL_UNSIGNED_BYTE;
-      const GLenum dstFormat = texImage->Format;
-      const GLchan *srcPtr = (const GLchan *) image;
-      GLchan *destPtr = texImage->Data;
-
-      if (texImage->Format == GL_COLOR_INDEX) {
-         /* color index texture */
-         GLint img, row;
-         assert(imgFormat == GL_COLOR_INDEX);
-         for (img = 0; img < depth; img++) {
-            for (row = 0; row < height; row++) {
-               _mesa_unpack_index_span(ctx, width, dstType, destPtr,
-                             imgType, srcPtr, &_mesa_native_packing, GL_FALSE);
-               destPtr += destBytesPerRow;
-               srcPtr += srcBytesPerRow;
-            }
-         }
-      }
-      else {
-         /* color texture */
-         GLint img, row;
-         for (img = 0; img < depth; img++) {
-            for (row = 0; row < height; row++) {
-               _mesa_unpack_chan_color_span(ctx, width, dstFormat, destPtr,
-                  imgFormat, imgType, srcPtr, &_mesa_native_packing, GL_FALSE);
-               destPtr += destBytesPerRow;
-               srcPtr += srcBytesPerRow;
-            }
-         }
-      }
-   }
-
-   if (freeImage)
-      FREE(image);
-}
-
-
-/*
- * Get all the mipmap images for a texture object from the device driver.
- * Actually, only get mipmap images if we're using a mipmap filter.
- */
-GLboolean
-_mesa_get_teximages_from_driver(GLcontext *ctx,
-                                struct gl_texture_object *texObj)
-{
-   if (ctx->Driver.GetTexImage) {
-      static const GLenum targets[] = {
-         GL_TEXTURE_1D,
-         GL_TEXTURE_2D,
-         GL_TEXTURE_3D,
-         GL_TEXTURE_CUBE_MAP_ARB,
-         GL_TEXTURE_CUBE_MAP_ARB,
-         GL_TEXTURE_CUBE_MAP_ARB
-      };
-      GLboolean needLambda = (texObj->MinFilter != texObj->MagFilter);
-      GLenum target = targets[texObj->Dimensions - 1];
-      if (needLambda) {
-         GLint level;
-         /* Get images for all mipmap levels.  We might not need them
-          * all but this is easier.  We're on a (slow) software path
-          * anyway.
-          */
-         for (level = texObj->BaseLevel; level <= texObj->_MaxLevel; level++) {
-            struct gl_texture_image *texImg = texObj->Image[level];
-            if (texImg && !texImg->Data) {
-               _mesa_get_teximage_from_driver(ctx, target, level, texObj);
-               if (!texImg->Data)
-                  return GL_FALSE;  /* out of memory */
-            }
-         }
-      }
-      else {
-         GLint level = texObj->BaseLevel;
-         struct gl_texture_image *texImg = texObj->Image[level];
-         if (texImg && !texImg->Data) {
-            _mesa_get_teximage_from_driver(ctx, target, level, texObj);
-            if (!texImg->Data)
-               return GL_FALSE;  /* out of memory */
-         }
-      }
-      return GL_TRUE;
-   }
-   return GL_FALSE;
-}
-
-
-
-void
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
-                   GLenum type, GLvoid *pixels )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   const struct gl_texture_unit *texUnit;
-   const struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   GLboolean discardImage;
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
-      gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
-      return;
-   }
-
-   if (_mesa_sizeof_type(type) <= 0) {
-      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
-      return;
-   }
-
-   if (_mesa_components_in_format(format) <= 0) {
-      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
-      return;
-   }
-
-   if (!pixels)
-      return;
-
-   texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   if (!texObj ||
-       target == GL_PROXY_TEXTURE_1D ||
-       target == GL_PROXY_TEXTURE_2D ||
-       target == GL_PROXY_TEXTURE_3D) {
-      gl_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
-      return;
-   }
-
-   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-   if (!texImage) {
-      /* invalid mipmap level, not an error */
-      return;
-   }
-
-   if (!texImage->Data) {
-      /* try to get the texture image from the device driver */
-      _mesa_get_teximage_from_driver(ctx, target, level, texObj);
-      discardImage = GL_TRUE;
-   }
-   else {
-      discardImage = GL_FALSE;
-   }
-
-   if (texImage->Data) {
-      GLint width = texImage->Width;
-      GLint height = texImage->Height;
-      GLint depth = texImage->Depth;
-      GLint img, row;
-
-      if (ctx->NewState & _NEW_PIXEL)
-         gl_update_state(ctx);
-
-      if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
-         /* convert texture image to GL_RGBA, GL_FLOAT */
-         GLfloat *tmpImage, *convImage;
-         const GLint comps = components_in_intformat(texImage->Format);
-
-         tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
-         if (!tmpImage) {
-            gl_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
-            return;
-         }
-         convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
-         if (!convImage) {
-            FREE(tmpImage);
-            gl_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
-            return;
-         }
-
-         for (img = 0; img < depth; img++) {
-            GLint convWidth, convHeight;
-
-            /* convert to GL_RGBA */
-            for (row = 0; row < height; row++) {
-               const GLchan *src = texImage->Data
-                                  + (img * height + row ) * width * comps;
-               GLfloat *dst = tmpImage + row * width * 4;
-               _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst,
-                          texImage->Format, GL_UNSIGNED_BYTE,
-                          src, &_mesa_native_packing,
-                          ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
-                          GL_FALSE);
-            }
-
-            convWidth = width;
-            convHeight = height;
-
-            /* convolve */
-            if (target == GL_TEXTURE_1D) {
-               if (ctx->Pixel.Convolution1DEnabled) {
-                  _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
-               }
-            }
-            else {
-               if (ctx->Pixel.Convolution2DEnabled) {
-                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
-                                          tmpImage, convImage);
-               }
-               else if (ctx->Pixel.Separable2DEnabled) {
-                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
-                                           tmpImage, convImage);
-               }
-            }
-
-            /* pack convolved image */
-            for (row = 0; row < convHeight; row++) {
-               const GLfloat *src = convImage + row * convWidth * 4;
-               GLvoid *dest = _mesa_image_address(&ctx->Pack, pixels,
-                                                  convWidth, convHeight,
-                                                  format, type, img, row, 0);
-               _mesa_pack_float_rgba_span(ctx, convWidth,
-                        (const GLfloat(*)[4]) src,
-                        format, type, dest, &ctx->Pack,
-                        ctx->_ImageTransferState & IMAGE_POST_CONVOLUTION_BITS);
-            }
-         }
-
-         FREE(tmpImage);
-         FREE(convImage);
-      }
-      else {
-         /* no convolution */
-         for (img = 0; img < depth; img++) {
-            for (row = 0; row < height; row++) {
-               /* compute destination address in client memory */
-               GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels,
-                                  width, height, format, type, img, row, 0);
-               assert(dest);
-               if (texImage->Format == GL_RGBA) {
-                  /* simple case */
-                  const GLchan *src = texImage->Data
-                                     + (img * height + row ) * width * 4;
-                  _mesa_pack_rgba_span( ctx, width, (CONST GLchan (*)[4]) src,
-                                        format, type, dest, &ctx->Pack,
-                                        ctx->_ImageTransferState );
-               }
-               else {
-                  /* general case:  convert row to RGBA format */
-                  GLchan rgba[MAX_WIDTH][4];
-                  GLint i;
-                  const GLchan *src;
-                  switch (texImage->Format) {
-                     case GL_ALPHA:
-                        src = texImage->Data + row * width;
-                        for (i = 0; i < width; i++) {
-                           rgba[i][RCOMP] = CHAN_MAX;
-                           rgba[i][GCOMP] = CHAN_MAX;
-                           rgba[i][BCOMP] = CHAN_MAX;
-                           rgba[i][ACOMP] = src[i];
-                        }
-                        break;
-                     case GL_LUMINANCE:
-                        src = texImage->Data + row * width;
-                        for (i = 0; i < width; i++) {
-                           rgba[i][RCOMP] = src[i];
-                           rgba[i][GCOMP] = src[i];
-                           rgba[i][BCOMP] = src[i];
-                           rgba[i][ACOMP] = CHAN_MAX;
-                         }
-                        break;
-                     case GL_LUMINANCE_ALPHA:
-                        src = texImage->Data + row * 2 * width;
-                        for (i = 0; i < width; i++) {
-                           rgba[i][RCOMP] = src[i*2+0];
-                           rgba[i][GCOMP] = src[i*2+0];
-                           rgba[i][BCOMP] = src[i*2+0];
-                           rgba[i][ACOMP] = src[i*2+1];
-                        }
-                        break;
-                     case GL_INTENSITY:
-                        src = texImage->Data + row * width;
-                        for (i = 0; i < width; i++) {
-                           rgba[i][RCOMP] = src[i];
-                           rgba[i][GCOMP] = src[i];
-                           rgba[i][BCOMP] = src[i];
-                           rgba[i][ACOMP] = CHAN_MAX;
-                        }
-                        break;
-                     case GL_RGB:
-                        src = texImage->Data + row * 3 * width;
-                        for (i = 0; i < width; i++) {
-                           rgba[i][RCOMP] = src[i*3+0];
-                           rgba[i][GCOMP] = src[i*3+1];
-                           rgba[i][BCOMP] = src[i*3+2];
-                           rgba[i][ACOMP] = CHAN_MAX;
-                        }
-                        break;
-                     case GL_COLOR_INDEX:
-                        gl_problem( ctx, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
-                        break;
-                     case GL_RGBA:
-                     default:
-                        gl_problem( ctx, "bad format in gl_GetTexImage" );
-                  }
-                  _mesa_pack_rgba_span( ctx, width, (const GLchan (*)[4])rgba,
-                                        format, type, dest, &ctx->Pack,
-                                        ctx->_ImageTransferState );
-               } /* format */
-            } /* row */
-         } /* img */
-      } /* convolution */
-
-      /* if we got the teximage from the device driver we'll discard it now */
-      if (discardImage) {
-         FREE(texImage->Data);
-         texImage->Data = NULL;
-      }
-   }
-}
-
-
 
 void
 _mesa_TexSubImage1D( GLenum target, GLint level,
@@ -2395,9 +1423,8 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
-   adjust_texture_size_for_convolution(ctx, 1, &postConvWidth, NULL);
+   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
 
    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
                               postConvWidth, 1, 1, format, type)) {
@@ -2405,8 +1432,8 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    }
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = texUnit->Current1D;
-   texImage = texObj->Image[level];
+   texObj = _mesa_select_tex_object(ctx, texUnit, target);
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || !pixels)
@@ -2415,40 +1442,10 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   if (!ctx->_ImageTransferState && ctx->Driver.TexSubImage1D) {
-      success = (*ctx->Driver.TexSubImage1D)( ctx, target, level, xoffset,
-                                              width, format, type, pixels,
-                                              &ctx->Unpack, texObj, texImage );
-   }
-   if (!success) {
-      /* XXX if Driver.TexSubImage1D, unpack image and try again? */
-      GLboolean retain = GL_TRUE;
-      if (!texImage->Data) {
-         _mesa_get_teximage_from_driver( ctx, target, level, texObj );
-         if (!texImage->Data) {
-            make_null_texture(texImage);
-         }
-         if (!texImage->Data)
-            return;  /* we're really out of luck! */
-      }
-
-      fill_texture_image(ctx, 1, texImage->Format, texImage->Data,
-                         width, 1, 1, xoffset + texImage->Border, 0, 0, /* size and offsets */
-                         0, 0, /* strides */
-                         format, type, pixels, &ctx->Unpack);
-
-      if (ctx->Driver.TexImage1D) {
-         (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
-                                    GL_UNSIGNED_BYTE, texImage->Data,
-                                    &_mesa_native_packing, texObj, texImage,
-                                    &retain );
-      }
-
-      if (!retain && texImage->Data) {
-         FREE(texImage->Data);
-         texImage->Data = NULL;
-      }
-   }
+   ASSERT(ctx->Driver.TexSubImage1D);
+   (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
+                                format, type, pixels, &ctx->Unpack,
+                                texObj, texImage);
 }
 
 
@@ -2464,9 +1461,8 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
-   adjust_texture_size_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
+   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
 
    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
                              postConvWidth, postConvHeight, 1, format, type)) {
@@ -2475,7 +1471,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   texImage = texObj->Image[level];
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || height == 0 || !pixels)
@@ -2484,43 +1480,10 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   if (!ctx->_ImageTransferState && ctx->Driver.TexSubImage2D) {
-      success = (*ctx->Driver.TexSubImage2D)( ctx, target, level, xoffset,
-                                     yoffset, width, height, format, type,
-                                     pixels, &ctx->Unpack, texObj, texImage );
-   }
-   if (!success) {
-      /* XXX if Driver.TexSubImage2D, unpack image and try again? */
-      const GLint texComps = components_in_intformat(texImage->Format);
-      const GLint texRowStride = texImage->Width * texComps;
-      GLboolean retain = GL_TRUE;
-
-      if (!texImage->Data) {
-         _mesa_get_teximage_from_driver( ctx, target, level, texObj );
-         if (!texImage->Data) {
-            make_null_texture(texImage);
-         }
-         if (!texImage->Data)
-            return;  /* we're really out of luck! */
-      }
-
-      fill_texture_image(ctx, 2, texImage->Format, texImage->Data,
-                         width, height, 1, xoffset + texImage->Border,
-                         yoffset + texImage->Border, 0, texRowStride, 0,
-                         format, type, pixels, &ctx->Unpack);
-
-      if (ctx->Driver.TexImage2D) {
-         (*ctx->Driver.TexImage2D)(ctx, target, level, texImage->Format,
-                                   GL_UNSIGNED_BYTE, texImage->Data,
-                                   &_mesa_native_packing, texObj, texImage,
-                                   &retain);
-      }
-
-      if (!retain && texImage->Data) {
-         FREE(texImage->Data);
-         texImage->Data = NULL;
-      }
-   }
+   ASSERT(ctx->Driver.TexSubImage2D);
+   (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
+                                width, height, format, type, pixels,
+                                &ctx->Unpack, texObj, texImage);
 }
 
 
@@ -2536,7 +1499,6 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
                               width, height, depth, format, type)) {
@@ -2544,8 +1506,8 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    }
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = texUnit->Current3D;
-   texImage = texObj->Image[level];
+   texObj = _mesa_select_tex_object(ctx, texUnit, target);
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || height == 0 || height == 0 || !pixels)
@@ -2554,45 +1516,12 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   if (!ctx->_ImageTransferState && ctx->Driver.TexSubImage3D) {
-      success = (*ctx->Driver.TexSubImage3D)( ctx, target, level, xoffset,
-                                yoffset, zoffset, width, height, depth, format,
-                                type, pixels, &ctx->Unpack, texObj, texImage );
-   }
-   if (!success) {
-      /* XXX if Driver.TexSubImage3D, unpack image and try again? */
-      const GLint texComps = components_in_intformat(texImage->Format);
-      const GLint texRowStride = texImage->Width * texComps;
-      const GLint texImgStride = texRowStride * texImage->Height;
-      GLboolean retain = GL_TRUE;
-
-      if (!texImage->Data) {
-         _mesa_get_teximage_from_driver( ctx, target, level, texObj );
-         if (!texImage->Data) {
-            make_null_texture(texImage);
-         }
-         if (!texImage->Data)
-            return;  /* we're really out of luck! */
-      }
-
-      fill_texture_image(ctx, 3, texImage->Format, texImage->Data,
-                         width, height, depth, xoffset + texImage->Border,
-                         yoffset + texImage->Border,
-                         zoffset + texImage->Border, texRowStride,
-                         texImgStride, format, type, pixels, &ctx->Unpack);
-
-      if (ctx->Driver.TexImage3D) {
-         (*ctx->Driver.TexImage3D)(ctx, target, level, texImage->Format,
-                                   GL_UNSIGNED_BYTE, texImage->Data,
-                                   &_mesa_native_packing, texObj, texImage,
-                                   &retain);
-      }
-
-      if (!retain && texImage->Data) {
-         FREE(texImage->Data);
-         texImage->Data = NULL;
-      }
-   }
+   ASSERT(ctx->Driver.TexSubImage3D);
+   (*ctx->Driver.TexSubImage3D)(ctx, target, level,
+                                xoffset, yoffset, zoffset,
+                                width, height, depth,
+                                format, type, pixels,
+                                &ctx->Unpack, texObj, texImage );
 }
 
 
@@ -2654,7 +1583,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 1, &postConvWidth, NULL);
+   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
 
    if (copytexture_error_check(ctx, 1, target, level, internalFormat,
                                postConvWidth, 1, border))
@@ -2697,7 +1626,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
+   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
 
    if (copytexture_error_check(ctx, 2, target, level, internalFormat,
                                postConvWidth, postConvHeight, border))
@@ -2739,7 +1668,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 1, &postConvWidth, NULL);
+   _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
 
    if (copytexsubimage_error_check(ctx, 1, target, level,
                                    xoffset, 0, 0, postConvWidth, 1))
@@ -2789,7 +1718,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
+   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
 
    if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
                                    postConvWidth, postConvHeight))
@@ -2839,7 +1768,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
    if (ctx->NewState & _NEW_PIXEL)
       gl_update_state(ctx);
 
-   adjust_texture_size_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
+   _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,&postConvHeight);
 
    if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset,
                                    zoffset, postConvWidth, postConvHeight))
@@ -2904,7 +1833,6 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLsizei computedImageSize;
 
       if (texture_error_check(ctx, target, level, internalFormat,
                               GL_NONE, GL_NONE, 1, width, 1, 1, border)) {
@@ -2912,8 +1840,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-      texObj = texUnit->Current1D;
-      texImage = texObj->Image[level];
+      texObj = _mesa_select_tex_object(ctx, texUnit, target);
+      texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
@@ -2928,48 +1856,13 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, width, 1, 1,
-                         border, internalFormat);
-
-      /* process the texture image */
-      if (data) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (ctx->Driver.CompressedTexImage1D) {
-            success = (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
-                               imageSize, data, texObj, texImage, &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            computedImageSize = _mesa_compressed_image_size(ctx,
-                                                        internalFormat,
-                                                        1,    /* num dims */
-                                                        width,
-                                                        1,    /* height   */
-                                                        1);   /* depth    */
-            if (computedImageSize != imageSize) {
-                gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage1DARB(imageSize)");
-                return;
-            }
-            texImage->Data = MALLOC(computedImageSize);
-            if (texImage->Data) {
-               MEMCPY(texImage->Data, data, computedImageSize);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
-      }
-      else {
-         make_null_texture(texImage);
-         if (ctx->Driver.CompressedTexImage1D) {
-            GLboolean retain;
-            (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, 0,
-                                                texImage->Data, texObj,
-                                                texImage, &retain);
-         }
+      if (ctx->Extensions.ARB_texture_compression) {
+         ASSERT(ctx->Driver.CompressedTexImage1D);
+         (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
+                                             internalFormat, width, border,
+                                             imageSize, data,
+                                             texObj, texImage);
+         ASSERT(texImage->CompressedSize > 0); /* sanity */
       }
 
       /* state update */
@@ -2980,7 +1873,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
                                     GL_NONE, GL_NONE, 1, width, 1, 1, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                              internalFormat, GL_NONE, GL_NONE,
                                              width, 1, 1, border);
@@ -2991,11 +1885,6 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
             clear_proxy_teximage(ctx->Texture.Proxy1D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx, ctx->Texture.Proxy1D->Image[level],
-                            width, 1, 1, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)" );
@@ -3027,14 +1916,13 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          ;
    }
 
-   if (target==GL_TEXTURE_2D ||
+   if (target == GL_TEXTURE_2D ||
        (ctx->Extensions.ARB_texture_cube_map &&
         target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
         target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLsizei computedImageSize;
 
       if (texture_error_check(ctx, target, level, internalFormat,
                               GL_NONE, GL_NONE, 1, width, height, 1, border)) {
@@ -3042,8 +1930,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-      texObj = texUnit->Current2D;
-      texImage = texObj->Image[level];
+      texObj = _mesa_select_tex_object(ctx, texUnit, target);
+      texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
@@ -3058,53 +1946,13 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, width, height, 1, border, internalFormat);
-
-      /* process the texture image */
-      if (data) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (ctx->Driver.CompressedTexImage2D) {
-            success = (*ctx->Driver.CompressedTexImage2D)( ctx,
-                                                           target,
-                                                           level,
-                                                           imageSize,
-                                                           data,
-                                                           texObj,
-                                                           texImage,
-                                                           &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            computedImageSize = _mesa_compressed_image_size(ctx,
-                                                           internalFormat,
-                                                           2,    /* num dims */
-                                                           width,
-                                                           height,
-                                                           1);   /* depth    */
-            if (computedImageSize != imageSize) {
-                gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2DARB(imageSize)");
-                return;
-            }
-            texImage->Data = MALLOC(computedImageSize);
-            if (texImage->Data) {
-               MEMCPY(texImage->Data, data, computedImageSize);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
-      }
-      else {
-         make_null_texture(texImage);
-         if (ctx->Driver.CompressedTexImage2D) {
-            GLboolean retain;
-            (*ctx->Driver.CompressedTexImage2D)( ctx, target, level, 0,
-                                                 texImage->Data, texObj,
-                                                 texImage, &retain);
-         }
+      if (ctx->Extensions.ARB_texture_compression) {
+         ASSERT(ctx->Driver.CompressedTexImage2D);
+         (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
+                                             internalFormat, width, height,
+                                             border, imageSize, data,
+                                             texObj, texImage);
+         ASSERT(texImage->CompressedSize > 0); /* sanity */
       }
 
       /* state update */
@@ -3115,7 +1963,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
                                 GL_NONE, GL_NONE, 2, width, height, 1, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                               internalFormat, GL_NONE, GL_NONE,
                                               width, height, 1, border);
@@ -3126,11 +1975,6 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
             clear_proxy_teximage(ctx->Texture.Proxy2D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx, ctx->Texture.Proxy2D->Image[level],
-                            width, 1, 1, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)" );
@@ -3166,7 +2010,6 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
       struct gl_texture_unit *texUnit;
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
-      GLsizei computedImageSize;
 
       if (texture_error_check(ctx, target, level, internalFormat,
                           GL_NONE, GL_NONE, 1, width, height, depth, border)) {
@@ -3174,8 +2017,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
       }
 
       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-      texObj = texUnit->Current3D;
-      texImage = texObj->Image[level];
+      texObj = _mesa_select_tex_object(ctx, texUnit, target);
+      texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
@@ -3190,50 +2033,14 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      /* setup the teximage struct's fields */
-      init_texture_image(ctx, texImage, width, height, depth,
-                         border, internalFormat);
-
-      /* process the texture image */
-      if (data) {
-         GLboolean retain = GL_TRUE;
-         GLboolean success = GL_FALSE;
-         if (ctx->Driver.CompressedTexImage3D) {
-            success = (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
-                                                          imageSize, data,
-                                                          texObj, texImage,
-                                                          &retain);
-         }
-         if (retain || !success) {
-            /* make internal copy of the texture image */
-            computedImageSize = _mesa_compressed_image_size(ctx,
-                                                            internalFormat,
-                                                            3,  /* num dims */
-                                                            width,
-                                                            height,
-                                                            depth);
-            if (computedImageSize != imageSize) {
-                gl_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage3DARB(imageSize)");
-                return;
-            }
-            texImage->Data = MALLOC(computedImageSize);
-            if (texImage->Data) {
-               MEMCPY(texImage->Data, data, computedImageSize);
-            }
-         }
-         if (!retain && texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
-      }
-      else {
-         make_null_texture(texImage);
-         if (ctx->Driver.CompressedTexImage3D) {
-            GLboolean retain;
-            (*ctx->Driver.CompressedTexImage3D)( ctx, target, level, 0,
-                                                 texImage->Data, texObj,
-                                                 texImage, &retain);
-         }
+      if (ctx->Extensions.ARB_texture_compression) {
+         ASSERT(ctx->Driver.CompressedTexImage3D);
+         (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
+                                             internalFormat,
+                                             width, height, depth,
+                                             border, imageSize, data,
+                                             texObj, texImage);
+         ASSERT(texImage->CompressedSize > 0); /* sanity */
       }
 
       /* state update */
@@ -3244,7 +2051,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
       /* Proxy texture: check for errors and update proxy state */
       GLenum error = texture_error_check(ctx, target, level, internalFormat,
                             GL_NONE, GL_NONE, 1, width, height, depth, border);
-      if (!error && ctx->Driver.TestProxyTexImage) {
+      if (!error) {
+         ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                              internalFormat, GL_NONE, GL_NONE,
                                              width, height, depth, border);
@@ -3255,11 +2063,6 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
             clear_proxy_teximage(ctx->Texture.Proxy3D->Image[level]);
          }
       }
-      else {
-         /* if no error, update proxy texture image parameters */
-         init_texture_image(ctx, ctx->Texture.Proxy3D->Image[level],
-                            width, 1, 1, border, internalFormat);
-      }
    }
    else {
       gl_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)" );
@@ -3277,7 +2080,6 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
                               width, 1, 1, format, GL_NONE)) {
@@ -3286,20 +2088,17 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   texImage = texObj->Image[level];
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || !data)
       return;  /* no-op, not an error */
 
    if (ctx->Driver.CompressedTexSubImage1D) {
-      success = (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
-                   xoffset, width, format, imageSize, data, texObj, texImage);
-   }
-   if (!success) {
-      /* XXX what else can we do? */
-      gl_problem(ctx, "glCompressedTexSubImage1DARB failed!");
-      return;
+      (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
+                                             xoffset, width,
+                                             format, imageSize, data,
+                                             texObj, texImage);
    }
 }
 
@@ -3314,7 +2113,6 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
                               width, height, 1, format, GL_NONE)) {
@@ -3323,21 +2121,17 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   texImage = texObj->Image[level];
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || height == 0 || !data)
       return;  /* no-op, not an error */
 
    if (ctx->Driver.CompressedTexSubImage2D) {
-      success = (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
-                                       xoffset, yoffset, width, height, format,
-                                       imageSize, data, texObj, texImage);
-   }
-   if (!success) {
-      /* XXX what else can we do? */
-      gl_problem(ctx, "glCompressedTexSubImage2DARB failed!");
-      return;
+      (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
+                                             xoffset, yoffset, width, height,
+                                             format, imageSize, data,
+                                             texObj, texImage);
    }
 }
 
@@ -3352,7 +2146,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLboolean success = GL_FALSE;
 
    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
                               width, height, depth, format, GL_NONE)) {
@@ -3361,21 +2154,18 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
    texObj = _mesa_select_tex_object(ctx, texUnit, target);
-   texImage = texObj->Image[level];
+   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    assert(texImage);
 
    if (width == 0 || height == 0 || depth == 0 || !data)
       return;  /* no-op, not an error */
 
    if (ctx->Driver.CompressedTexSubImage3D) {
-      success = (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
-                               xoffset, yoffset, zoffset, width, height, depth,
-                               format, imageSize, data, texObj, texImage);
-   }
-   if (!success) {
-      /* XXX what else can we do? */
-      gl_problem(ctx, "glCompressedTexSubImage3DARB failed!");
-      return;
+      (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
+                                             xoffset, yoffset, zoffset,
+                                             width, height, depth,
+                                             format, imageSize, data,
+                                             texObj, texImage);
    }
 }
 
@@ -3384,6 +2174,7 @@ void
 _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
 {
    GET_CURRENT_CONTEXT(ctx);
+   const struct gl_texture_unit *texUnit;
    const struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
 
@@ -3394,48 +2185,15 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
       return;
    }
 
-   switch (target) {
-      case GL_TEXTURE_1D:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D;
-         texImage = texObj->Image[level];
-         break;
-      case GL_TEXTURE_2D:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D;
-         texImage = texObj->Image[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->Image[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->NegX[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->PosY[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->NegY[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->PosZ[level];
-         break;
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap;
-         texImage = texObj->NegZ[level];
-         break;
-      case GL_TEXTURE_3D:
-         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D;
-         texImage = texObj->Image[level];
-         break;
-      default:
-         gl_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
-         return;
+   if (is_proxy_target(target)) {
+      gl_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+      return;
    }
 
+   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 (!texImage) {
       /* invalid mipmap level */
       gl_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
@@ -3450,11 +2208,9 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
    if (!img)
       return;
 
-   if (ctx->Driver.GetCompressedTexImage) {
+   if (ctx->Extensions.ARB_texture_compression) {
+      ASSERT(ctx->Driver.GetCompressedTexImage);
       (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj,
                                            texImage);
    }
-   else {
-      gl_problem(ctx, "Driver doesn't implement GetCompressedTexImage");
-   }
 }
index a3baa5f..e547a35 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teximage.h,v 1.15 2000/11/22 07:32:17 joukj Exp $ */
+/* $Id: teximage.h,v 1.16 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -47,13 +47,6 @@ extern void
 _mesa_free_texture_image( struct gl_texture_image *teximage );
 
 
-extern GLuint
-_mesa_compressed_image_size(GLcontext *ctx,
-                            GLenum internalFormat,
-                            GLint numDimensions,
-                            GLint width, GLint height, GLint depth);
-
-
 extern struct gl_texture_object *
 _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
                         GLenum target);
@@ -64,16 +57,6 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
                        GLenum target, GLint level);
 
 
-extern void
-_mesa_get_teximage_from_driver(GLcontext *ctx, GLenum target, GLint level,
-                               const struct gl_texture_object *texObj);
-
-
-extern GLboolean
-_mesa_get_teximages_from_driver(GLcontext *ctx,
-                                struct gl_texture_object *texObj);
-
-
 
 /*** API entry point functions ***/
 
index edd382a..33b7da0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.29 2001/01/29 20:47:39 keithw Exp $ */
+/* $Id: texstate.c,v 1.30 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -37,7 +37,6 @@
 #include "texobj.h"
 #include "teximage.h"
 #include "texstate.h"
-#include "texture.h"
 #include "mtypes.h"
 #include "math/m_xform.h"
 #include "math/m_matrix.h"
index 088fddc..a3e8255 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: texstate.h,v 1.5 2000/11/22 07:32:17 joukj Exp $ */
+/* $Id: texstate.h,v 1.6 2001/02/06 21:42:48 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.5
  *
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  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"),
@@ -25,9 +25,6 @@
  */
 
 
-
-
-
 #ifndef TEXSTATE_H
 #define TEXSTATE_H
 
@@ -114,8 +111,6 @@ _mesa_TexGeniv( GLenum coord, GLenum pname, const GLint *params );
 
 
 
-extern void gl_SelectTextureTransform( GLcontext *ctx, GLenum target );
-
 
 /*
  * GL_ARB_multitexture
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
new file mode 100644 (file)
index 0000000..c9ec73f
--- /dev/null
@@ -0,0 +1,1068 @@
+/* $Id: texstore.c,v 1.1 2001/02/06 21:42:48 brianp Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2001  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"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ *   Brian Paul
+ */
+
+
+/*
+ * The functions in this file are mostly related to software texture fallbacks.
+ * This includes texture image transfer/packing and texel fetching.
+ * Hardware drivers will likely override most of this.
+ */
+
+
+
+#include "context.h"
+#include "convolve.h"
+#include "image.h"
+#include "macros.h"
+#include "mem.h"
+#include "teximage.h"
+#include "texstore.h"
+
+
+/*
+ * Get texture palette entry.
+ */
+static void
+palette_sample(GLcontext *ctx,
+               const struct gl_texture_object *tObj,
+               GLint index, GLchan rgba[4] )
+{
+   const GLchan *palette;
+   GLenum format;
+
+   if (ctx->Texture.SharedPalette) {
+      ASSERT(!ctx->Texture.Palette.FloatTable);
+      palette = (const GLchan *) ctx->Texture.Palette.Table;
+      format = ctx->Texture.Palette.Format;
+   }
+   else {
+      ASSERT(!tObj->Palette.FloatTable);
+      palette = (const GLchan *) tObj->Palette.Table;
+      format = tObj->Palette.Format;
+   }
+
+   switch (format) {
+      case GL_ALPHA:
+         rgba[ACOMP] = palette[index];
+         return;
+      case GL_LUMINANCE:
+      case GL_INTENSITY:
+         rgba[RCOMP] = palette[index];
+         return;
+      case GL_LUMINANCE_ALPHA:
+         rgba[RCOMP] = palette[(index << 1) + 0];
+         rgba[ACOMP] = palette[(index << 1) + 1];
+         return;
+      case GL_RGB:
+         rgba[RCOMP] = palette[index * 3 + 0];
+         rgba[GCOMP] = palette[index * 3 + 1];
+         rgba[BCOMP] = palette[index * 3 + 2];
+         return;
+      case GL_RGBA:
+         rgba[RCOMP] = palette[(index << 2) + 0];
+         rgba[GCOMP] = palette[(index << 2) + 1];
+         rgba[BCOMP] = palette[(index << 2) + 2];
+         rgba[ACOMP] = palette[(index << 2) + 3];
+         return;
+      default:
+         gl_problem(NULL, "Bad palette format in palette_sample");
+   }
+}
+
+
+
+/*
+ * Default 1-D texture texel fetch function.  This will typically be
+ * overridden by hardware drivers which store their texture images in
+ * special ways.
+ */
+static void
+fetch_1d_texel(GLcontext *ctx,
+               const struct gl_texture_object *tObj,
+               const struct gl_texture_image *img,
+               GLint i, GLint j, GLint k, GLchan rgba[4])
+{
+   const GLchan *data = (GLchan *) img->Data;
+   const GLchan *texel;
+#ifdef DEBUG
+   GLint width = img->Width;
+   assert(i >= 0);
+   assert(i < width);
+#endif
+
+   switch (img->Format) {
+      case GL_COLOR_INDEX:
+         {
+            GLint index = data[i];
+            palette_sample(ctx, tObj, index, rgba);
+            return;
+         }
+      case GL_ALPHA:
+         rgba[ACOMP] = data[i];
+         return;
+      case GL_LUMINANCE:
+      case GL_INTENSITY:
+         rgba[RCOMP] = data[i];
+         return;
+      case GL_LUMINANCE_ALPHA:
+         texel = data + i * 2;
+         rgba[RCOMP] = texel[0];
+         rgba[ACOMP] = texel[1];
+         return;
+      case GL_RGB:
+         texel = data + i * 3;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         return;
+      case GL_RGBA:
+         texel = data + i * 4;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         rgba[ACOMP] = texel[3];
+         return;
+      default:
+         gl_problem(NULL, "Bad format in fetch_1d_texel");
+         return;
+   }
+}
+
+
+/*
+ * Default 2-D texture texel fetch function.
+ */
+static void
+fetch_2d_texel(GLcontext *ctx,
+               const struct gl_texture_object *tObj,
+               const struct gl_texture_image *img,
+               GLint i, GLint j, GLint k, GLchan rgba[4])
+{
+   const GLint width = img->Width;    /* includes border */
+   const GLchan *data = (GLchan *) img->Data;
+   const GLchan *texel;
+
+#ifdef DEBUG
+   const GLint height = img->Height;  /* includes border */
+   assert(i >= 0);
+   assert(i < width);
+   assert(j >= 0);
+   assert(j < height);
+#endif
+
+   switch (img->Format) {
+      case GL_COLOR_INDEX:
+         {
+            GLint index = data[width *j + i];
+            palette_sample(ctx, tObj, index, rgba );
+            return;
+         }
+      case GL_ALPHA:
+         rgba[ACOMP] = data[width * j + i];
+         return;
+      case GL_LUMINANCE:
+      case GL_INTENSITY:
+         rgba[RCOMP] = data[ width * j + i];
+         return;
+      case GL_LUMINANCE_ALPHA:
+         texel = data + (width * j + i) * 2;
+         rgba[RCOMP] = texel[0];
+         rgba[ACOMP] = texel[1];
+         return;
+      case GL_RGB:
+         texel = data + (width * j + i) * 3;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         return;
+      case GL_RGBA:
+         texel = data + (width * j + i) * 4;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         rgba[ACOMP] = texel[3];
+         return;
+      default:
+         gl_problem(NULL, "Bad format in fetch_2d_texel");
+   }
+}
+
+
+/*
+ * Default 2-D texture texel fetch function.
+ */
+static void
+fetch_3d_texel(GLcontext *ctx,
+               const struct gl_texture_object *tObj,
+               const struct gl_texture_image *img,
+               GLint i, GLint j, GLint k, GLchan rgba[4])
+{
+   const GLint width = img->Width;    /* includes border */
+   const GLint height = img->Height;  /* includes border */
+   const GLint rectarea = width * height;
+   const GLchan *data = (GLchan *) img->Data;
+   const GLchan *texel;
+
+#ifdef DEBUG
+   const GLint depth = img->Depth;    /* includes border */
+   assert(i >= 0);
+   assert(i < width);
+   assert(j >= 0);
+   assert(j < height);
+   assert(k >= 0);
+   assert(k < depth);
+#endif
+
+   switch (img->Format) {
+      case GL_COLOR_INDEX:
+         {
+            GLint index = data[ rectarea * k +  width * j + i ];
+            palette_sample(ctx, tObj, index, rgba );
+            return;
+         }
+      case GL_ALPHA:
+         rgba[ACOMP] = data[ rectarea * k +  width * j + i ];
+         return;
+      case GL_LUMINANCE:
+      case GL_INTENSITY:
+         rgba[RCOMP] = data[ rectarea * k +  width * j + i ];
+         return;
+      case GL_LUMINANCE_ALPHA:
+         texel = data + ( rectarea * k + width * j + i) * 2;
+         rgba[RCOMP] = texel[0];
+         rgba[ACOMP] = texel[1];
+         return;
+      case GL_RGB:
+         texel = data + (rectarea * k + width * j + i) * 3;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         return;
+      case GL_RGBA:
+         texel = data + (rectarea * k + width * j + i) * 4;
+         rgba[RCOMP] = texel[0];
+         rgba[GCOMP] = texel[1];
+         rgba[BCOMP] = texel[2];
+         rgba[ACOMP] = texel[3];
+         return;
+      default:
+         gl_problem(NULL, "Bad format in fetch_3d_texel");
+   }
+}
+
+
+
+/*
+ * Examine the texImage->Format field and set the Red, Green, Blue, etc
+ * texel component sizes to default values.
+ * These fields are set only here by core Mesa but device drivers may
+ * overwritting these fields to indicate true texel resolution.
+ */
+static void
+set_teximage_component_sizes( struct gl_texture_image *texImage )
+{
+   switch (texImage->Format) {
+      case GL_ALPHA:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 8 * sizeof(GLchan);
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_LUMINANCE:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 8 * sizeof(GLchan);
+         texImage->IndexBits = 0;
+         break;
+      case GL_LUMINANCE_ALPHA:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 8 * sizeof(GLchan);
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 8 * sizeof(GLchan);
+         texImage->IndexBits = 0;
+         break;
+      case GL_INTENSITY:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 8 * sizeof(GLchan);
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_RED:
+         texImage->RedBits = 8 * sizeof(GLchan);
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_GREEN:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 8 * sizeof(GLchan);
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_BLUE:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 8 * sizeof(GLchan);
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_RGB:
+      case GL_BGR:
+         texImage->RedBits = 8 * sizeof(GLchan);
+         texImage->GreenBits = 8 * sizeof(GLchan);
+         texImage->BlueBits = 8 * sizeof(GLchan);
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_RGBA:
+      case GL_BGRA:
+      case GL_ABGR_EXT:
+         texImage->RedBits = 8 * sizeof(GLchan);
+         texImage->GreenBits = 8 * sizeof(GLchan);
+         texImage->BlueBits = 8 * sizeof(GLchan);
+         texImage->AlphaBits = 8 * sizeof(GLchan);
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_COLOR_INDEX:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 8 * sizeof(GLchan);
+         break;
+      default:
+         gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
+   }
+}
+
+
+/*
+ * Compute log base 2 of n.
+ * If n isn't an exact power of two return -1.
+ * If n<0 return -1.
+ */
+static int
+logbase2( int n )
+{
+   GLint i = 1;
+   GLint log2 = 0;
+
+   if (n<0) {
+      return -1;
+   }
+
+   while ( n > i ) {
+      i *= 2;
+      log2++;
+   }
+   if (i != n) {
+      return -1;
+   }
+   else {
+      return log2;
+   }
+}
+
+
+
+/*
+ * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
+ * otherwise.
+ */
+static GLboolean
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
+{
+    if (ctx->Driver.IsCompressedFormat) {
+        return (*ctx->Driver.IsCompressedFormat)(ctx, internalFormat);
+    }
+    return GL_FALSE;
+}
+
+
+
+/*
+ * Initialize most fields of a gl_texture_image struct.
+ */
+static void
+init_teximage_fields( GLcontext *ctx,
+                      struct gl_texture_image *img,
+                      GLsizei width, GLsizei height, GLsizei depth,
+                      GLint border, GLenum internalFormat )
+{
+   ASSERT(img);
+   ASSERT(!img->Data);
+   img->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
+   img->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
+   set_teximage_component_sizes( img );
+   img->IntFormat = internalFormat;
+   img->Border = border;
+   img->Width = width;
+   img->Height = height;
+   img->Depth = depth;
+   img->WidthLog2 = logbase2(width - 2 * border);
+   if (height == 1)  /* 1-D texture */
+      img->HeightLog2 = 0;
+   else
+      img->HeightLog2 = logbase2(height - 2 * border);
+   if (depth == 1)   /* 2-D texture */
+      img->DepthLog2 = 0;
+   else
+      img->DepthLog2 = logbase2(depth - 2 * border);
+   img->Width2 = 1 << img->WidthLog2;
+   img->Height2 = 1 << img->HeightLog2;
+   img->Depth2 = 1 << img->DepthLog2;
+   img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
+   img->IsCompressed = is_compressed_format(ctx, internalFormat);
+
+   if (height == 1 && depth == 1) {
+      img->FetchTexel = fetch_1d_texel;
+   }
+   else if (depth == 1) {
+      img->FetchTexel = fetch_2d_texel;
+   }
+   else {
+      img->FetchTexel = fetch_3d_texel;
+   }
+}
+
+
+
+/*
+ * Given an internal texture format enum or 1, 2, 3, 4 return the
+ * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
+ * number of components for the format.  Return -1 if invalid enum.
+ */
+static GLint
+components_in_intformat( GLint format )
+{
+   switch (format) {
+      case GL_ALPHA:
+      case GL_ALPHA4:
+      case GL_ALPHA8:
+      case GL_ALPHA12:
+      case GL_ALPHA16:
+         return 1;
+      case 1:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE4:
+      case GL_LUMINANCE8:
+      case GL_LUMINANCE12:
+      case GL_LUMINANCE16:
+         return 1;
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE4_ALPHA4:
+      case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+      case GL_LUMINANCE12_ALPHA4:
+      case GL_LUMINANCE12_ALPHA12:
+      case GL_LUMINANCE16_ALPHA16:
+         return 2;
+      case GL_INTENSITY:
+      case GL_INTENSITY4:
+      case GL_INTENSITY8:
+      case GL_INTENSITY12:
+      case GL_INTENSITY16:
+         return 1;
+      case 3:
+      case GL_RGB:
+      case GL_R3_G3_B2:
+      case GL_RGB4:
+      case GL_RGB5:
+      case GL_RGB8:
+      case GL_RGB10:
+      case GL_RGB12:
+      case GL_RGB16:
+         return 3;
+      case 4:
+      case GL_RGBA:
+      case GL_RGBA2:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8:
+      case GL_RGB10_A2:
+      case GL_RGBA12:
+      case GL_RGBA16:
+         return 4;
+      case GL_COLOR_INDEX:
+      case GL_COLOR_INDEX1_EXT:
+      case GL_COLOR_INDEX2_EXT:
+      case GL_COLOR_INDEX4_EXT:
+      case GL_COLOR_INDEX8_EXT:
+      case GL_COLOR_INDEX12_EXT:
+      case GL_COLOR_INDEX16_EXT:
+         return 1;
+      default:
+         return -1;  /* error */
+   }
+}
+
+
+/*
+ * This function is used to transfer the user's image data into a texture
+ * image buffer.  We handle both full texture images and subtexture images.
+ * We also take care of all image transfer operations here, including
+ * convolution, scale/bias, colortables, etc.
+ *
+ * The destination texel channel type is always GLchan.
+ *
+ * A hardware driver may use this as a helper routine to unpack and
+ * apply pixel transfer ops into a temporary image buffer.  Then,
+ * convert the temporary image into the special hardware format.
+ *
+ * Input:
+ *   dimensions - 1, 2, or 3
+ *   texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
+ *               GL_RGB or GL_RGBA
+ *   texAddr - destination image address
+ *   srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
+ *   dstXoffset, dstYoffset, dstZoffset - position to store the image within
+ *      the destination 3D texture
+ *   dstRowStride, dstImageStride - dest image strides in GLchan's
+ *   srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
+ *   srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
+ *   srcPacking - describes packing of incoming image.
+ */
+void
+_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
+                        GLenum texFormat, GLchan *texAddr,
+                        GLint srcWidth, GLint srcHeight, GLint srcDepth,
+                        GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+                        GLint dstRowStride, GLint dstImageStride,
+                        GLenum srcFormat, GLenum srcType,
+                        const GLvoid *srcAddr,
+                        const struct gl_pixelstore_attrib *srcPacking)
+{
+   GLint texComponents;
+
+   ASSERT(ctx);
+   ASSERT(dimensions >= 1 && dimensions <= 3);
+   ASSERT(texAddr);
+   ASSERT(srcWidth >= 1);
+   ASSERT(srcHeight >= 1);
+   ASSERT(srcDepth >= 1);
+   ASSERT(dstXoffset >= 0);
+   ASSERT(dstYoffset >= 0);
+   ASSERT(dstZoffset >= 0);
+   ASSERT(dstRowStride >= 0);
+   ASSERT(dstImageStride >= 0);
+   ASSERT(srcAddr);
+   ASSERT(srcPacking);
+
+   texComponents = components_in_intformat(texFormat);
+
+   /* try common 2D texture cases first */
+   if (!ctx->_ImageTransferState && dimensions == 2
+       && srcType == GL_UNSIGNED_BYTE) {
+
+      if (srcFormat == texFormat) {
+         /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
+          * GL_LUMINANCE_ALPHA, etc. texture formats.  Use memcpy().
+          */
+         const GLchan *src = (const GLchan *) _mesa_image_address(
+                                   srcPacking, srcAddr, srcWidth, srcHeight,
+                                   srcFormat, srcType, 0, 0, 0);
+         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+                                               srcWidth, srcFormat, srcType);
+         const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
+         GLchan *dst = texAddr + dstYoffset * dstRowStride
+                      + dstXoffset * texComponents;
+         if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
+            MEMCPY(dst, src, srcHeight * widthInBytes);
+         }
+         else {
+            GLint i;
+            for (i = 0; i < srcHeight; i++) {
+               MEMCPY(dst, src, widthInBytes);
+               src += srcRowStride;
+               dst += dstRowStride;
+            }
+         }
+         return;  /* all done */
+      }
+      else if (srcFormat == GL_RGBA && texFormat == GL_RGB) {
+         /* commonly used by Quake */
+         const GLchan *src = (const GLchan *) _mesa_image_address(
+                                   srcPacking, srcAddr, srcWidth, srcHeight,
+                                   srcFormat, srcType, 0, 0, 0);
+         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+                                               srcWidth, srcFormat, srcType);
+         GLchan *dst = texAddr + dstYoffset * dstRowStride
+                      + dstXoffset * texComponents;
+         GLint i, j;
+         for (i = 0; i < srcHeight; i++) {
+            const GLchan *s = src;
+            GLchan *d = dst;
+            for (j = 0; j < srcWidth; j++) {
+               *d++ = *s++;  /*red*/
+               *d++ = *s++;  /*green*/
+               *d++ = *s++;  /*blue*/
+               s++;          /*alpha*/
+            }
+            src += srcRowStride;
+            dst += dstRowStride;
+         }
+         return;  /* all done */
+      }
+   }
+
+   /*
+    * General case solutions
+    */
+   if (texFormat == GL_COLOR_INDEX) {
+      /* color index texture */
+      const GLenum texType = GL_UNSIGNED_BYTE;
+      GLint img, row;
+      GLchan *dest = texAddr + dstZoffset * dstImageStride
+                    + dstYoffset * dstRowStride
+                    + dstXoffset * texComponents;
+      for (img = 0; img < srcDepth; img++) {
+         GLchan *destRow = dest;
+         for (row = 0; row < srcHeight; row++) {
+            const GLvoid *src = _mesa_image_address(srcPacking,
+                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
+                                    srcType, src, srcPacking,
+                                    ctx->_ImageTransferState);
+            destRow += dstRowStride;
+         }
+         dest += dstImageStride;
+      }
+   }
+   else {
+      /* regular, color texture */
+      if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
+          (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
+          (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
+         /*
+          * Fill texture image with convolution
+          */
+         GLint img, row;
+         GLint convWidth = srcWidth, convHeight = srcHeight;
+         GLfloat *tmpImage, *convImage;
+         tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
+         if (!tmpImage) {
+            gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+            return;
+         }
+         convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
+         if (!convImage) {
+            gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+            FREE(tmpImage);
+            return;
+         }
+
+         for (img = 0; img < srcDepth; img++) {
+            const GLfloat *srcf;
+            GLfloat *dstf = tmpImage;
+            GLchan *dest;
+
+            /* unpack and do transfer ops up to convolution */
+            for (row = 0; row < srcHeight; row++) {
+               const GLvoid *src = _mesa_image_address(srcPacking,
+                                              srcAddr, srcWidth, srcHeight,
+                                              srcFormat, srcType, img, row, 0);
+               _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
+                         srcFormat, srcType, src, srcPacking,
+                         ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
+                         GL_TRUE);
+               dstf += srcWidth * 4;
+            }
+
+            /* convolve */
+            if (dimensions == 1) {
+               ASSERT(ctx->Pixel.Convolution1DEnabled);
+               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
+            }
+            else {
+               if (ctx->Pixel.Convolution2DEnabled) {
+                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
+                                          tmpImage, convImage);
+               }
+               else {
+                  ASSERT(ctx->Pixel.Separable2DEnabled);
+                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
+                                           tmpImage, convImage);
+               }
+            }
+
+            /* packing and transfer ops after convolution */
+            srcf = convImage;
+            dest = texAddr + (dstZoffset + img) * dstImageStride
+                 + dstYoffset * dstRowStride;
+            for (row = 0; row < convHeight; row++) {
+               _mesa_pack_float_rgba_span(ctx, convWidth,
+                                          (const GLfloat (*)[4]) srcf,
+                                          texFormat, GL_UNSIGNED_BYTE,
+                                          dest, &_mesa_native_packing,
+                                          ctx->_ImageTransferState
+                                          & IMAGE_POST_CONVOLUTION_BITS);
+               srcf += convWidth * 4;
+               dest += dstRowStride;
+            }
+         }
+
+         FREE(convImage);
+         FREE(tmpImage);
+      }
+      else {
+         /*
+          * no convolution
+          */
+         GLint img, row;
+         GLchan *dest = texAddr + dstZoffset * dstImageStride
+                       + dstYoffset * dstRowStride
+                       + dstXoffset * texComponents;
+         for (img = 0; img < srcDepth; img++) {
+            GLchan *destRow = dest;
+            for (row = 0; row < srcHeight; row++) {
+               const GLvoid *srcRow = _mesa_image_address(srcPacking,
+                                              srcAddr, srcWidth, srcHeight,
+                                              srcFormat, srcType, img, row, 0);
+               _mesa_unpack_chan_color_span(ctx, srcWidth, texFormat, destRow,
+                                       srcFormat, srcType, srcRow, srcPacking,
+                                       ctx->_ImageTransferState);
+               destRow += dstRowStride;
+            }
+            dest += dstImageStride;
+         }
+      }
+   }
+}
+
+
+
+/*
+ * This is the software fallback for Driver.TexImage1D().
+ * The texture image type will be GLchan.
+ * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
+ * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
+ *
+ */
+void
+_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint border,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage)
+{
+   const GLint components = components_in_intformat(internalFormat);
+   GLint postConvWidth = width;
+
+   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
+   }
+
+   /* setup the teximage struct's fields */
+   init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+                        border, internalFormat);
+
+   /* allocate memory */
+   texImage->Data = (GLchan *) MALLOC(postConvWidth
+                                      * components * sizeof(GLchan));
+   if (!texImage->Data)
+      return;      /* out of memory */
+
+   /* unpack image, apply transfer ops and store in texImage->Data */
+   _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data,
+                           width, 1, 1, 0, 0, 0,
+                           0, /* dstRowStride */
+                           0, /* dstImageStride */
+                           format, type, pixels, packing);
+}
+
+
+/*
+ * This is the software fallback for Driver.TexImage2D().
+ * The texture image type will be GLchan.
+ * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
+ * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
+ *
+ */
+void
+_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint border,
+                       GLenum format, GLenum type, const void *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage)
+{
+   const GLint components = components_in_intformat(internalFormat);
+   GLint postConvWidth = width, postConvHeight = height;
+
+   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
+                                         &postConvHeight);
+   }
+
+   /* setup the teximage struct's fields */
+   init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
+                        border, internalFormat);
+
+   /* allocate memory */
+   texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight
+                                      * components * sizeof(GLchan));
+   if (!texImage->Data)
+      return;      /* out of memory */
+
+   /* unpack image, apply transfer ops and store in texImage->Data */
+   _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data,
+                           width, height, 1, 0, 0, 0,
+                           texImage->Width * components * sizeof(GLchan),
+                           0, /* dstImageStride */
+                           format, type, pixels, packing);
+}
+
+
+
+/*
+ * This is the software fallback for Driver.TexImage3D().
+ * The texture image type will be GLchan.
+ * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
+ * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
+ *
+ */
+void
+_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint depth, GLint border,
+                       GLenum format, GLenum type, const void *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage)
+{
+   const GLint components = components_in_intformat(internalFormat);
+
+   /* setup the teximage struct's fields */
+   init_teximage_fields(ctx, texImage, width, height, depth,
+                        border, internalFormat);
+
+   /* allocate memory */
+   texImage->Data = (GLchan *) MALLOC(width * height * depth
+                                      * components * sizeof(GLchan));
+   if (!texImage->Data)
+      return;      /* out of memory */
+
+   /* unpack image, apply transfer ops and store in texImage->Data */
+   _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data,
+                           width, height, depth, 0, 0, 0,
+                           texImage->Width * components * sizeof(GLchan),
+                           texImage->Width * texImage->Height * components
+                           * sizeof(GLchan),
+                           format, type, pixels, packing);
+}
+
+
+
+
+/*
+ * This is the software fallback for Driver.TexSubImage1D().
+ */
+void
+_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint width,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage)
+{
+   _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data,
+                           width, 1, 1, /* src size */
+                           xoffset, 0, 0, /* dest offsets */
+                           0, /* dstRowStride */
+                           0, /* dstImageStride */
+                           format, type, pixels, packing);
+}
+
+
+/*
+ * This is the software fallback for Driver.TexSubImage2D().
+ */
+void
+_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset,
+                          GLint width, GLint height,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage)
+{
+   const GLint components = components_in_intformat(texImage->IntFormat);
+   _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data,
+                           width, height, 1, /* src size */
+                           xoffset, yoffset, 0, /* dest offsets */
+                           texImage->Width * components * sizeof(GLchan),
+                           0, /* dstImageStride */
+                           format, type, pixels, packing);
+}
+
+
+/*
+ * This is the software fallback for Driver.TexSubImage3D().
+ */
+void
+_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLint width, GLint height, GLint depth,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage)
+{
+   const GLint components = components_in_intformat(texImage->IntFormat);
+   _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data,
+                           width, height, depth, /* src size */
+                           xoffset, yoffset, xoffset, /* dest offsets */
+                           texImage->Width * components * sizeof(GLchan),
+                           texImage->Width * texImage->Height * components
+                           * sizeof(GLchan),
+                           format, type, pixels, packing);
+}
+
+
+
+/*
+ * Fallback for Driver.CompressedTexImage1D()
+ */
+void
+_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage)
+{
+   /* Nothing here.
+    * The device driver has to do it all.
+    */
+}
+
+
+
+/*
+ * Fallback for Driver.CompressedTexImage2D()
+ */
+void
+_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint height, GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage)
+{
+   /* Nothing here.
+    * The device driver has to do it all.
+    */
+}
+
+
+
+/*
+ * Fallback for Driver.CompressedTexImage3D()
+ */
+void
+_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint height, GLint depth,
+                                  GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage)
+{
+   /* Nothing here.
+    * The device driver has to do it all.
+    */
+}
+
+
+
+
+
+
+/*
+ * This is the fallback for Driver.TestProxyTexImage().
+ */
+GLboolean
+_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);
+
+   /* We always pass.
+    * The core Mesa code will have already tested the image size, etc.
+    * Drivers may have more stringent texture limits to enforce and will
+    * have to override this function.
+    */
+   init_teximage_fields(ctx, texImage, width, height, depth, border,
+                        internalFormat);
+
+   return GL_TRUE;
+}
+
diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h
new file mode 100644 (file)
index 0000000..96bdf09
--- /dev/null
@@ -0,0 +1,143 @@
+/* $Id: texstore.h,v 1.1 2001/02/06 21:42:48 brianp Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2001  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"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Authors:
+ *   Brian Paul
+ */
+
+
+#ifndef TEXSTORE_H
+#define TEXSTORE_H
+
+
+#include "mtypes.h"
+
+
+extern void
+_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
+                        GLenum texFormat, GLchan *texAddr,
+                        GLint srcWidth, GLint srcHeight, GLint srcDepth,
+                        GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+                        GLint dstRowStride, GLint dstImageStride,
+                        GLenum srcFormat, GLenum srcType,
+                        const GLvoid *srcAddr,
+                        const struct gl_pixelstore_attrib *srcPacking);
+
+
+extern void
+_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint border,
+                       GLenum format, GLenum type, const GLvoid *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint border,
+                       GLenum format, GLenum type, const void *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+                       GLint internalFormat,
+                       GLint width, GLint height, GLint depth, GLint border,
+                       GLenum format, GLenum type, const void *pixels,
+                       const struct gl_pixelstore_attrib *packing,
+                       struct gl_texture_object *texObj,
+                       struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint width,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset,
+                          GLint width, GLint height,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLint width, GLint height, GLint depth,
+                          GLenum format, GLenum type, const void *pixels,
+                          const struct gl_pixelstore_attrib *packing,
+                          struct gl_texture_object *texObj,
+                          struct gl_texture_image *texImage);
+
+
+
+extern void
+_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint height, GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage);
+
+extern void
+_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+                                  GLint internalFormat,
+                                  GLint width, GLint height, GLint depth,
+                                  GLint border,
+                                  GLsizei imageSize, const GLvoid *data,
+                                  struct gl_texture_object *texObj,
+                                  struct gl_texture_image *texImage);
+
+
+extern GLboolean
+_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
+                         GLint internalFormat, GLenum format, GLenum type,
+                         GLint width, GLint height, GLint depth, GLint border);
+
+
+#endif
index 1123cdc..80fd98b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_texture.c,v 1.8 2001/01/06 22:46:13 gareth Exp $ */
+/* $Id: s_texture.c,v 1.9 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 
 
 
-
-/*
- * Paletted texture sampling.
- * Input:  tObj - the texture object
- *         index - the palette index (8-bit only)
- * Output:  red, green, blue, alpha - the texel color
- */
-static void
-palette_sample(const struct gl_texture_object *tObj,
-               GLint index, GLchan rgba[4] )
-{
-   GLcontext *ctx = _mesa_get_current_context();  /* THIS IS A HACK */
-   const GLchan *palette;
-   GLenum format;
-
-   if (ctx->Texture.SharedPalette) {
-      ASSERT(!ctx->Texture.Palette.FloatTable);
-      palette = (const GLchan *) ctx->Texture.Palette.Table;
-      format = ctx->Texture.Palette.Format;
-   }
-   else {
-      ASSERT(!tObj->Palette.FloatTable);
-      palette = (const GLchan *) tObj->Palette.Table;
-      format = tObj->Palette.Format;
-   }
-
-   switch (format) {
-      case GL_ALPHA:
-         rgba[ACOMP] = palette[index];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = palette[index];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         rgba[RCOMP] = palette[(index << 1) + 0];
-         rgba[ACOMP] = palette[(index << 1) + 1];
-         return;
-      case GL_RGB:
-         rgba[RCOMP] = palette[index * 3 + 0];
-         rgba[GCOMP] = palette[index * 3 + 1];
-         rgba[BCOMP] = palette[index * 3 + 2];
-         return;
-      case GL_RGBA:
-         rgba[RCOMP] = palette[(index << 2) + 0];
-         rgba[GCOMP] = palette[(index << 2) + 1];
-         rgba[BCOMP] = palette[(index << 2) + 2];
-         rgba[ACOMP] = palette[(index << 2) + 3];
-         return;
-      default:
-         gl_problem(NULL, "Bad palette format in palette_sample");
-   }
-}
-
-
-
 /*
  * These values are used in the fixed-point arithmetic used
  * for linear filtering.
@@ -215,74 +159,16 @@ palette_sample(const struct gl_texture_object *tObj,
 /*                    1-D Texture Sampling Functions                  */
 /**********************************************************************/
 
-
-/*
- * Given 1-D texture image and an (i) texel column coordinate, return the
- * texel color.
- */
-static void
-get_1d_texel( const struct gl_texture_object *tObj,
-              const struct gl_texture_image *img, GLint i,
-              GLchan rgba[4] )
-{
-   const GLchan *texel;
-
-#ifdef DEBUG
-   GLint width = img->Width;
-   assert(i >= 0);
-   assert(i < width);
-#endif
-
-   switch (img->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[i];
-            palette_sample(tObj, index, rgba);
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[ i ];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[ i ];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + i * 2;
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + i * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + i * 4;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in get_1d_texel");
-         return;
-   }
-}
-
-
-
 /*
  * Return the texture sample for coordinate (s) using GL_NEAREST filter.
  */
 static void
-sample_1d_nearest( const struct gl_texture_object *tObj,
-                   const struct gl_texture_image *img,
-                   GLfloat s, GLchan rgba[4] )
+sample_1d_nearest(GLcontext *ctx,
+                  const struct gl_texture_object *tObj,
+                  const struct gl_texture_image *img,
+                  GLfloat s, GLchan rgba[4])
 {
    const GLint width = img->Width2;  /* without border, power of two */
-   const GLchan *texel;
    GLint i;
 
    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
@@ -290,42 +176,7 @@ sample_1d_nearest( const struct gl_texture_object *tObj,
    /* skip over the border, if any */
    i += img->Border;
 
-   /* Get the texel */
-   switch (img->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[i];
-            palette_sample(tObj, index, rgba );
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[i];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[i];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + i * 2;
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + i * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + i * 4;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in sample_1d_nearest");
-   }
+   (*img->FetchTexel)(ctx, tObj, img, i, 0, 0, rgba);
 }
 
 
@@ -334,9 +185,10 @@ sample_1d_nearest( const struct gl_texture_object *tObj,
  * Return the texture sample for coordinate (s) using GL_LINEAR filter.
  */
 static void
-sample_1d_linear( const struct gl_texture_object *tObj,
-                  const struct gl_texture_image *img,
-                  GLfloat s, GLchan rgba[4] )
+sample_1d_linear(GLcontext *ctx,
+                 const struct gl_texture_object *tObj,
+                 const struct gl_texture_image *img,
+                 GLfloat s, GLchan rgba[4])
 {
    const GLint width = img->Width2;
    GLint i0, i1;
@@ -367,13 +219,13 @@ sample_1d_linear( const struct gl_texture_object *tObj,
          COPY_CHAN4(t0, tObj->BorderColor);
       }
       else {
-         get_1d_texel( tObj, img, i0, t0 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, 0, 0, t0);
       }
       if (useBorderColor & I1BIT) {
          COPY_CHAN4(t1, tObj->BorderColor);
       }
       else {
-         get_1d_texel( tObj, img, i1, t1 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, 0, 0, t1);
       }
 
       rgba[0] = (GLchan) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT);
@@ -385,45 +237,48 @@ sample_1d_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_1d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
-                                  GLfloat s, GLfloat lambda,
-                                  GLchan rgba[4] )
+sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
+                                 const struct gl_texture_object *tObj,
+                                 GLfloat s, GLfloat lambda,
+                                 GLchan rgba[4])
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_1d_nearest( tObj, tObj->Image[level], s, rgba );
+   sample_1d_nearest(ctx, tObj, tObj->Image[level], s, rgba);
 }
 
 
 static void
-sample_1d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat lambda,
-                                 GLchan rgba[4] )
+sample_1d_linear_mipmap_nearest(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat lambda,
+                                GLchan rgba[4])
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_1d_linear( tObj, tObj->Image[level], s, rgba );
+   sample_1d_linear(ctx, tObj, tObj->Image[level], s, rgba);
 }
 
 
 
 static void
-sample_1d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat lambda,
-                                 GLchan rgba[4] )
+sample_1d_nearest_mipmap_linear(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat lambda,
+                                GLchan rgba[4])
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_1d_nearest( tObj, tObj->Image[tObj->_MaxLevel], s, rgba );
+      sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
    }
    else {
       GLchan t0[4], t1[4];
       const GLfloat f = FRAC(lambda);
-      sample_1d_nearest( tObj, tObj->Image[level  ], s, t0 );
-      sample_1d_nearest( tObj, tObj->Image[level+1], s, t1 );
+      sample_1d_nearest(ctx, tObj, tObj->Image[level  ], s, t0);
+      sample_1d_nearest(ctx, tObj, tObj->Image[level+1], s, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -434,22 +289,23 @@ sample_1d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_1d_linear_mipmap_linear( const struct gl_texture_object *tObj,
-                                GLfloat s, GLfloat lambda,
-                                GLchan rgba[4] )
+sample_1d_linear_mipmap_linear(GLcontext *ctx,
+                               const struct gl_texture_object *tObj,
+                               GLfloat s, GLfloat lambda,
+                               GLchan rgba[4])
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_1d_linear( tObj, tObj->Image[tObj->_MaxLevel], s, rgba );
+      sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
    }
    else {
       GLchan t0[4], t1[4];
       const GLfloat f = FRAC(lambda);
-      sample_1d_linear( tObj, tObj->Image[level  ], s, t0 );
-      sample_1d_linear( tObj, tObj->Image[level+1], s, t1 );
+      sample_1d_linear(ctx, tObj, tObj->Image[level  ], s, t0);
+      sample_1d_linear(ctx, tObj, tObj->Image[level+1], s, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -472,7 +328,7 @@ sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
    (void) u;
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_1d_nearest( tObj, image, s[i], rgba[i] );
+      sample_1d_nearest(ctx, tObj, image, s[i], rgba[i]);
    }
 }
 
@@ -491,7 +347,7 @@ sample_linear_1d( GLcontext *ctx, GLuint texUnit,
    (void) u;
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_1d_linear( tObj, image, s[i], rgba[i] );
+      sample_1d_linear(ctx, tObj, image, s[i], rgba[i]);
    }
 }
 
@@ -519,22 +375,28 @@ sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
          /* minification */
          switch (tObj->MinFilter) {
             case GL_NEAREST:
-               sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+               sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                 s[i], rgba[i]);
                break;
             case GL_LINEAR:
-               sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+               sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                s[i], rgba[i]);
                break;
             case GL_NEAREST_MIPMAP_NEAREST:
-               sample_1d_nearest_mipmap_nearest( tObj, lambda[i], s[i], rgba[i] );
+               sample_1d_nearest_mipmap_nearest(ctx, tObj, lambda[i], s[i],
+                                                rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_NEAREST:
-               sample_1d_linear_mipmap_nearest( tObj, s[i], lambda[i], rgba[i] );
+               sample_1d_linear_mipmap_nearest(ctx, tObj, s[i], lambda[i],
+                                               rgba[i]);
                break;
             case GL_NEAREST_MIPMAP_LINEAR:
-               sample_1d_nearest_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
+               sample_1d_nearest_mipmap_linear(ctx, tObj, s[i], lambda[i],
+                                               rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_LINEAR:
-               sample_1d_linear_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
+               sample_1d_linear_mipmap_linear(ctx, tObj, s[i], lambda[i],
+                                              rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad min filter in sample_1d_texture");
@@ -545,10 +407,12 @@ sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
          /* magnification */
          switch (tObj->MagFilter) {
             case GL_NEAREST:
-               sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+               sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                 s[i], rgba[i]);
                break;
             case GL_LINEAR:
-               sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+               sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                s[i], rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad mag filter in sample_1d_texture");
@@ -567,77 +431,17 @@ sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
 
 
 /*
- * Given a texture image and an (i,j) integer texel coordinate, return the
- * texel color.
- */
-static void
-get_2d_texel( const struct gl_texture_object *tObj,
-              const struct gl_texture_image *img, GLint i, GLint j,
-              GLchan rgba[4] )
-{
-   const GLint width = img->Width;    /* includes border */
-   const GLchan *texel;
-
-#ifdef DEBUG
-   const GLint height = img->Height;  /* includes border */
-   assert(i >= 0);
-   assert(i < width);
-   assert(j >= 0);
-   assert(j < height);
-#endif
-
-   switch (img->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[ width *j + i ];
-            palette_sample(tObj, index, rgba );
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[ width * j + i ];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[ width * j + i ];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + (width * j + i) * 2;
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + (width * j + i) * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + (width * j + i) * 4;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in get_2d_texel");
-   }
-}
-
-
-
-/*
  * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
  */
 static void
-sample_2d_nearest( const struct gl_texture_object *tObj,
-                   const struct gl_texture_image *img,
-                   GLfloat s, GLfloat t,
-                   GLchan rgba[] )
+sample_2d_nearest(GLcontext *ctx,
+                  const struct gl_texture_object *tObj,
+                  const struct gl_texture_image *img,
+                  GLfloat s, GLfloat t,
+                  GLchan rgba[])
 {
-   const GLint imgWidth = img->Width;  /* includes border */
    const GLint width = img->Width2;    /* without border, power of two */
    const GLint height = img->Height2;  /* without border, power of two */
-   const GLchan *texel;
    GLint i, j;
 
    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width,  i);
@@ -647,41 +451,7 @@ sample_2d_nearest( const struct gl_texture_object *tObj,
    i += img->Border;
    j += img->Border;
 
-   switch (img->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[ j * imgWidth + i ];
-            palette_sample(tObj, index, rgba);
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[ j * imgWidth + i ];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[ j * imgWidth + i ];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + ((j * imgWidth + i) << 1);
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + (j * imgWidth + i) * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + ((j * imgWidth + i) << 2);
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in sample_2d_nearest");
-   }
+   (*img->FetchTexel)(ctx, tObj, img, i, j, 0, rgba);
 }
 
 
@@ -691,10 +461,11 @@ sample_2d_nearest( const struct gl_texture_object *tObj,
  * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
  */
 static void
-sample_2d_linear( const struct gl_texture_object *tObj,
-                  const struct gl_texture_image *img,
-                  GLfloat s, GLfloat t,
-                  GLchan rgba[] )
+sample_2d_linear(GLcontext *ctx,
+                 const struct gl_texture_object *tObj,
+                 const struct gl_texture_image *img,
+                 GLfloat s, GLfloat t,
+                 GLchan rgba[])
 {
    const GLint width = img->Width2;
    const GLint height = img->Height2;
@@ -736,25 +507,25 @@ sample_2d_linear( const struct gl_texture_object *tObj,
          COPY_CHAN4(t00, tObj->BorderColor);
       }
       else {
-         get_2d_texel( tObj, img, i0, j0, t00 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j0, 0, t00);
       }
       if (useBorderColor & (I1BIT | J0BIT)) {
          COPY_CHAN4(t10, tObj->BorderColor);
       }
       else {
-         get_2d_texel( tObj, img, i1, j0, t10 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j0, 0, t10);
       }
       if (useBorderColor & (I0BIT | J1BIT)) {
          COPY_CHAN4(t01, tObj->BorderColor);
       }
       else {
-         get_2d_texel( tObj, img, i0, j1, t01 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j1, 0, t01);
       }
       if (useBorderColor & (I1BIT | J1BIT)) {
          COPY_CHAN4(t11, tObj->BorderColor);
       }
       else {
-         get_2d_texel( tObj, img, i1, j1, t11 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j1, 0, t11);
       }
 
       rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
@@ -768,46 +539,49 @@ sample_2d_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_2d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
-                                  GLfloat s, GLfloat t, GLfloat lambda,
-                                  GLchan rgba[4] )
+sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
+                                 const struct gl_texture_object *tObj,
+                                 GLfloat s, GLfloat t, GLfloat lambda,
+                                 GLchan rgba[4])
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_2d_nearest( tObj, tObj->Image[level], s, t, rgba );
+   sample_2d_nearest(ctx, tObj, tObj->Image[level], s, t, rgba);
 }
 
 
 
 static void
-sample_2d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat t, GLfloat lambda,
-                                 GLchan rgba[4] )
+sample_2d_linear_mipmap_nearest(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat t, GLfloat lambda,
+                                GLchan rgba[4])
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_2d_linear( tObj, tObj->Image[level], s, t, rgba );
+   sample_2d_linear(ctx, tObj, tObj->Image[level], s, t, rgba);
 }
 
 
 
 static void
-sample_2d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat t, GLfloat lambda,
-                                 GLchan rgba[4] )
+sample_2d_nearest_mipmap_linear(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat t, GLfloat lambda,
+                                GLchan rgba[4])
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_2d_nearest( tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba );
+      sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
    }
    else {
       GLchan t0[4], t1[4];  /* texels */
       const GLfloat f = FRAC(lambda);
-      sample_2d_nearest( tObj, tObj->Image[level  ], s, t, t0 );
-      sample_2d_nearest( tObj, tObj->Image[level+1], s, t, t1 );
+      sample_2d_nearest(ctx, tObj, tObj->Image[level  ], s, t, t0);
+      sample_2d_nearest(ctx, tObj, tObj->Image[level+1], s, t, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -818,22 +592,23 @@ sample_2d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_2d_linear_mipmap_linear( const struct gl_texture_object *tObj,
-                                GLfloat s, GLfloat t, GLfloat lambda,
-                                GLchan rgba[4] )
+sample_2d_linear_mipmap_linear(GLcontext *ctx,
+                               const struct gl_texture_object *tObj,
+                               GLfloat s, GLfloat t, GLfloat lambda,
+                               GLchan rgba[4])
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_2d_linear( tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba );
+      sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
    }
    else {
       GLchan t0[4], t1[4];  /* texels */
       const GLfloat f = FRAC(lambda);
-      sample_2d_linear( tObj, tObj->Image[level  ], s, t, t0 );
-      sample_2d_linear( tObj, tObj->Image[level+1], s, t, t1 );
+      sample_2d_linear(ctx, tObj, tObj->Image[level  ], s, t, t0);
+      sample_2d_linear(ctx, tObj, tObj->Image[level+1], s, t, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -855,7 +630,7 @@ sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
    (void) u;
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_2d_nearest( tObj, image, s[i], t[i], rgba[i] );
+      sample_2d_nearest(ctx, tObj, image, s[i], t[i], rgba[i]);
    }
 }
 
@@ -873,14 +648,14 @@ sample_linear_2d( GLcontext *ctx, GLuint texUnit,
    (void) u;
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_2d_linear( tObj, image, s[i], t[i], rgba[i] );
+      sample_2d_linear(ctx, tObj, image, s[i], t[i], rgba[i]);
    }
 }
 
 
 /*
- * Given an (s,t) texture coordinate and lambda (level of detail) value,
- * return a texture sample.
+ * Given an array of (s,t) texture coordinate and lambda (level of detail)
+ * values, return an array of texture sample.
  */
 static void
 sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
@@ -890,47 +665,76 @@ sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
                   const GLfloat u[], const GLfloat lambda[],
                   GLchan rgba[][4] )
 {
-   GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
+   const GLfloat minMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
    GLuint i;
    (void) u;
-   for (i=0;i<n;i++) {
-      if (lambda[i] > MinMagThresh) {
-         /* minification */
-         switch (tObj->MinFilter) {
-            case GL_NEAREST:
-               sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
-               break;
-            case GL_LINEAR:
-               sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
-               break;
-            case GL_NEAREST_MIPMAP_NEAREST:
-               sample_2d_nearest_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
-               break;
-            case GL_LINEAR_MIPMAP_NEAREST:
-               sample_2d_linear_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
-               break;
-            case GL_NEAREST_MIPMAP_LINEAR:
-               sample_2d_nearest_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
-               break;
-            case GL_LINEAR_MIPMAP_LINEAR:
-               sample_2d_linear_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
-               break;
-            default:
-               gl_problem(NULL, "Bad min filter in sample_2d_texture");
-               return;
-         }
+
+   /* check if lambda is monotonous-array */
+   if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
+      /* magnification */
+      switch (tObj->MagFilter) {
+      case GL_NEAREST:
+         for (i = 0; i < n; i++)
+            sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                              s[i], t[i], rgba[i] );
+         break;
+      case GL_LINEAR:
+         for (i = 0; i < n; i++)
+            sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                             s[i], t[i], rgba[i] );
+         break;
+      default:
+         gl_problem(NULL, "Bad mag filter in sample_2d_texture");
       }
-      else {
-         /* magnification */
-         switch (tObj->MagFilter) {
-            case GL_NEAREST:
-               sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
-               break;
-            case GL_LINEAR:
-               sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
-               break;
-            default:
-               gl_problem(NULL, "Bad mag filter in sample_2d_texture");
+   }
+   else {
+      for (i = 0; i < n; i++) {
+         if (lambda[i] > minMagThresh) {
+            /* minification */
+            switch (tObj->MinFilter) {
+               case GL_NEAREST:
+                  sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                    s[i], t[i], rgba[i]);
+                  break;
+               case GL_LINEAR:
+                  sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                   s[i], t[i], rgba[i]);
+                  break;
+               case GL_NEAREST_MIPMAP_NEAREST:
+                  sample_2d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i],
+                                                   lambda[i], rgba[i]);
+                  break;
+               case GL_LINEAR_MIPMAP_NEAREST:
+                  sample_2d_linear_mipmap_nearest(ctx,tObj, s[i], t[i],
+                                                  lambda[i], rgba[i]);
+                  break;
+               case GL_NEAREST_MIPMAP_LINEAR:
+                  sample_2d_nearest_mipmap_linear(ctx,tObj, s[i], t[i],
+                                                  lambda[i], rgba[i]);
+                  break;
+               case GL_LINEAR_MIPMAP_LINEAR:
+                  sample_2d_linear_mipmap_linear(ctx,tObj, s[i], t[i],
+                                                 lambda[i], rgba[i] );
+                  break;
+               default:
+                  gl_problem(NULL, "Bad min filter in sample_2d_texture");
+                  return;
+            }
+         }
+         else {
+            /* magnification */
+            switch (tObj->MagFilter) {
+               case GL_NEAREST:
+                  sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                    s[i], t[i], rgba[i]);
+                  break;
+               case GL_LINEAR:
+                  sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                   s[i], t[i], rgba[i] );
+                  break;
+               default:
+                  gl_problem(NULL, "Bad mag filter in sample_2d_texture");
+            }
          }
       }
    }
@@ -972,7 +776,7 @@ opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
       GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
       GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
       GLint pos = (j << shift) | i;
-      GLchan *texel = img->Data + pos + pos + pos;  /* pos*3 */
+      GLchan *texel = ((GLchan *) img->Data) + pos + pos + pos;  /* pos*3 */
       rgba[k][RCOMP] = texel[0];
       rgba[k][GCOMP] = texel[1];
       rgba[k][BCOMP] = texel[2];
@@ -1015,7 +819,7 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
       GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
       GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
       GLint pos = (j << shift) | i;
-      GLchan *texel = img->Data + (pos << 2);    /* pos*4 */
+      GLchan *texel = ((GLchan *) img->Data) + (pos << 2);    /* pos*4 */
       rgba[k][RCOMP] = texel[0];
       rgba[k][GCOMP] = texel[1];
       rgba[k][BCOMP] = texel[2];
@@ -1030,125 +834,25 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
 /**********************************************************************/
 
 /*
- * Given a texture image and an (i,j,k) integer texel coordinate, return the
- * texel color.
- */
-static void
-get_3d_texel( const struct gl_texture_object *tObj,
-              const struct gl_texture_image *img,
-              GLint i, GLint j, GLint k,
-              GLchan rgba[4] )
-{
-   const GLint width = img->Width;    /* includes border */
-   const GLint height = img->Height;  /* includes border */
-   const GLint rectarea = width * height;
-   const GLchan *texel;
-
-#ifdef DEBUG
-   const GLint depth = img->Depth;    /* includes border */
-   assert(i >= 0);
-   assert(i < width);
-   assert(j >= 0);
-   assert(j < height);
-   assert(k >= 0);
-   assert(k < depth);
-#endif
-
-   switch (img->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[ rectarea * k +  width * j + i ];
-            palette_sample(tObj, index, rgba );
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[ rectarea * k +  width * j + i ];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[ rectarea * k +  width * j + i ];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + ( rectarea * k + width * j + i) * 2;
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + (rectarea * k + width * j + i) * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + (rectarea * k + width * j + i) * 4;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in get_3d_texel");
-   }
-}
-
-
-/*
  * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  */
 static void
-sample_3d_nearest( const struct gl_texture_object *tObj,
-                   const struct gl_texture_image *img,
-                   GLfloat s, GLfloat t, GLfloat r,
-                   GLchan rgba[4] )
+sample_3d_nearest(GLcontext *ctx,
+                  const struct gl_texture_object *tObj,
+                  const struct gl_texture_image *img,
+                  GLfloat s, GLfloat t, GLfloat r,
+                  GLchan rgba[4])
 {
-   const GLint imgWidth = img->Width;   /* includes border, if any */
-   const GLint imgHeight = img->Height; /* includes border, if any */
    const GLint width = img->Width2;     /* without border, power of two */
    const GLint height = img->Height2;   /* without border, power of two */
    const GLint depth = img->Depth2;     /* without border, power of two */
-   const GLint rectarea = imgWidth * imgHeight;
-   const GLchan *texel;
    GLint i, j, k;
 
    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width,  i);
    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth,  k);
 
-   switch (tObj->Image[0]->Format) {
-      case GL_COLOR_INDEX:
-         {
-            GLint index = img->Data[ rectarea * k + j * imgWidth + i ];
-            palette_sample(tObj, index, rgba );
-            return;
-         }
-      case GL_ALPHA:
-         rgba[ACOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
-         return;
-      case GL_LUMINANCE:
-      case GL_INTENSITY:
-         rgba[RCOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
-         return;
-      case GL_LUMINANCE_ALPHA:
-         texel = img->Data + ((rectarea * k + j * imgWidth + i) << 1);
-         rgba[RCOMP] = texel[0];
-         rgba[ACOMP] = texel[1];
-         return;
-      case GL_RGB:
-         texel = img->Data + ( rectarea * k + j * imgWidth + i) * 3;
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         return;
-      case GL_RGBA:
-         texel = img->Data + ((rectarea * k + j * imgWidth + i) << 2);
-         rgba[RCOMP] = texel[0];
-         rgba[GCOMP] = texel[1];
-         rgba[BCOMP] = texel[2];
-         rgba[ACOMP] = texel[3];
-         return;
-      default:
-         gl_problem(NULL, "Bad format in sample_3d_nearest");
-   }
+   (*img->FetchTexel)(ctx, tObj, img, i, j, k, rgba);
 }
 
 
@@ -1157,10 +861,11 @@ sample_3d_nearest( const struct gl_texture_object *tObj,
  * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  */
 static void
-sample_3d_linear( const struct gl_texture_object *tObj,
-                  const struct gl_texture_image *img,
-                  GLfloat s, GLfloat t, GLfloat r,
-                  GLchan rgba[4] )
+sample_3d_linear(GLcontext *ctx,
+                 const struct gl_texture_object *tObj,
+                 const struct gl_texture_image *img,
+                 GLfloat s, GLfloat t, GLfloat r,
+                 GLchan rgba[4])
 {
    const GLint width = img->Width2;
    const GLint height = img->Height2;
@@ -1213,50 +918,50 @@ sample_3d_linear( const struct gl_texture_object *tObj,
          COPY_CHAN4(t000, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i0, j0, k0, t000 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j0, k0, t000);
       }
       if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
          COPY_CHAN4(t100, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i1, j0, k0, t100 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j0, k0, t100);
       }
       if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
          COPY_CHAN4(t010, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i0, j1, k0, t010 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j1, k0, t010);
       }
       if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
          COPY_CHAN4(t110, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i1, j1, k0, t110 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j1, k0, t110);
       }
 
       if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
          COPY_CHAN4(t001, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i0, j0, k1, t001 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j0, k1, t001);
       }
       if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
          COPY_CHAN4(t101, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i1, j0, k1, t101 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j0, k1, t101);
       }
       if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
          COPY_CHAN4(t011, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i0, j1, k1, t011 );
+         (*img->FetchTexel)(ctx, tObj, img, i0, j1, k1, t011);
       }
       if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
          COPY_CHAN4(t111, tObj->BorderColor);
       }
       else {
-         get_3d_texel( tObj, img, i1, j1, k1, t111 );
+         (*img->FetchTexel)(ctx, tObj, img, i1, j1, k1, t111);
       }
 
       rgba[0] = (GLchan) (
@@ -1281,44 +986,48 @@ sample_3d_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_3d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
-                                  GLfloat s, GLfloat t, GLfloat r,
-                                  GLfloat lambda, GLchan rgba[4] )
+sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
+                                 const struct gl_texture_object *tObj,
+                                 GLfloat s, GLfloat t, GLfloat r,
+                                 GLfloat lambda, GLchan rgba[4] )
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_3d_nearest( tObj, tObj->Image[level], s, t, r, rgba );
+   sample_3d_nearest(ctx, tObj, tObj->Image[level], s, t, r, rgba);
 }
 
 
 static void
-sample_3d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat t, GLfloat r,
-                                 GLfloat lambda, GLchan rgba[4] )
+sample_3d_linear_mipmap_nearest(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat t, GLfloat r,
+                                GLfloat lambda, GLchan rgba[4])
 {
    GLint level;
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-   sample_3d_linear( tObj, tObj->Image[level], s, t, r, rgba );
+   sample_3d_linear(ctx, tObj, tObj->Image[level], s, t, r, rgba);
 }
 
 
 static void
-sample_3d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
-                                 GLfloat s, GLfloat t, GLfloat r,
-                                 GLfloat lambda, GLchan rgba[4] )
+sample_3d_nearest_mipmap_linear(GLcontext *ctx,
+                                const struct gl_texture_object *tObj,
+                                GLfloat s, GLfloat t, GLfloat r,
+                                GLfloat lambda, GLchan rgba[4])
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_3d_nearest( tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba );
+      sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+                        s, t, r, rgba);
    }
    else {
       GLchan t0[4], t1[4];  /* texels */
       const GLfloat f = FRAC(lambda);
-      sample_3d_nearest( tObj, tObj->Image[level  ], s, t, r, t0 );
-      sample_3d_nearest( tObj, tObj->Image[level+1], s, t, r, t1 );
+      sample_3d_nearest(ctx, tObj, tObj->Image[level  ], s, t, r, t0);
+      sample_3d_nearest(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -1328,22 +1037,23 @@ sample_3d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_3d_linear_mipmap_linear( const struct gl_texture_object *tObj,
-                                GLfloat s, GLfloat t, GLfloat r,
-                                GLfloat lambda, GLchan rgba[4] )
+sample_3d_linear_mipmap_linear(GLcontext *ctx,
+                               const struct gl_texture_object *tObj,
+                               GLfloat s, GLfloat t, GLfloat r,
+                               GLfloat lambda, GLchan rgba[4] )
 {
    GLint level;
 
    COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
 
    if (level >= tObj->_MaxLevel) {
-      sample_3d_linear( tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba );
+      sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba);
    }
    else {
       GLchan t0[4], t1[4];  /* texels */
       const GLfloat f = FRAC(lambda);
-      sample_3d_linear( tObj, tObj->Image[level  ], s, t, r, t0 );
-      sample_3d_linear( tObj, tObj->Image[level+1], s, t, r, t1 );
+      sample_3d_linear(ctx, tObj, tObj->Image[level  ], s, t, r, t0);
+      sample_3d_linear(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -1353,17 +1063,17 @@ sample_3d_linear_mipmap_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_nearest_3d( GLcontext *ctx, GLuint texUnit,
-                   const struct gl_texture_object *tObj, GLuint n,
-                   const GLfloat s[], const GLfloat t[],
-                   const GLfloat u[], const GLfloat lambda[],
-                   GLchan rgba[][4] )
+sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
+                  const struct gl_texture_object *tObj, GLuint n,
+                  const GLfloat s[], const GLfloat t[],
+                  const GLfloat u[], const GLfloat lambda[],
+                  GLchan rgba[][4])
 {
    GLuint i;
    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_3d_nearest( tObj, image, s[i], t[i], u[i], rgba[i] );
+      sample_3d_nearest(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
    }
 }
 
@@ -1380,7 +1090,7 @@ sample_linear_3d( GLcontext *ctx, GLuint texUnit,
    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
    (void) lambda;
    for (i=0;i<n;i++) {
-      sample_3d_linear( tObj, image, s[i], t[i], u[i], rgba[i] );
+      sample_3d_linear(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
    }
 }
 
@@ -1405,22 +1115,28 @@ sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
          /* minification */
          switch (tObj->MinFilter) {
             case GL_NEAREST:
-               sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+               sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                 s[i], t[i], u[i], rgba[i]);
                break;
             case GL_LINEAR:
-               sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+               sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                s[i], t[i], u[i], rgba[i]);
                break;
             case GL_NEAREST_MIPMAP_NEAREST:
-               sample_3d_nearest_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+               sample_3d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+                                                lambda[i], rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_NEAREST:
-               sample_3d_linear_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+               sample_3d_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+                                               lambda[i], rgba[i]);
                break;
             case GL_NEAREST_MIPMAP_LINEAR:
-               sample_3d_nearest_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+               sample_3d_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+                                               lambda[i], rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_LINEAR:
-               sample_3d_linear_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+               sample_3d_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+                                              lambda[i], rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad min filterin sample_3d_texture");
@@ -1430,10 +1146,12 @@ sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
          /* magnification */
          switch (tObj->MagFilter) {
             case GL_NEAREST:
-               sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+               sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                 s[i], t[i], u[i], rgba[i]);
                break;
             case GL_LINEAR:
-               sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+               sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+                                s[i], t[i], u[i], rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad mag filter in sample_3d_texture");
@@ -1534,7 +1252,8 @@ sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
       const struct gl_texture_image **images;
       GLfloat newS, newT;
       images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
-      sample_2d_nearest( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
+      sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+                        newS, newT, rgba[i]);
    }
 }
 
@@ -1552,15 +1271,17 @@ sample_linear_cube(GLcontext *ctx, GLuint texUnit,
       const struct gl_texture_image **images;
       GLfloat newS, newT;
       images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
-      sample_2d_linear( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
+      sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+                       newS, newT, rgba[i]);
    }
 }
 
 
 static void
-sample_cube_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
-                                    GLfloat s, GLfloat t, GLfloat u,
-                                    GLfloat lambda, GLchan rgba[4] )
+sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
+                                   const struct gl_texture_object *tObj,
+                                   GLfloat s, GLfloat t, GLfloat u,
+                                   GLfloat lambda, GLchan rgba[4])
 {
    const struct gl_texture_image **images;
    GLfloat newS, newT;
@@ -1569,14 +1290,15 @@ sample_cube_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
 
    images = choose_cube_face(tObj, s, t, u, &newS, &newT);
-   sample_2d_nearest( tObj, images[level], newS, newT, rgba );
+   sample_2d_nearest(ctx, tObj, images[level], newS, newT, rgba);
 }
 
 
 static void
-sample_cube_linear_mipmap_nearest( const struct gl_texture_object *tObj,
-                                   GLfloat s, GLfloat t, GLfloat u,
-                                   GLfloat lambda, GLchan rgba[4] )
+sample_cube_linear_mipmap_nearest(GLcontext *ctx,
+                                  const struct gl_texture_object *tObj,
+                                  GLfloat s, GLfloat t, GLfloat u,
+                                  GLfloat lambda, GLchan rgba[4])
 {
    const struct gl_texture_image **images;
    GLfloat newS, newT;
@@ -1585,14 +1307,15 @@ sample_cube_linear_mipmap_nearest( const struct gl_texture_object *tObj,
    COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
 
    images = choose_cube_face(tObj, s, t, u, &newS, &newT);
-   sample_2d_linear( tObj, images[level], newS, newT, rgba );
+   sample_2d_linear(ctx, tObj, images[level], newS, newT, rgba);
 }
 
 
 static void
-sample_cube_nearest_mipmap_linear( const struct gl_texture_object *tObj,
-                                   GLfloat s, GLfloat t, GLfloat u,
-                                   GLfloat lambda, GLchan rgba[4] )
+sample_cube_nearest_mipmap_linear(GLcontext *ctx,
+                                  const struct gl_texture_object *tObj,
+                                  GLfloat s, GLfloat t, GLfloat u,
+                                  GLfloat lambda, GLchan rgba[4])
 {
    const struct gl_texture_image **images;
    GLfloat newS, newT;
@@ -1603,13 +1326,13 @@ sample_cube_nearest_mipmap_linear( const struct gl_texture_object *tObj,
    images = choose_cube_face(tObj, s, t, u, &newS, &newT);
 
    if (level >= tObj->_MaxLevel) {
-      sample_2d_nearest( tObj, images[tObj->_MaxLevel], newS, newT, rgba );
+      sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
    }
    else {
       GLchan t0[4], t1[4];  /* texels */
       const GLfloat f = FRAC(lambda);
-      sample_2d_nearest( tObj, images[level  ], newS, newT, t0 );
-      sample_2d_nearest( tObj, images[level+1], newS, newT, t1 );
+      sample_2d_nearest(ctx, tObj, images[level  ], newS, newT, t0);
+      sample_2d_nearest(ctx, tObj, images[level+1], newS, newT, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -1619,9 +1342,10 @@ sample_cube_nearest_mipmap_linear( const struct gl_texture_object *tObj,
 
 
 static void
-sample_cube_linear_mipmap_linear( const struct gl_texture_object *tObj,
-                                  GLfloat s, GLfloat t, GLfloat u,
-                                  GLfloat lambda, GLchan rgba[4] )
+sample_cube_linear_mipmap_linear(GLcontext *ctx,
+                                 const struct gl_texture_object *tObj,
+                                 GLfloat s, GLfloat t, GLfloat u,
+                                 GLfloat lambda, GLchan rgba[4])
 {
    const struct gl_texture_image **images;
    GLfloat newS, newT;
@@ -1632,13 +1356,13 @@ sample_cube_linear_mipmap_linear( const struct gl_texture_object *tObj,
    images = choose_cube_face(tObj, s, t, u, &newS, &newT);
 
    if (level >= tObj->_MaxLevel) {
-      sample_2d_linear( tObj, images[tObj->_MaxLevel], newS, newT, rgba );
+      sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
    }
    else {
       GLchan t0[4], t1[4];
       const GLfloat f = FRAC(lambda);
-      sample_2d_linear( tObj, images[level  ], newS, newT, t0 );
-      sample_2d_linear( tObj, images[level+1], newS, newT, t1 );
+      sample_2d_linear(ctx, tObj, images[level  ], newS, newT, t0);
+      sample_2d_linear(ctx, tObj, images[level+1], newS, newT, t1);
       rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
       rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
       rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
@@ -1667,8 +1391,8 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
                   GLfloat newS, newT;
                   images = choose_cube_face(tObj, s[i], t[i], u[i],
                                             &newS, &newT);
-                  sample_2d_nearest( tObj, images[tObj->BaseLevel],
-                                     newS, newT, rgba[i] );
+                  sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+                                    newS, newT, rgba[i]);
                }
                break;
             case GL_LINEAR:
@@ -1677,25 +1401,25 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
                   GLfloat newS, newT;
                   images = choose_cube_face(tObj, s[i], t[i], u[i],
                                             &newS, &newT);
-                  sample_2d_linear( tObj, images[tObj->BaseLevel],
-                                    newS, newT, rgba[i] );
+                  sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+                                   newS, newT, rgba[i]);
                }
                break;
             case GL_NEAREST_MIPMAP_NEAREST:
-               sample_cube_nearest_mipmap_nearest( tObj, s[i], t[i], u[i],
-                                                   lambda[i], rgba[i] );
+               sample_cube_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+                                                  lambda[i], rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_NEAREST:
-               sample_cube_linear_mipmap_nearest( tObj, s[i], t[i], u[i],
-                                                  lambda[i], rgba[i] );
+               sample_cube_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+                                                 lambda[i], rgba[i]);
                break;
             case GL_NEAREST_MIPMAP_LINEAR:
-               sample_cube_nearest_mipmap_linear( tObj, s[i], t[i], u[i],
-                                                  lambda[i], rgba[i] );
+               sample_cube_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+                                                 lambda[i], rgba[i]);
                break;
             case GL_LINEAR_MIPMAP_LINEAR:
-               sample_cube_linear_mipmap_linear( tObj, s[i], t[i], u[i],
-                                                 lambda[i], rgba[i] );
+               sample_cube_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+                                                lambda[i], rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad min filter in sample_lambda_cube");
@@ -1709,12 +1433,12 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
                                    &newS, &newT);
          switch (tObj->MagFilter) {
             case GL_NEAREST:
-               sample_2d_nearest( tObj, images[tObj->BaseLevel],
-                                  newS, newT, rgba[i] );
+               sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+                                 newS, newT, rgba[i]);
                break;
             case GL_LINEAR:
-               sample_2d_linear( tObj, images[tObj->BaseLevel],
-                                 newS, newT, rgba[i] );
+               sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+                                newS, newT, rgba[i]);
                break;
             default:
                gl_problem(NULL, "Bad mag filter in sample_lambda_cube");
@@ -1788,10 +1512,12 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
                ASSERT(t->MinFilter==GL_NEAREST);
                if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
                    && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGB) {
+                  /* XXX check for well-known texture image format */
                   swrast->TextureSample[texUnit] = opt_sample_rgb_2d;
                }
                else if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
                    && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGBA) {
+                  /* XXX check for well-known texture image format */
                   swrast->TextureSample[texUnit] = opt_sample_rgba_2d;
                }
                else
@@ -2585,13 +2311,6 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,
             }
          }
 
-         /* fetch texture images from device driver, if needed */
-         if (ctx->Driver.GetTexImage) {
-            if (!_mesa_get_teximages_from_driver(ctx, textureUnit->_Current)) {
-               return;
-            }
-         }
-
          /* Sample the texture. */
          SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
                                                      textureUnit->_Current,
index 1819e44..d268b2e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_triangle.c,v 1.10 2001/01/29 18:51:25 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.11 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -243,14 +243,12 @@ static void simple_textured_triangle( GLcontext *ctx,
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                            \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
@@ -304,14 +302,12 @@ static void simple_z_textured_triangle( GLcontext *ctx,
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                            \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
@@ -376,7 +372,7 @@ static void affine_textured_triangle( GLcontext *ctx,
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                             \
    GLint format = obj->Image[b]->Format;                                \
@@ -386,10 +382,8 @@ static void affine_textured_triangle( GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */        \
@@ -499,7 +493,7 @@ static void affine_textured_triangle( GLcontext *ctx,
            GLint s = FixedToInt(ffs) & smask;              \
            GLint t = FixedToInt(fft) & tmask;              \
            GLint pos = (t << twidth_log2) + s;             \
-           GLchan *tex00 = texture + COMP * pos;           \
+           const GLchan *tex00 = texture + COMP * pos;     \
           zspan[i] = FixedToDepth(ffz);                   \
           fogspan[i] = fffog / 256;                       \
            DO_TEX;                                         \
@@ -523,10 +517,10 @@ static void affine_textured_triangle( GLcontext *ctx,
            GLint si = FIXED_FRAC_MASK - sf;                \
            GLint ti = FIXED_FRAC_MASK - tf;                \
            GLint pos = (t << twidth_log2) + s;             \
-           GLchan *tex00 = texture + COMP * pos;           \
-           GLchan *tex10 = tex00 + tbytesline;             \
-           GLchan *tex01 = tex00 + COMP;                   \
-           GLchan *tex11 = tex10 + COMP;                   \
+           const GLchan *tex00 = texture + COMP * pos;     \
+           const GLchan *tex10 = tex00 + tbytesline;       \
+           const GLchan *tex01 = tex00 + COMP;             \
+           const GLchan *tex11 = tex10 + COMP;             \
            if (t == tmask) {                               \
               tex10 -= tsize;                              \
               tex11 -= tsize;                              \
@@ -705,7 +699,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
    const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
    const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
    const GLint twidth_log2 = obj->Image[b]->WidthLog2;                 \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    const GLint smask = (obj->Image[b]->Width - 1);                      \
    const GLint tmask = (obj->Image[b]->Height - 1);                     \
    const GLint format = obj->Image[b]->Format;                          \
@@ -714,10 +708,8 @@ static void near_persp_textured_triangle(GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
       er = FloatToFixed(unit->EnvColor[0]);                             \
@@ -1448,10 +1440,7 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
       er = FloatToFixed(unit->EnvColor[0]);                             \
@@ -2304,6 +2293,7 @@ _swrast_choose_triangle( GLcontext *ctx )
              && ((image = current2Dtex->Image[current2Dtex->BaseLevel]) != 0)  /* correct! */
              && image->Border==0
              && ((format = image->Format)==GL_RGB || format==GL_RGBA)
+             && image->Type == CHAN_TYPE
             && (filter = current2Dtex->MinFilter)==current2Dtex->MagFilter
             /* ==> current2Dtex->MinFilter != GL_XXX_MIPMAP_XXX */
             && ctx->Light.Model.ColorControl==GL_SINGLE_COLOR
index c0ab9f9..a622abe 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_tritemp.h,v 1.8 2001/01/29 18:51:25 brianp Exp $ */
+/* $Id: s_tritemp.h,v 1.9 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #error "Mipmapping without texturing doesn't make sense."
 #endif
       GLfloat lambda_nominator;
-#endif
+#endif /* INTERP_LAMBDA */
 
 
       /*
index 5889592..215749b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_imm_exec.c,v 1.9 2001/01/24 00:04:59 brianp Exp $ */
+/* $Id: t_imm_exec.c,v 1.10 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -37,7 +37,6 @@
 #include "mmath.h"
 #include "light.h"
 #include "state.h"
-#include "texture.h"
 #include "mtypes.h"
 
 #include "math/m_matrix.h"
index 44bd4c4..dc45799 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_imm_fixup.c,v 1.4 2001/01/24 00:04:59 brianp Exp $ */
+/* $Id: t_imm_fixup.c,v 1.5 2001/02/06 21:42:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -39,7 +39,6 @@
 #include "mem.h"
 #include "mmath.h"
 #include "state.h"
-#include "texture.h"
 #include "mtypes.h"
 
 #include "math/m_matrix.h"