mesa: document sRGBDecode field
[mesa.git] / src / mesa / main / texstore.c
index d3237959e0ce3f64764721d6db849a83fa48bbc9..7dd4a1fa6506d1b3f3157a543f2b0121244c84da 100644 (file)
@@ -45,7 +45,7 @@
  * Texture image processing is actually kind of complicated.  We have to do:
  *    Format/type conversions
  *    pixel unpacking
- *    pixel transfer (scale, bais, lookup, convolution!, etc)
+ *    pixel transfer (scale, bais, lookup, etc)
  *
  * These functions can handle most everything, including processing full
  * images and sub-images.
 #include "glheader.h"
 #include "bufferobj.h"
 #include "colormac.h"
-#include "context.h"
-#if FEATURE_convolve
-#include "convolve.h"
-#endif
 #include "image.h"
 #include "macros.h"
 #include "mipmap.h"
+#include "mfeatures.h"
+#include "mtypes.h"
+#include "pack.h"
 #include "imports.h"
+#include "pack.h"
 #include "texcompress.h"
-#include "texformat.h"
+#include "texcompress_fxt1.h"
+#include "texcompress_s3tc.h"
 #include "teximage.h"
 #include "texstore.h"
 #include "enums.h"
@@ -76,6 +77,12 @@ enum {
 };
 
 
+/**
+ * Texture image storage function.
+ */
+typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
+
+
 /**
  * Return GL_TRUE if the given image format is one that be converted
  * to another format by swizzling.
@@ -96,6 +103,7 @@ can_swizzle(GLenum logicalBaseFormat)
    case GL_BGR:
    case GL_BGRA:
    case GL_ABGR_EXT:
+   case GL_RG:
       return GL_TRUE;
    default:
       return GL_FALSE;
@@ -117,6 +125,7 @@ enum {
    IDX_BGR,
    IDX_BGRA,
    IDX_ABGR,
+   IDX_RG,
    MAX_IDX
 };
 
@@ -168,7 +177,6 @@ static const struct {
       MAP4(0,1,2,3),
    },
 
-
    {
       IDX_RED,
       MAP4(0, ZERO, ZERO, ONE),
@@ -204,6 +212,12 @@ static const struct {
       MAP4(3,2,1,0),
       MAP4(3,2,1,0)
    },
+
+   {
+      IDX_RG,
+      MAP4(0, 1, ZERO, ONE),
+      MAP2(0, 1)
+   },
 };
 
 
@@ -227,6 +241,7 @@ get_map_idx(GLenum value)
    case GL_BGR: return IDX_BGR;
    case GL_BGRA: return IDX_BGRA;
    case GL_ABGR_EXT: return IDX_ABGR;
+   case GL_RG: return IDX_RG;
    default:
       _mesa_problem(NULL, "Unexpected inFormat");
       return 0;
@@ -258,28 +273,18 @@ compute_component_mapping(GLenum inFormat, GLenum outFormat,
    map[ZERO] = ZERO;
    map[ONE] = ONE;   
 
-/*
-   _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
-               inFormat, _mesa_lookup_enum_by_nr(inFormat),
-               outFormat, _mesa_lookup_enum_by_nr(outFormat),
-               map[0], 
-               map[1], 
-               map[2], 
-               map[3], 
-               map[4], 
-               map[5]); 
-*/
-}
-
-
-#if !FEATURE_convolve
-static void
-_mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
-                                   GLsizei *srcWidth, GLsizei *srcHeight)
-{
-   /* no-op */
-}
+#if 0
+   printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
+         inFormat, _mesa_lookup_enum_by_nr(inFormat),
+         outFormat, _mesa_lookup_enum_by_nr(outFormat),
+         map[0], 
+         map[1], 
+         map[2], 
+         map[3], 
+         map[4], 
+         map[5]); 
 #endif
+}
 
 
 /**
@@ -287,7 +292,7 @@ _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
  * Apply all needed pixel unpacking and pixel transfer operations.
  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
  * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures.  So, might
+ * but the graphics hardware doesn't support luminance textures.  So, we might
  * use an RGB hardware format instead.
  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
  *
@@ -306,21 +311,28 @@ _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
  * \return resulting image with format = textureBaseFormat and type = GLfloat.
  */
 static GLfloat *
-make_temp_float_image(GLcontext *ctx, GLuint dims,
+make_temp_float_image(struct gl_context *ctx, GLuint dims,
                       GLenum logicalBaseFormat,
                       GLenum textureBaseFormat,
                       GLint srcWidth, GLint srcHeight, GLint srcDepth,
                       GLenum srcFormat, GLenum srcType,
                       const GLvoid *srcAddr,
-                      const struct gl_pixelstore_attrib *srcPacking)
+                      const struct gl_pixelstore_attrib *srcPacking,
+                      GLbitfield transferOps)
 {
-   GLuint transferOps = ctx->_ImageTransferState;
    GLfloat *tempImage;
+   const GLint components = _mesa_components_in_format(logicalBaseFormat);
+   const GLint srcStride =
+      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+   GLfloat *dst;
+   GLint img, row;
 
    ASSERT(dims >= 1 && dims <= 3);
 
    ASSERT(logicalBaseFormat == GL_RGBA ||
           logicalBaseFormat == GL_RGB ||
+          logicalBaseFormat == GL_RG ||
+          logicalBaseFormat == GL_RED ||
           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
           logicalBaseFormat == GL_LUMINANCE ||
           logicalBaseFormat == GL_ALPHA ||
@@ -330,6 +342,8 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(textureBaseFormat == GL_RGBA ||
           textureBaseFormat == GL_RGB ||
+          textureBaseFormat == GL_RG ||
+          textureBaseFormat == GL_RED ||
           textureBaseFormat == GL_LUMINANCE_ALPHA ||
           textureBaseFormat == GL_LUMINANCE ||
           textureBaseFormat == GL_ALPHA ||
@@ -337,126 +351,132 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
           textureBaseFormat == GL_COLOR_INDEX ||
           textureBaseFormat == GL_DEPTH_COMPONENT);
 
-   /* conventional color image */
+   tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+                                 * components * sizeof(GLfloat));
+   if (!tempImage)
+      return NULL;
 
-   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
-       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
-       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
-      /* need image convolution */
-      const GLuint preConvTransferOps
-         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
-      const GLuint postConvTransferOps
-         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
-      GLint img, row;
-      GLint convWidth, convHeight;
-      GLfloat *convImage;
+   dst = tempImage;
+   for (img = 0; img < srcDepth; img++) {
+      const GLubyte *src
+        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                                srcWidth, srcHeight,
+                                                srcFormat, srcType,
+                                                img, 0, 0);
+      for (row = 0; row < srcHeight; row++) {
+        _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
+                                      dst, srcFormat, srcType, src,
+                                      srcPacking, transferOps);
+        dst += srcWidth * components;
+        src += srcStride;
+      }
+   }
 
-      /* pre-convolution image buffer (3D) */
-      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
-                                           * 4 * sizeof(GLfloat));
-      if (!tempImage)
-         return NULL;
+   if (logicalBaseFormat != textureBaseFormat) {
+      /* more work */
+      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
+      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
+      GLfloat *newImage;
+      GLint i, n;
+      GLubyte map[6];
+
+      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
+      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
+             textureBaseFormat == GL_LUMINANCE_ALPHA);
+
+      /* The actual texture format should have at least as many components
+       * as the logical texture format.
+       */
+      ASSERT(texComponents >= logComponents);
 
-      /* post-convolution image buffer (2D) */
-      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
-                                           * 4 * sizeof(GLfloat));
-      if (!convImage) {
-         _mesa_free(tempImage);
+      newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+                                          * texComponents * sizeof(GLfloat));
+      if (!newImage) {
+         free(tempImage);
          return NULL;
       }
 
-      /* loop over 3D image slices */
-      for (img = 0; img < srcDepth; img++) {
-         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
+      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
 
-         /* unpack and do transfer ops up to convolution */
-         for (row = 0; row < srcHeight; row++) {
-            const GLvoid *src = _mesa_image_address(dims, srcPacking,
-                                              srcAddr, srcWidth, srcHeight,
-                                              srcFormat, srcType, img, row, 0);
-            _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
-                                          srcFormat, srcType, src,
-                                          srcPacking,
-                                          preConvTransferOps);
-            dst += srcWidth * 4;
+      n = srcWidth * srcHeight * srcDepth;
+      for (i = 0; i < n; i++) {
+         GLint k;
+         for (k = 0; k < texComponents; k++) {
+            GLint j = map[k];
+            if (j == ZERO)
+               newImage[i * texComponents + k] = 0.0F;
+            else if (j == ONE)
+               newImage[i * texComponents + k] = 1.0F;
+            else
+               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
          }
+      }
 
-         /* size after optional convolution */
-         convWidth = srcWidth;
-         convHeight = srcHeight;
-
-#if FEATURE_convolve
-         /* do convolution */
-         {
-            GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
-            if (dims == 1) {
-               ASSERT(ctx->Pixel.Convolution1DEnabled);
-               _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
-            }
-            else {
-               if (ctx->Pixel.Convolution2DEnabled) {
-                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
-                                          src, convImage);
-               }
-               else {
-                  ASSERT(ctx->Pixel.Separable2DEnabled);
-                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
-                                           src, convImage);
-               }
-            }
-         }
-#endif
-         /* do post-convolution transfer and pack into tempImage */
-         {
-            const GLint logComponents
-               = _mesa_components_in_format(logicalBaseFormat);
-            const GLfloat *src = convImage;
-            GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
-            for (row = 0; row < convHeight; row++) {
-               _mesa_pack_rgba_span_float(ctx, convWidth,
-                                          (GLfloat (*)[4]) src,
-                                          logicalBaseFormat, GL_FLOAT,
-                                          dst, &ctx->DefaultPacking,
-                                          postConvTransferOps);
-               src += convWidth * 4;
-               dst += convWidth * logComponents;
-            }
-         }
-      } /* loop over 3D image slices */
+      free(tempImage);
+      tempImage = newImage;
+   }
 
-      _mesa_free(convImage);
+   return tempImage;
+}
 
-      /* might need these below */
-      srcWidth = convWidth;
-      srcHeight = convHeight;
-   }
-   else {
-      /* no convolution */
-      const GLint components = _mesa_components_in_format(logicalBaseFormat);
-      const GLint srcStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
-      GLfloat *dst;
-      GLint img, row;
 
-      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
-                                           * components * sizeof(GLfloat));
-      if (!tempImage)
-         return NULL;
+/**
+ * Make temporary image with uint pixel values.  Used for unsigned
+ * integer-valued textures.
+ */
+static GLuint *
+make_temp_uint_image(struct gl_context *ctx, GLuint dims,
+                     GLenum logicalBaseFormat,
+                     GLenum textureBaseFormat,
+                     GLint srcWidth, GLint srcHeight, GLint srcDepth,
+                     GLenum srcFormat, GLenum srcType,
+                     const GLvoid *srcAddr,
+                     const struct gl_pixelstore_attrib *srcPacking)
+{
+   GLuint *tempImage;
+   const GLint components = _mesa_components_in_format(logicalBaseFormat);
+   const GLint srcStride =
+      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+   GLuint *dst;
+   GLint img, row;
 
-      dst = tempImage;
-      for (img = 0; img < srcDepth; img++) {
-         const GLubyte *src
-            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                                    srcWidth, srcHeight,
-                                                    srcFormat, srcType,
-                                                    img, 0, 0);
-         for (row = 0; row < srcHeight; row++) {
-            _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
-                                          dst, srcFormat, srcType, src,
-                                          srcPacking, transferOps);
-            dst += srcWidth * components;
-            src += srcStride;
-         }
+   ASSERT(dims >= 1 && dims <= 3);
+
+   ASSERT(logicalBaseFormat == GL_RGBA ||
+          logicalBaseFormat == GL_RGB ||
+          logicalBaseFormat == GL_RG ||
+          logicalBaseFormat == GL_RED ||
+          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
+          logicalBaseFormat == GL_LUMINANCE ||
+          logicalBaseFormat == GL_INTENSITY ||
+          logicalBaseFormat == GL_ALPHA);
+
+   ASSERT(textureBaseFormat == GL_RGBA ||
+          textureBaseFormat == GL_RGB ||
+          textureBaseFormat == GL_RG ||
+          textureBaseFormat == GL_RED ||
+          textureBaseFormat == GL_LUMINANCE_ALPHA ||
+          textureBaseFormat == GL_LUMINANCE ||
+          textureBaseFormat == GL_ALPHA);
+
+   tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+                                 * components * sizeof(GLuint));
+   if (!tempImage)
+      return NULL;
+
+   dst = tempImage;
+   for (img = 0; img < srcDepth; img++) {
+      const GLubyte *src
+        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                                srcWidth, srcHeight,
+                                                srcFormat, srcType,
+                                                img, 0, 0);
+      for (row = 0; row < srcHeight; row++) {
+        _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
+                                      dst, srcFormat, srcType, src,
+                                      srcPacking);
+        dst += srcWidth * components;
+        src += srcStride;
       }
    }
 
@@ -464,7 +484,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
       /* more work */
       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
-      GLfloat *newImage;
+      GLuint *newImage;
       GLint i, n;
       GLubyte map[6];
 
@@ -477,10 +497,10 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
-                                          * texComponents * sizeof(GLfloat));
+      newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+                                   * texComponents * sizeof(GLuint));
       if (!newImage) {
-         _mesa_free(tempImage);
+         free(tempImage);
          return NULL;
       }
 
@@ -500,7 +520,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
          }
       }
 
-      _mesa_free(tempImage);
+      free(tempImage);
       tempImage = newImage;
    }
 
@@ -508,12 +528,13 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
 }
 
 
+
 /**
  * Make a temporary (color) texture image with GLchan components.
  * Apply all needed pixel unpacking and pixel transfer operations.
  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
  * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures.  So, might
+ * but the graphics hardware doesn't support luminance textures.  So, we might
  * use an RGB hardware format instead.
  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
  *
@@ -532,7 +553,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims,
  * \return resulting image with format = textureBaseFormat and type = GLchan.
  */
 GLchan *
-_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
+_mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
                            GLenum logicalBaseFormat,
                            GLenum textureBaseFormat,
                            GLint srcWidth, GLint srcHeight, GLint srcDepth,
@@ -542,7 +563,6 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
 {
    GLuint transferOps = ctx->_ImageTransferState;
    const GLint components = _mesa_components_in_format(logicalBaseFormat);
-   GLboolean freeSrcImage = GL_FALSE;
    GLint img, row;
    GLchan *tempImage, *dst;
 
@@ -550,6 +570,8 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(logicalBaseFormat == GL_RGBA ||
           logicalBaseFormat == GL_RGB ||
+          logicalBaseFormat == GL_RG ||
+          logicalBaseFormat == GL_RED ||
           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
           logicalBaseFormat == GL_LUMINANCE ||
           logicalBaseFormat == GL_ALPHA ||
@@ -557,55 +579,29 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
 
    ASSERT(textureBaseFormat == GL_RGBA ||
           textureBaseFormat == GL_RGB ||
+          textureBaseFormat == GL_RG ||
+          textureBaseFormat == GL_RED ||
           textureBaseFormat == GL_LUMINANCE_ALPHA ||
           textureBaseFormat == GL_LUMINANCE ||
           textureBaseFormat == GL_ALPHA ||
           textureBaseFormat == GL_INTENSITY);
 
-#if FEATURE_convolve
-   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
-       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
-       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
-      /* get convolved image */
-      GLfloat *convImage = make_temp_float_image(ctx, dims,
-                                                 logicalBaseFormat,
-                                                 logicalBaseFormat,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType,
-                                                 srcAddr, srcPacking);
-      if (!convImage)
-         return NULL;
-      /* the convolved image is our new source image */
-      srcAddr = convImage;
-      srcFormat = logicalBaseFormat;
-      srcType = GL_FLOAT;
-      srcPacking = &ctx->DefaultPacking;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
-      transferOps = 0;
-      freeSrcImage = GL_TRUE;
-   }
-#endif
-
    /* unpack and transfer the source image */
-   tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+   tempImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
                                        * components * sizeof(GLchan));
    if (!tempImage) {
-      if (freeSrcImage) {
-         _mesa_free((void *) srcAddr);
-      }
       return NULL;
    }
 
    dst = tempImage;
    for (img = 0; img < srcDepth; img++) {
-      const GLint srcStride = _mesa_image_row_stride(srcPacking,
-                                                     srcWidth, srcFormat,
-                                                     srcType);
-      const GLubyte *src
-         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                                 srcWidth, srcHeight,
-                                                 srcFormat, srcType,
-                                                 img, 0, 0);
+      const GLint srcStride =
+         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+      const GLubyte *src =
+         (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                               srcWidth, srcHeight,
+                                               srcFormat, srcType,
+                                               img, 0, 0);
       for (row = 0; row < srcHeight; row++) {
          _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
                                       srcFormat, srcType, src, srcPacking,
@@ -615,11 +611,6 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
       }
    }
 
-   /* If we made a temporary image for convolution, free it here */
-   if (freeSrcImage) {
-      _mesa_free((void *) srcAddr);
-   }
-
    if (logicalBaseFormat != textureBaseFormat) {
       /* one more conversion step */
       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
@@ -637,10 +628,10 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+      newImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
                                          * texComponents * sizeof(GLchan));
       if (!newImage) {
-         _mesa_free(tempImage);
+         free(tempImage);
          return NULL;
       }
 
@@ -660,7 +651,7 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
          }
       }
 
-      _mesa_free(tempImage);
+      free(tempImage);
       tempImage = newImage;
    }
 
@@ -796,7 +787,10 @@ swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
 
-/* Deal with the _REV input types:
+
+/**
+ * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
+ * mapping array depending on endianness.
  */
 static const GLubyte *
 type_mapping( GLenum srcType )
@@ -814,7 +808,10 @@ type_mapping( GLenum srcType )
    }
 }
 
-/* Mapping required if input type is 
+
+/**
+ * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
+ * mapping array depending on pixelstore byte swapping state.
  */
 static const GLubyte *
 byteswap_mapping( GLboolean swapBytes,
@@ -841,7 +838,7 @@ byteswap_mapping( GLboolean swapBytes,
  * Transfer a GLubyte texture image with component swizzling.
  */
 static void
-_mesa_swizzle_ubyte_image(GLcontext *ctx, 
+_mesa_swizzle_ubyte_image(struct gl_context *ctx, 
                          GLuint dimensions,
                          GLenum srcFormat,
                          GLenum srcType,
@@ -890,7 +887,7 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx,
    for (i = 0; i < 4; i++)
       map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
 
-/*    _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
+/*    printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
 
    if (srcComponents == dstComponents &&
        srcRowStride == dstRowStride &&
@@ -928,9 +925,9 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx,
  * 1D, 2D and 3D images supported.
  */
 static void
-memcpy_texture(GLcontext *ctx,
+memcpy_texture(struct gl_context *ctx,
               GLuint dimensions,
-               const struct gl_texture_format *dstFormat,
+               gl_format dstFormat,
                GLvoid *dstAddr,
                GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
                GLint dstRowStride,
@@ -946,7 +943,8 @@ memcpy_texture(GLcontext *ctx,
                                       srcWidth, srcHeight, srcFormat, srcType);
    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
-   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLint bytesPerRow = srcWidth * texelBytes;
 
 #if 0
    /* XXX update/re-enable for dstImageOffsets array */
@@ -955,7 +953,7 @@ memcpy_texture(GLcontext *ctx,
    GLubyte *dstImage = (GLubyte *) dstAddr
                      + dstZoffset * dstImageStride
                      + dstYoffset * dstRowStride
-                     + dstXoffset * dstFormat->TexelBytes;
+                     + dstXoffset * texelBytes;
 
    if (dstRowStride == srcRowStride &&
        dstRowStride == bytesPerRow &&
@@ -986,9 +984,9 @@ memcpy_texture(GLcontext *ctx,
    for (img = 0; img < srcDepth; img++) {
       const GLubyte *srcRow = srcImage;
       GLubyte *dstRow = (GLubyte *) dstAddr
-         + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+         + dstImageOffsets[dstZoffset + img] * texelBytes
          + dstYoffset * dstRowStride
-         + dstXoffset * dstFormat->TexelBytes;
+         + dstXoffset * texelBytes;
       for (row = 0; row < srcHeight; row++) {
          ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
          dstRow += dstRowStride;
@@ -1001,38 +999,23 @@ memcpy_texture(GLcontext *ctx,
 
 
 /**
- * Store an image in any of the formats:
- *   _mesa_texformat_rgba
- *   _mesa_texformat_rgb
- *   _mesa_texformat_alpha
- *   _mesa_texformat_luminance
- *   _mesa_texformat_luminance_alpha
- *   _mesa_texformat_intensity
- * 
+ * Store a 32-bit integer depth component texture image.
  */
-GLboolean
-_mesa_texstore_rgba(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_z32(TEXSTORE_PARAMS)
 {
-   const GLint components = _mesa_components_in_format(baseInternalFormat);
-
-   ASSERT(dstFormat == &_mesa_texformat_rgba ||
-          dstFormat == &_mesa_texformat_rgb ||
-          dstFormat == &_mesa_texformat_alpha ||
-          dstFormat == &_mesa_texformat_luminance ||
-          dstFormat == &_mesa_texformat_luminance_alpha ||
-          dstFormat == &_mesa_texformat_intensity);
-   ASSERT(baseInternalFormat == GL_RGBA ||
-          baseInternalFormat == GL_RGB ||
-          baseInternalFormat == GL_ALPHA ||
-          baseInternalFormat == GL_LUMINANCE ||
-          baseInternalFormat == GL_LUMINANCE_ALPHA ||
-          baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
+   const GLuint depthScale = 0xffffffff;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   (void) dims;
+   ASSERT(dstFormat == MESA_FORMAT_Z32);
+   ASSERT(texelBytes == sizeof(GLuint));
 
-   if (!ctx->_ImageTransferState &&
+   if (ctx->Pixel.DepthScale == 1.0f &&
+       ctx->Pixel.DepthBias == 0.0f &&
        !srcPacking->SwapBytes &&
-       baseInternalFormat == srcFormat &&
-       srcType == CHAN_TYPE) {
+       baseInternalFormat == GL_DEPTH_COMPONENT &&
+       srcFormat == GL_DEPTH_COMPONENT &&
+       srcType == GL_UNSIGNED_INT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -1041,160 +1024,92 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
-   else if (!ctx->_ImageTransferState &&
-            !srcPacking->SwapBytes &&
-            dstFormat == &_mesa_texformat_rgb &&
-            srcFormat == GL_RGBA &&
-            srcType == CHAN_TYPE) {
-      /* extract RGB from RGBA */
-      GLint img, row, col;
+   else {
+      /* general path */
+      GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLchan *dstImage = (GLchan *)
-            ((GLubyte *) dstAddr
-             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
-             + dstYoffset * dstRowStride
-             + dstXoffset * dstFormat->TexelBytes);
-
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
-         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
-                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLchan *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            for (col = 0; col < srcWidth; col++) {
-               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
-               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
-               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
-            }
-            dstRow += dstRowStride / sizeof(GLchan);
-            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
+            const GLvoid *src = _mesa_image_address(dims, srcPacking,
+                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
+                                    depthScale, srcType, src, srcPacking);
+            dstRow += dstRowStride;
          }
       }
    }
-   else if (!ctx->_ImageTransferState &&
-           CHAN_TYPE == GL_UNSIGNED_BYTE &&
-           (srcType == GL_UNSIGNED_BYTE ||
-            srcType == GL_UNSIGNED_INT_8_8_8_8 ||
-            srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
-           can_swizzle(baseInternalFormat) &&
-           can_swizzle(srcFormat)) {
+   return GL_TRUE;
+}
 
-      const GLubyte *dstmap;
-      GLuint components;
 
-      /* dstmap - how to swizzle from RGBA to dst format:
-       */
-      if (dstFormat == &_mesa_texformat_rgba) {
-        dstmap = mappings[IDX_RGBA].from_rgba;
-        components = 4;
-      }
-      else if (dstFormat == &_mesa_texformat_rgb) {
-        dstmap = mappings[IDX_RGB].from_rgba;
-        components = 3;
-      }
-      else if (dstFormat == &_mesa_texformat_alpha) {
-        dstmap = mappings[IDX_ALPHA].from_rgba;
-        components = 1;
-      }
-      else if (dstFormat == &_mesa_texformat_luminance) {
-        dstmap = mappings[IDX_LUMINANCE].from_rgba;
-        components = 1;
-      }
-      else if (dstFormat == &_mesa_texformat_luminance_alpha) {
-        dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba;
-        components = 2;
-      }
-      else if (dstFormat == &_mesa_texformat_intensity) {
-        dstmap = mappings[IDX_INTENSITY].from_rgba;
-        components = 1;
-      }
-      else {
-         _mesa_problem(ctx, "Unexpected dstFormat in _mesa_texstore_rgba");
-         return GL_FALSE;
-      }
+/**
+ * Store a 24-bit integer depth component texture image.
+ */
+static GLboolean
+_mesa_texstore_x8_z24(TEXSTORE_PARAMS)
+{
+   const GLuint depthScale = 0xffffff;
+   const GLuint texelBytes = 4;
 
-      _mesa_swizzle_ubyte_image(ctx, dims,
-                               srcFormat,
-                               srcType,
-                               baseInternalFormat,
-                               dstmap, components,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
-                               srcWidth, srcHeight, srcDepth, srcAddr,
-                               srcPacking);      
-   }
-   else {
+   (void) dims;
+   ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
+
+   {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 dstFormat->BaseFormat,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLchan *src = tempImage;
-      GLint bytesPerRow;
       GLint img, row;
-      if (!tempImage)
-         return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
-      bytesPerRow = srcWidth * components * sizeof(GLchan);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            _mesa_memcpy(dstRow, src, bytesPerRow);
+            const GLvoid *src = _mesa_image_address(dims, srcPacking,
+                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
+                                    depthScale, srcType, src, srcPacking);
             dstRow += dstRowStride;
-            src += srcWidth * components;
          }
       }
-
-      _mesa_free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
 /**
- * Store a 32-bit integer depth component texture image.
+ * Store a 24-bit integer depth component texture image.
  */
-GLboolean
-_mesa_texstore_z32(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
 {
-   const GLuint depthScale = 0xffffffff;
+   const GLuint depthScale = 0xffffff;
+   const GLuint texelBytes = 4;
+
    (void) dims;
-   ASSERT(dstFormat == &_mesa_texformat_z32);
-   ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
+   ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
 
-   if (ctx->Pixel.DepthScale == 1.0f &&
-       ctx->Pixel.DepthBias == 0.0f &&
-       !srcPacking->SwapBytes &&
-       baseInternalFormat == GL_DEPTH_COMPONENT &&
-       srcFormat == GL_DEPTH_COMPONENT &&
-       srcType == GL_UNSIGNED_INT) {
-      /* simple memcpy path */
-      memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
-                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
-                     srcAddr, srcPacking);
-   }
-   else {
+   {
       /* general path */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            GLuint *dst = (GLuint *) dstRow;
+            GLint i;
             _mesa_unpack_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
+                                    GL_UNSIGNED_INT, dst,
                                     depthScale, srcType, src, srcPacking);
+            for (i = 0; i < srcWidth; i++)
+               dst[i] <<= 8;
             dstRow += dstRowStride;
          }
       }
@@ -1202,18 +1117,18 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
-#define STRIDE_3D 0
 
 /**
  * Store a 16-bit integer depth component texture image.
  */
-GLboolean
+static GLboolean
 _mesa_texstore_z16(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffff;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
    (void) dims;
-   ASSERT(dstFormat == &_mesa_texformat_z16);
-   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
+   ASSERT(dstFormat == MESA_FORMAT_Z16);
+   ASSERT(texelBytes == sizeof(GLushort));
 
    if (ctx->Pixel.DepthScale == 1.0f &&
        ctx->Pixel.DepthBias == 0.0f &&
@@ -1234,9 +1149,9 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -1255,16 +1170,19 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
 /**
  * Store an rgb565 or rgb565_rev texture image.
  */
-GLboolean
+static GLboolean
 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
-          dstFormat == &_mesa_texformat_rgb565_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
+          dstFormat == MESA_FORMAT_RGB565_REV);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_rgb565 &&
+       dstFormat == MESA_FORMAT_RGB565 &&
        baseInternalFormat == GL_RGB &&
        srcFormat == GL_RGB &&
        srcType == GL_UNSIGNED_SHORT_5_6_5) {
@@ -1283,20 +1201,20 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
             srcType == GL_UNSIGNED_BYTE &&
             dims == 2) {
       /* do optimized tex store */
-      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
-                                                        srcFormat, srcType);
+      const GLint srcRowStride =
+         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
       const GLubyte *src = (const GLubyte *)
          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
                              srcFormat, srcType, 0, 0, 0);
       GLubyte *dst = (GLubyte *) dstAddr
                    + dstYoffset * dstRowStride
-                   + dstXoffset * dstFormat->TexelBytes;
+                   + dstXoffset * texelBytes;
       GLint row, col;
       for (row = 0; row < srcHeight; row++) {
          const GLubyte *srcUB = (const GLubyte *) src;
          GLushort *dstUS = (GLushort *) dst;
          /* check for byteswapped format */
-         if (dstFormat == &_mesa_texformat_rgb565) {
+         if (dstFormat == MESA_FORMAT_RGB565) {
             for (col = 0; col < srcWidth; col++) {
                dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
                srcUB += 3;
@@ -1316,7 +1234,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1324,16 +1242,15 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             /* check for byteswapped format */
-            if (dstFormat == &_mesa_texformat_rgb565) {
+            if (dstFormat == MESA_FORMAT_RGB565) {
                for (col = 0; col < srcWidth; col++) {
                   dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
                                                CHAN_TO_UBYTE(src[GCOMP]),
@@ -1352,7 +1269,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
@@ -1361,18 +1278,20 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
 /**
  * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
  */
-GLboolean
+static GLboolean
 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
-          dstFormat == &_mesa_texformat_rgba8888_rev);
-   ASSERT(dstFormat->TexelBytes == 4);
+   ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
+          dstFormat == MESA_FORMAT_RGBA8888_REV);
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_rgba8888 &&
+       dstFormat == MESA_FORMAT_RGBA8888 &&
        baseInternalFormat == GL_RGBA &&
       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
@@ -1388,7 +1307,7 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
    }
    else if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_rgba8888_rev &&
+       dstFormat == MESA_FORMAT_RGBA8888_REV &&
        baseInternalFormat == GL_RGBA &&
       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
@@ -1413,8 +1332,8 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == &_mesa_texformat_rgba8888) ||
-         (!littleEndian && dstFormat == &_mesa_texformat_rgba8888_rev)) {
+      if ((littleEndian && dstFormat == MESA_FORMAT_RGBA8888) ||
+         (!littleEndian && dstFormat == MESA_FORMAT_RGBA8888_REV)) {
         dstmap[3] = 0;
         dstmap[2] = 1;
         dstmap[1] = 2;
@@ -1441,7 +1360,7 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1449,15 +1368,14 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            if (dstFormat == &_mesa_texformat_rgba8888) {
+            if (dstFormat == MESA_FORMAT_RGBA8888) {
                for (col = 0; col < srcWidth; col++) {
                   dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
                                                 CHAN_TO_UBYTE(src[GCOMP]),
@@ -1478,24 +1396,29 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = GL_RGBA;
 
-   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
-          dstFormat == &_mesa_texformat_argb8888_rev);
-   ASSERT(dstFormat->TexelBytes == 4);
+   ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
+          dstFormat == MESA_FORMAT_ARGB8888_REV ||
+          dstFormat == MESA_FORMAT_XRGB8888 ||
+          dstFormat == MESA_FORMAT_XRGB8888_REV );
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_argb8888 &&
+       (dstFormat == MESA_FORMAT_ARGB8888 ||
+        dstFormat == MESA_FORMAT_XRGB8888) &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
@@ -1510,7 +1433,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
    }
    else if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_argb8888_rev &&
+       (dstFormat == MESA_FORMAT_ARGB8888_REV ||
+        dstFormat == MESA_FORMAT_XRGB8888_REV) &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
@@ -1525,21 +1449,22 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
    }
    else if (!ctx->_ImageTransferState &&
             !srcPacking->SwapBytes &&
-           dstFormat == &_mesa_texformat_argb8888 &&
+           (dstFormat == MESA_FORMAT_ARGB8888 ||
+             dstFormat == MESA_FORMAT_XRGB8888) &&
             srcFormat == GL_RGB &&
            (baseInternalFormat == GL_RGBA ||
             baseInternalFormat == GL_RGB) &&
             srcType == GL_UNSIGNED_BYTE) {
       int img, row, col;
       for (img = 0; img < srcDepth; img++) {
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
+         const GLint srcRowStride =
+            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *d4 = (GLuint *) dstRow;
             for (col = 0; col < srcWidth; col++) {
@@ -1555,7 +1480,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
    }
    else if (!ctx->_ImageTransferState &&
             !srcPacking->SwapBytes &&
-           dstFormat == &_mesa_texformat_argb8888 &&
+           dstFormat == MESA_FORMAT_ARGB8888 &&
             srcFormat == GL_RGBA &&
            baseInternalFormat == GL_RGBA &&
             srcType == GL_UNSIGNED_BYTE) {
@@ -1568,14 +1493,14 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
        * Strangely the same isn't required for the RGB path, above.
        */
       for (img = 0; img < srcDepth; img++) {
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
+         const GLint srcRowStride =
+            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *d4 = (GLuint *) dstRow;
             for (col = 0; col < srcWidth; col++) {
@@ -1600,16 +1525,20 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == &_mesa_texformat_argb8888) ||
-         (!littleEndian && dstFormat == &_mesa_texformat_argb8888_rev)) {
+      if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
+          (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
+         (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
+         (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
         dstmap[3] = 3;         /* alpha */
         dstmap[2] = 0;         /* red */
         dstmap[1] = 1;         /* green */
         dstmap[0] = 2;         /* blue */
       }
       else {
-        assert((littleEndian && dstFormat == &_mesa_texformat_argb8888_rev) ||
-               (!littleEndian && dstFormat == &_mesa_texformat_argb8888));
+        assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
+               (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
+               (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
+               (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
         dstmap[3] = 2;
         dstmap[2] = 1;
         dstmap[1] = 0;
@@ -1619,7 +1548,6 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       _mesa_swizzle_ubyte_image(ctx, dims,
                                srcFormat,
                                srcType,
-
                                baseInternalFormat,
                                dstmap, 4,
                                dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -1632,7 +1560,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1640,15 +1568,14 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            if (dstFormat == &_mesa_texformat_argb8888) {
+            if (dstFormat == MESA_FORMAT_ARGB8888) {
                for (col = 0; col < srcWidth; col++) {
                   dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
                                                 CHAN_TO_UBYTE(src[RCOMP]),
@@ -1657,6 +1584,15 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
                   src += 4;
                }
             }
+            else if (dstFormat == MESA_FORMAT_XRGB8888) {
+               for (col = 0; col < srcWidth; col++) {
+                  dstUI[col] = PACK_COLOR_8888( 0xff,
+                                                CHAN_TO_UBYTE(src[RCOMP]),
+                                                CHAN_TO_UBYTE(src[GCOMP]),
+                                                CHAN_TO_UBYTE(src[BCOMP]) );
+                  src += 4;
+               }
+            }
             else {
                for (col = 0; col < srcWidth; col++) {
                   dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
@@ -1669,19 +1605,21 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_rgb888);
-   ASSERT(dstFormat->TexelBytes == 3);
+   ASSERT(dstFormat == MESA_FORMAT_RGB888);
+   ASSERT(texelBytes == 3);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1704,14 +1642,14 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
       /* extract RGB from RGBA */
       GLint img, row, col;
       for (img = 0; img < srcDepth; img++) {
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
+         const GLint srcRowStride =
+            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
@@ -1751,7 +1689,7 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1759,12 +1697,11 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
 #if 0
             if (littleEndian) {
@@ -1794,19 +1731,21 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_bgr888);
-   ASSERT(dstFormat->TexelBytes == 3);
+   ASSERT(dstFormat == MESA_FORMAT_BGR888);
+   ASSERT(texelBytes == 3);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1829,14 +1768,14 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
       /* extract BGR from RGBA */
       int img, row, col;
       for (img = 0; img < srcDepth; img++) {
-         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
+         const GLint srcRowStride =
+            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
@@ -1876,7 +1815,7 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1884,12 +1823,11 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
@@ -1900,76 +1838,25 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
-GLboolean
-_mesa_texstore_rgba4444(TEXSTORE_PARAMS)
-{
-   ASSERT(dstFormat == &_mesa_texformat_rgba4444);
-   ASSERT(dstFormat->TexelBytes == 2);
-
-   if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_rgba4444 &&
-       baseInternalFormat == GL_RGBA &&
-       srcFormat == GL_RGBA &&
-       srcType == GL_UNSIGNED_SHORT_4_4_4_4){
-      /* simple memcpy path */
-      memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
-                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
-                     srcAddr, srcPacking);
-   }
-   else {
-      /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 dstFormat->BaseFormat,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLchan *src = tempImage;
-      GLint img, row, col;
-      if (!tempImage)
-         return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
-      for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
-            + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
-         for (row = 0; row < srcHeight; row++) {
-            GLushort *dstUS = (GLushort *) dstRow;
-           for (col = 0; col < srcWidth; col++) {
-             dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
-                                           CHAN_TO_UBYTE(src[GCOMP]),
-                                           CHAN_TO_UBYTE(src[BCOMP]),
-                                           CHAN_TO_UBYTE(src[ACOMP]) );
-             src += 4;
-            }
-            dstRow += dstRowStride;
-         }
-      }
-      _mesa_free((void *) tempImage);
-   }
-   return GL_TRUE;
-}
 
-GLboolean
+static GLboolean
 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
-          dstFormat == &_mesa_texformat_argb4444_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
+          dstFormat == MESA_FORMAT_ARGB4444_REV);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_argb4444 &&
+       dstFormat == MESA_FORMAT_ARGB4444 &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
@@ -1985,7 +1872,7 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1993,15 +1880,14 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
-            if (dstFormat == &_mesa_texformat_argb4444) {
+            if (dstFormat == MESA_FORMAT_ARGB4444) {
                for (col = 0; col < srcWidth; col++) {
                   dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
                                                 CHAN_TO_UBYTE(src[RCOMP]),
@@ -2022,20 +1908,23 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
-GLboolean
+static GLboolean
 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_rgba5551);
-   ASSERT(dstFormat->TexelBytes == 2);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_rgba5551 &&
+       dstFormat == MESA_FORMAT_RGBA5551 &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_RGBA &&
        srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
@@ -2051,7 +1940,7 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2059,12 +1948,11 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
            for (col = 0; col < srcWidth; col++) {
@@ -2077,21 +1965,24 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
-GLboolean
+static GLboolean
 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
-          dstFormat == &_mesa_texformat_argb1555_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
+          dstFormat == MESA_FORMAT_ARGB1555_REV);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_argb1555 &&
+       dstFormat == MESA_FORMAT_ARGB1555 &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
@@ -2107,7 +1998,7 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2115,15 +2006,14 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
-            if (dstFormat == &_mesa_texformat_argb1555) {
+            if (dstFormat == MESA_FORMAT_ARGB1555) {
                for (col = 0; col < srcWidth; col++) {
                   dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
                                                 CHAN_TO_UBYTE(src[RCOMP]),
@@ -2144,26 +2034,158 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-GLboolean
-_mesa_texstore_al88(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_argb2101010(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
+   ASSERT(texelBytes == 4);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_ARGB2101010 &&
+       srcFormat == GL_BGRA &&
+       srcType == GL_UNSIGNED_INT_2_10_10_10_REV &&
+       baseInternalFormat == GL_RGBA) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         if (baseInternalFormat == GL_RGBA) {
+            for (row = 0; row < srcHeight; row++) {
+               GLuint *dstUI = (GLuint *) dstRow;
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort a,r,g,b;
+
+                  UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
+                  UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
+                  UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
+                  UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
+                  dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
+                  src += 4;
+               }
+               dstRow += dstRowStride;
+            }
+         } else if (baseInternalFormat == GL_RGB) {
+            for (row = 0; row < srcHeight; row++) {
+               GLuint *dstUI = (GLuint *) dstRow;
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort r,g,b;
+
+                  UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
+                  UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
+                  UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
+                  dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
+                  src += 4;
+               }
+               dstRow += dstRowStride;
+            }
+         } else {
+            ASSERT(0);
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
+ */
+static GLboolean
+_mesa_texstore_unorm44(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_AL44);
+   ASSERT(texelBytes == 1);
+
+   {
+      /* general path */
+      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLchan *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLubyte *dstUS = (GLubyte *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               /* src[0] is luminance, src[1] is alpha */
+               dstUS[col] = PACK_COLOR_44( CHAN_TO_UBYTE(src[1]),
+                                           CHAN_TO_UBYTE(src[0]) );
+               src += 2;
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
+ */
+static GLboolean
+_mesa_texstore_unorm88(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_al88 ||
-          dstFormat == &_mesa_texformat_al88_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(dstFormat == MESA_FORMAT_AL88 ||
+          dstFormat == MESA_FORMAT_AL88_REV ||
+          dstFormat == MESA_FORMAT_RG88 ||
+          dstFormat == MESA_FORMAT_RG88_REV);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_al88 &&
-       baseInternalFormat == GL_LUMINANCE_ALPHA &&
-       srcFormat == GL_LUMINANCE_ALPHA &&
+       (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_RG88) &&
+       baseInternalFormat == srcFormat &&
        srcType == GL_UNSIGNED_BYTE &&
        littleEndian) {
       /* simple memcpy path */
@@ -2179,19 +2201,31 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
            srcType == GL_UNSIGNED_BYTE &&
            can_swizzle(baseInternalFormat) &&
            can_swizzle(srcFormat)) {
-
       GLubyte dstmap[4];
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == &_mesa_texformat_al88) ||
-         (!littleEndian && dstFormat == &_mesa_texformat_al88_rev)) {
-        dstmap[0] = 0;
-        dstmap[1] = 3;
+      if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
+        if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
+            (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
+           dstmap[0] = 0;
+           dstmap[1] = 3;
+        }
+        else {
+           dstmap[0] = 3;
+           dstmap[1] = 0;
+        }
       }
       else {
-        dstmap[0] = 3;
-        dstmap[1] = 0;
+        if ((littleEndian && dstFormat == MESA_FORMAT_RG88) ||
+            (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
+           dstmap[0] = 0;
+           dstmap[1] = 1;
+        }
+        else {
+           dstmap[0] = 1;
+           dstmap[1] = 0;
+        }
       }
       dstmap[2] = ZERO;                /* ? */
       dstmap[3] = ONE;         /* ? */
@@ -2210,7 +2244,7 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2218,15 +2252,15 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
-            if (dstFormat == &_mesa_texformat_al88) {
+            if (dstFormat == MESA_FORMAT_AL88 ||
+               dstFormat == MESA_FORMAT_RG88) {
                for (col = 0; col < srcWidth; col++) {
                   /* src[0] is luminance, src[1] is alpha */
                  dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
@@ -2245,22 +2279,34 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-GLboolean
-_mesa_texstore_rgb332(TEXSTORE_PARAMS)
+/**
+ * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
+ */
+static GLboolean
+_mesa_texstore_unorm1616(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_rgb332);
-   ASSERT(dstFormat->TexelBytes == 1);
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
+          dstFormat == MESA_FORMAT_AL1616_REV ||
+         dstFormat == MESA_FORMAT_RG1616 ||
+          dstFormat == MESA_FORMAT_RG1616_REV);
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       baseInternalFormat == GL_RGB &&
-       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
+       (dstFormat == MESA_FORMAT_AL1616 || dstFormat == MESA_FORMAT_RG1616) &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_SHORT &&
+       littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -2271,53 +2317,73 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLchan *src = tempImage;
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            for (col = 0; col < srcWidth; col++) {
-               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
-                                             CHAN_TO_UBYTE(src[GCOMP]),
-                                             CHAN_TO_UBYTE(src[BCOMP]) );
-               src += 3;
+            GLuint *dstUI = (GLuint *) dstRow;
+            if (dstFormat == MESA_FORMAT_AL1616 ||
+               dstFormat == MESA_FORMAT_RG1616) {
+               for (col = 0; col < srcWidth; col++) {
+                 GLushort l, a;
+
+                 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
+                 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
+                 dstUI[col] = PACK_COLOR_1616(a, l);
+                 src += 2;
+               }
+            }
+            else {
+               for (col = 0; col < srcWidth; col++) {
+                 GLushort l, a;
+
+                 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
+                 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
+                 dstUI[col] = PACK_COLOR_1616_REV(a, l);
+                 src += 2;
+               }
             }
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-/**
- * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
- */
-GLboolean
-_mesa_texstore_a8(TEXSTORE_PARAMS)
+/* Texstore for R16, A16, L16, I16. */
+static GLboolean
+_mesa_texstore_unorm16(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == &_mesa_texformat_a8 ||
-          dstFormat == &_mesa_texformat_l8 ||
-          dstFormat == &_mesa_texformat_i8);
-   ASSERT(dstFormat->TexelBytes == 1);
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_R16 ||
+          dstFormat == MESA_FORMAT_A16 ||
+          dstFormat == MESA_FORMAT_L16 ||
+          dstFormat == MESA_FORMAT_I16);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
        baseInternalFormat == srcFormat &&
-       srcType == GL_UNSIGNED_BYTE) {
+       srcType == GL_UNSIGNED_SHORT &&
+       littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -2326,80 +2392,56 @@ _mesa_texstore_a8(TEXSTORE_PARAMS)
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
-   else if (!ctx->_ImageTransferState &&
-           srcType == GL_UNSIGNED_BYTE &&
-           can_swizzle(baseInternalFormat) &&
-           can_swizzle(srcFormat)) {
-
-      GLubyte dstmap[4];
-
-      /* dstmap - how to swizzle from RGBA to dst format:
-       */
-      if (dstFormat == &_mesa_texformat_a8) {
-        dstmap[0] = 3;
-      }
-      else {
-        dstmap[0] = 0;
-      }
-      dstmap[1] = ZERO;                /* ? */
-      dstmap[2] = ZERO;                /* ? */
-      dstmap[3] = ONE;         /* ? */
-      
-      _mesa_swizzle_ubyte_image(ctx, dims,
-                               srcFormat,
-                               srcType,
-                               baseInternalFormat,
-                               dstmap, 1,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
-                               srcWidth, srcHeight, srcDepth, srcAddr,
-                               srcPacking);      
-   }   
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLchan *src = tempImage;
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            for (col = 0; col < srcWidth; col++) {
-               dstRow[col] = CHAN_TO_UBYTE(src[col]);
-            }
+            GLushort *dstUS = (GLushort *) dstRow;
+           for (col = 0; col < srcWidth; col++) {
+              GLushort r;
+
+              UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
+              dstUS[col] = r;
+              src += 1;
+           }
             dstRow += dstRowStride;
-            src += srcWidth;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-
-GLboolean
-_mesa_texstore_ci8(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_rgba_16(TEXSTORE_PARAMS)
 {
-   (void) dims; (void) baseInternalFormat;
-   ASSERT(dstFormat == &_mesa_texformat_ci8);
-   ASSERT(dstFormat->TexelBytes == 1);
-   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
+   ASSERT(texelBytes == 8);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       srcFormat == GL_COLOR_INDEX &&
-       srcType == GL_UNSIGNED_BYTE) {
+       baseInternalFormat == GL_RGBA &&
+       srcFormat == GL_RGBA &&
+       srcType == GL_UNSIGNED_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -2410,38 +2452,314 @@ _mesa_texstore_ci8(TEXSTORE_PARAMS)
    }
    else {
       /* general path */
-      GLint img, row;
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            const GLvoid *src = _mesa_image_address(dims, srcPacking,
-                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
-            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
-                                    srcType, src, srcPacking,
-                                    ctx->_ImageTransferState);
+            GLushort *dstUS = (GLushort *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               GLushort r, g, b, a;
+
+               UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
+               UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
+               UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
+               UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
+               dstUS[col*4+0] = r;
+               dstUS[col*4+1] = g;
+               dstUS[col*4+2] = b;
+               dstUS[col*4+3] = a;
+               src += 4;
+            }
             dstRow += dstRowStride;
          }
       }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+static GLboolean
+_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_R_16 ||
+          dstFormat == MESA_FORMAT_SIGNED_RG_16 ||
+          dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
+          dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == GL_RGBA &&
+       dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
+       srcFormat == GL_RGBA &&
+       srcType == GL_SHORT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
+      const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
+      GLint img, row, col;
+
+      if (!tempImage)
+         return GL_FALSE;
+
+      /* Note: tempImage is always float[4] / RGBA.  We convert to 1, 2,
+       * 3 or 4 components/pixel here.
+       */
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLshort *dstRowS = (GLshort *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               GLuint c;
+               for (c = 0; c < comps; c++) {
+                  GLshort p;
+                  UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
+                  dstRowS[col * comps + c] = p;
+               }
+            }
+            dstRow += dstRowStride;
+            src += 4 * srcWidth;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+static GLboolean
+_mesa_texstore_rgb332(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGB332);
+   ASSERT(texelBytes == 1);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == GL_RGB &&
+       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLchan *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            for (col = 0; col < srcWidth; col++) {
+               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
+                                             CHAN_TO_UBYTE(src[GCOMP]),
+                                             CHAN_TO_UBYTE(src[BCOMP]) );
+               src += 3;
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
 /**
- * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
+ * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
  */
-GLboolean
+static GLboolean
+_mesa_texstore_a8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_A8 ||
+          dstFormat == MESA_FORMAT_L8 ||
+          dstFormat == MESA_FORMAT_I8 ||
+          dstFormat == MESA_FORMAT_R8);
+   ASSERT(texelBytes == 1);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (!ctx->_ImageTransferState &&
+           srcType == GL_UNSIGNED_BYTE &&
+           can_swizzle(baseInternalFormat) &&
+           can_swizzle(srcFormat)) {
+      GLubyte dstmap[4];
+
+      /* dstmap - how to swizzle from RGBA to dst format:
+       */
+      if (dstFormat == MESA_FORMAT_A8) {
+        dstmap[0] = 3;
+      }
+      else {
+        dstmap[0] = 0;
+      }
+      dstmap[1] = ZERO;                /* ? */
+      dstmap[2] = ZERO;                /* ? */
+      dstmap[3] = ONE;         /* ? */
+      
+      _mesa_swizzle_ubyte_image(ctx, dims,
+                               srcFormat,
+                               srcType,
+                               baseInternalFormat,
+                               dstmap, 1,
+                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstImageOffsets,
+                               srcWidth, srcHeight, srcDepth, srcAddr,
+                               srcPacking);      
+   }   
+   else {
+      /* general path */
+      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLchan *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            for (col = 0; col < srcWidth; col++) {
+               dstRow[col] = CHAN_TO_UBYTE(src[col]);
+            }
+            dstRow += dstRowStride;
+            src += srcWidth;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+
+static GLboolean
+_mesa_texstore_ci8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+
+   (void) dims; (void) baseInternalFormat;
+   ASSERT(dstFormat == MESA_FORMAT_CI8);
+   ASSERT(texelBytes == 1);
+   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       srcFormat == GL_COLOR_INDEX &&
+       srcType == GL_UNSIGNED_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      GLint img, row;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            const GLvoid *src = _mesa_image_address(dims, srcPacking,
+                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
+                                    srcType, src, srcPacking,
+                                    ctx->_ImageTransferState);
+            dstRow += dstRowStride;
+         }
+      }
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
+ */
+static GLboolean
 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+
    (void) ctx; (void) dims; (void) baseInternalFormat;
 
-   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
-          (dstFormat == &_mesa_texformat_ycbcr_rev));
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
+          (dstFormat == MESA_FORMAT_YCBCR_REV));
+   ASSERT(texelBytes == 2);
    ASSERT(ctx->Extensions.MESA_ycbcr_texture);
    ASSERT(srcFormat == GL_YCBCR_MESA);
    ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
@@ -2460,14 +2778,14 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
    /* XXX the logic here _might_ be wrong */
    if (srcPacking->SwapBytes ^
        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
-       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
+       (dstFormat == MESA_FORMAT_YCBCR_REV) ^
        !littleEndian) {
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             _mesa_swap2((GLushort *) dstRow, srcWidth);
             dstRow += dstRowStride;
@@ -2477,13 +2795,14 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
-GLboolean
+static GLboolean
 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_dudv8);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(dstFormat == MESA_FORMAT_DUDV8);
+   ASSERT(texelBytes == 2);
    ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
    ASSERT((srcFormat == GL_DU8DV8_ATI) ||
          (srcFormat == GL_DUDV_ATI));
@@ -2500,7 +2819,6 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else if (srcType == GL_BYTE) {
-
       GLubyte dstmap[4];
 
       /* dstmap - how to swizzle from RGBA to dst format:
@@ -2529,12 +2847,12 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
    else {
       /* general path - note this is defined for 2d textures only */
       const GLint components = _mesa_components_in_format(baseInternalFormat);
-      const GLint srcStride = _mesa_image_row_stride(srcPacking,
-                                                 srcWidth, srcFormat, srcType);
+      const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
+                                                     srcFormat, srcType);
       GLbyte *tempImage, *dst, *src;
       GLint row;
 
-      tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+      tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
                                           * components * sizeof(GLbyte));
       if (!tempImage)
          return GL_FALSE;
@@ -2556,53 +2874,197 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
       src = tempImage;
       dst = (GLbyte *) dstAddr
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
       for (row = 0; row < srcHeight; row++) {
-         memcpy(dst, src, srcWidth * dstFormat->TexelBytes);
+         memcpy(dst, src, srcWidth * texelBytes);
          dst += dstRowStride;
-         src += srcWidth * dstFormat->TexelBytes;
+         src += srcWidth * texelBytes;
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
+
 /**
- * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
+ * Store a texture in MESA_FORMAT_SIGNED_R8 format.
  */
-GLboolean
-_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_signed_r8(TEXSTORE_PARAMS)
 {
-   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_signed_rgba8888 ||
-          dstFormat == &_mesa_texformat_signed_rgba8888_rev);
-   ASSERT(dstFormat->TexelBytes == 4);
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_R8);
+   ASSERT(texelBytes == 1);
 
-   if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_signed_rgba8888 &&
-       baseInternalFormat == GL_RGBA &&
-      ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
-       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
-       /* simple memcpy path */
-      memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
-                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
-                     srcAddr, srcPacking);
+   /* XXX look at adding optimized paths */
+   {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *srcRow = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLubyte *dstB = (GLubyte *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               dstB[col] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
    }
-   else if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
-       dstFormat == &_mesa_texformat_signed_rgba8888_rev &&
-       baseInternalFormat == GL_RGBA &&
-      ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
-       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
-      /* simple memcpy path */
-      memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
+   return GL_TRUE;
+}
+
+
+/**
+ * Store a texture in MESA_FORMAT_SIGNED_RG88 format.
+ */
+static GLboolean
+_mesa_texstore_signed_rg88(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG88);
+   ASSERT(texelBytes == 1);
+
+   /* XXX look at adding optimized paths */
+   {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *srcRow = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLushort *dstUS = (GLushort *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               dstUS[col] = PACK_COLOR_88(FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
+                                          FLOAT_TO_BYTE_TEX(srcRow[GCOMP]));
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
+ */
+static GLboolean
+_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
+   ASSERT(texelBytes == 4);
+
+   {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *srcRow = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
+                                             FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
+                                             FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
+                                             0xff );
+               srcRow += 4;
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+
+/**
+ * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
+ * MESA_FORMAT_SIGNED_RGBA8888_REV
+ */
+static GLboolean
+_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
+{
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
+          dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
+   ASSERT(texelBytes == 4);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_SIGNED_RGBA8888 &&
+       baseInternalFormat == GL_RGBA &&
+      ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
+       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
+       /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV &&
+       baseInternalFormat == GL_RGBA &&
+      ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
+       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
                      dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
@@ -2616,8 +3078,8 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888) ||
-         (!littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888_rev)) {
+      if ((littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888) ||
+         (!littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV)) {
         dstmap[3] = 0;
         dstmap[2] = 1;
         dstmap[1] = 2;
@@ -2644,23 +3106,23 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
       /* general path */
       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
-                                                 srcPacking);
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
       const GLfloat *srcRow = tempImage;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            if (dstFormat == &_mesa_texformat_signed_rgba8888) {
+            if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
                for (col = 0; col < srcWidth; col++) {
                   dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
                                                 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
@@ -2681,31 +3143,43 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
             dstRow += dstRowStride;
          }
       }
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
+
 /**
  * Store a combined depth/stencil texture image.
  */
-GLboolean
+static GLboolean
 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
-   const GLfloat depthScale = (GLfloat) 0xffffff;
+   const GLuint depthScale = 0xffffff;
    const GLint srcRowStride
       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
       / sizeof(GLuint);
    GLint img, row;
 
-   ASSERT(dstFormat == &_mesa_texformat_z24_s8);
+   ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
 
-   /* In case we only upload depth we need to preserve the stencil */
-   if (srcFormat == GL_DEPTH_COMPONENT) {
+   if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f &&
+       ctx->Pixel.DepthBias == 0.0f &&
+       !srcPacking->SwapBytes) {
+      /* simple path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (srcFormat == GL_DEPTH_COMPONENT) {
+      /* In case we only upload depth we need to preserve the stencil */
       for (img = 0; img < srcDepth; img++) {
-         GLuint *dstRow = (GLuint *) dstAddr
+        GLuint *dstRow = (GLuint *) dstAddr
             + dstImageOffsets[dstZoffset + img]
             + dstYoffset * dstRowStride / sizeof(GLuint)
             + dstXoffset;
@@ -2716,25 +3190,137 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
                   img, 0, 0);
          for (row = 0; row < srcHeight; row++) {
             GLuint depth[MAX_WIDTH];
+           GLubyte stencil[MAX_WIDTH];
             GLint i;
-            _mesa_unpack_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT, /* dst type */
-                                    depth, /* dst addr */
-                                    depthScale,
-                                    srcType, src, srcPacking);
+           GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
 
-            for (i = 0; i < srcWidth; i++)
-               dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
+           if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+              keepstencil = GL_TRUE;
+           }
+            else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
+              keepdepth = GL_TRUE;
+           }
+
+           if (keepdepth == GL_FALSE)
+              /* the 24 depth bits will be in the low position: */
+              _mesa_unpack_depth_span(ctx, srcWidth,
+                                      GL_UNSIGNED_INT, /* dst type */
+                                      keepstencil ? depth : dstRow, /* dst addr */
+                                      depthScale,
+                                      srcType, src, srcPacking);
+
+           if (keepstencil == GL_FALSE)
+              /* get the 8-bit stencil values */
+              _mesa_unpack_stencil_span(ctx, srcWidth,
+                                        GL_UNSIGNED_BYTE, /* dst type */
+                                        stencil, /* dst addr */
+                                        srcType, src, srcPacking,
+                                        ctx->_ImageTransferState);
+
+           for (i = 0; i < srcWidth; i++) {
+              if (keepstencil)
+                 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
+              else
+                 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
+           }
 
             src += srcRowStride;
             dstRow += dstRowStride / sizeof(GLuint);
          }
       }
    }
-   else if (ctx->Pixel.DepthScale == 1.0f &&
-       ctx->Pixel.DepthBias == 0.0f &&
-       !srcPacking->SwapBytes) {
-      /* simple path */
+   return GL_TRUE;
+}
+
+
+/**
+ * Store a combined depth/stencil texture image.
+ */
+static GLboolean
+_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
+{
+   const GLuint depthScale = 0xffffff;
+   const GLint srcRowStride
+      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+      / sizeof(GLuint);
+   GLint img, row;
+
+   ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
+   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+          srcFormat == GL_DEPTH_COMPONENT ||
+          srcFormat == GL_STENCIL_INDEX);
+   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
+          srcType == GL_UNSIGNED_INT_24_8_EXT);
+
+   for (img = 0; img < srcDepth; img++) {
+      GLuint *dstRow = (GLuint *) dstAddr
+        + dstImageOffsets[dstZoffset + img]
+        + dstYoffset * dstRowStride / sizeof(GLuint)
+        + dstXoffset;
+      const GLuint *src
+        = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                               srcWidth, srcHeight,
+                                               srcFormat, srcType,
+                                               img, 0, 0);
+      for (row = 0; row < srcHeight; row++) {
+        GLuint depth[MAX_WIDTH];
+        GLubyte stencil[MAX_WIDTH];
+        GLint i;
+        GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
+        
+        if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+           keepstencil = GL_TRUE;
+        }
+         else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
+           keepdepth = GL_TRUE;
+        }
+
+        if (keepdepth == GL_FALSE)
+           /* the 24 depth bits will be in the low position: */
+           _mesa_unpack_depth_span(ctx, srcWidth,
+                                   GL_UNSIGNED_INT, /* dst type */
+                                   keepstencil ? depth : dstRow, /* dst addr */
+                                   depthScale,
+                                   srcType, src, srcPacking);   
+
+        if (keepstencil == GL_FALSE)
+           /* get the 8-bit stencil values */
+           _mesa_unpack_stencil_span(ctx, srcWidth,
+                                     GL_UNSIGNED_BYTE, /* dst type */
+                                     stencil, /* dst addr */
+                                     srcType, src, srcPacking,
+                                     ctx->_ImageTransferState);
+
+        /* merge stencil values into depth values */
+        for (i = 0; i < srcWidth; i++) {
+           if (keepstencil)
+              dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
+           else
+              dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
+
+        }
+        src += srcRowStride;
+        dstRow += dstRowStride / sizeof(GLuint);
+      }
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Store simple 8-bit/value stencil texture data.
+ */
+static GLboolean
+_mesa_texstore_s8(TEXSTORE_PARAMS)
+{
+   ASSERT(dstFormat == MESA_FORMAT_S8);
+   ASSERT(srcFormat == GL_STENCIL_INDEX);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_BYTE) {
+      /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
                      dstRowStride,
@@ -2743,14 +3329,13 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else {
-      /* general path */
       const GLint srcRowStride
-         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-         / sizeof(GLuint);
+        = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+        / sizeof(GLuint);
       GLint img, row;
-
+      
       for (img = 0; img < srcDepth; img++) {
-         GLuint *dstRow = (GLuint *) dstAddr
+         GLubyte *dstRow = (GLubyte *) dstAddr
             + dstImageOffsets[dstZoffset + img]
             + dstYoffset * dstRowStride / sizeof(GLuint)
             + dstXoffset;
@@ -2762,12 +3347,7 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLubyte stencil[MAX_WIDTH];
             GLint i;
-            /* the 24 depth bits will be in the high position: */
-            _mesa_unpack_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT_24_8_EXT, /* dst type */
-                                    dstRow, /* dst addr */
-                                    (GLuint) depthScale,
-                                    srcType, src, srcPacking);
+
             /* get the 8-bit stencil values */
             _mesa_unpack_stencil_span(ctx, srcWidth,
                                       GL_UNSIGNED_BYTE, /* dst type */
@@ -2776,132 +3356,447 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
                                       ctx->_ImageTransferState);
             /* merge stencil values into depth values */
             for (i = 0; i < srcWidth; i++)
-               dstRow[i] |= stencil[i];
+               dstRow[i] = stencil[i];
 
             src += srcRowStride;
-            dstRow += dstRowStride / sizeof(GLuint);
+            dstRow += dstRowStride / sizeof(GLubyte);
          }
       }
+
    }
+
    return GL_TRUE;
 }
 
 
 /**
- * Store a combined depth/stencil texture image.
+ * Store an image in any of the formats:
+ *   _mesa_texformat_rgba_float32
+ *   _mesa_texformat_rgb_float32
+ *   _mesa_texformat_alpha_float32
+ *   _mesa_texformat_luminance_float32
+ *   _mesa_texformat_luminance_alpha_float32
+ *   _mesa_texformat_intensity_float32
  */
-GLboolean
-_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
+static GLboolean
+_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
 {
-   const GLuint depthScale = 0xffffff;
-   const GLint srcRowStride
-      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-      / sizeof(GLuint);
-   GLint img, row;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
+          dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
+          dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
+          dstFormat == MESA_FORMAT_INTENSITY_FLOAT32);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLfloat));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_FLOAT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *srcRow = tempImage;
+      GLint bytesPerRow;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      bytesPerRow = srcWidth * components * sizeof(GLfloat);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            memcpy(dstRow, srcRow, bytesPerRow);
+            dstRow += dstRowStride;
+            srcRow += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
 
-   ASSERT(dstFormat == &_mesa_texformat_s8_z24);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
-   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
 
-   /* In case we only upload depth we need to preserve the stencil */
-   if (srcFormat == GL_DEPTH_COMPONENT) {
+/**
+ * As above, but store 16-bit floats.
+ */
+static GLboolean
+_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
+          dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
+          dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
+          dstFormat == MESA_FORMAT_INTENSITY_FLOAT16);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLhalfARB));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_HALF_FLOAT_ARB) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking,
+                                                 ctx->_ImageTransferState);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLuint *dstRow = (GLuint *) dstAddr
-            + dstImageOffsets[dstZoffset + img]
-            + dstYoffset * dstRowStride / sizeof(GLuint)
-            + dstXoffset;
-         const GLuint *src
-            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
-                  srcWidth, srcHeight,
-                  srcFormat, srcType,
-                  img, 0, 0);
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = _mesa_float_to_half(src[i]);
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, signed int8 */
+static GLboolean
+_mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT8);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLbyte));
+
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking, 0x0);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLbyte *dstTexel = (GLbyte *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLbyte) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, signed int16 */
+static GLboolean
+_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT16);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLshort));
+
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_SHORT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking, 0x0);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLshort *dstTexel = (GLshort *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLint) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, signed int32 */
+static GLboolean
+_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT32);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLint));
+
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_INT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking, 0x0);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            GLuint depth[MAX_WIDTH];
+            GLint *dstTexel = (GLint *) dstRow;
             GLint i;
-            _mesa_unpack_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT, /* dst type */
-                                    depth, /* dst addr */
-                                    depthScale,
-                                    srcType, src, srcPacking);
-
-            for (i = 0; i < srcWidth; i++)
-               dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
-
-            src += srcRowStride;
-            dstRow += dstRowStride / sizeof(GLuint);
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLint) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
          }
       }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, unsigned int8 */
+static GLboolean
+_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT8);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLubyte));
+
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
    }
    else {
+      /* general path */
+      const GLuint *tempImage =
+         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
+                              srcWidth, srcHeight, srcDepth,
+                              srcFormat, srcType, srcAddr, srcPacking);
+      const GLuint *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLuint *dstRow = (GLuint *) dstAddr
-            + dstImageOffsets[dstZoffset + img]
-            + dstYoffset * dstRowStride / sizeof(GLuint)
-            + dstXoffset;
-         const GLuint *src
-            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
-                  srcWidth, srcHeight,
-                  srcFormat, srcType,
-                  img, 0, 0);
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            GLubyte stencil[MAX_WIDTH];
+            GLubyte *dstTexel = (GLubyte *) dstRow;
             GLint i;
-            /* the 24 depth bits will be in the low position: */
-            _mesa_unpack_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT, /* dst type */
-                                    dstRow, /* dst addr */
-                                    depthScale,
-                                    srcType, src, srcPacking);
-            /* get the 8-bit stencil values */
-            _mesa_unpack_stencil_span(ctx, srcWidth,
-                                      GL_UNSIGNED_BYTE, /* dst type */
-                                      stencil, /* dst addr */
-                                      srcType, src, srcPacking,
-                                      ctx->_ImageTransferState);
-            /* merge stencil values into depth values */
-            for (i = 0; i < srcWidth; i++)
-               dstRow[i] |= stencil[i] << 24;
-
-            src += srcRowStride;
-            dstRow += dstRowStride / sizeof(GLuint);
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
          }
       }
+
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
-/**
- * Store an image in any of the formats:
- *   _mesa_texformat_rgba_float32
- *   _mesa_texformat_rgb_float32
- *   _mesa_texformat_alpha_float32
- *   _mesa_texformat_luminance_float32
- *   _mesa_texformat_luminance_alpha_float32
- *   _mesa_texformat_intensity_float32
- */
-GLboolean
-_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
+
+/* non-normalized, unsigned int16 */
+static GLboolean
+_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
 {
-   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
-          dstFormat == &_mesa_texformat_rgb_float32 ||
-          dstFormat == &_mesa_texformat_alpha_float32 ||
-          dstFormat == &_mesa_texformat_luminance_float32 ||
-          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
-          dstFormat == &_mesa_texformat_intensity_float32);
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT16);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
           baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
+   ASSERT(texelBytes == components * sizeof(GLushort));
 
-   if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
        baseInternalFormat == srcFormat &&
-       srcType == GL_FLOAT) {
+       srcType == GL_UNSIGNED_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -2912,63 +3807,59 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
    }
    else {
       /* general path */
-      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 dstFormat->BaseFormat,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLfloat *srcRow = tempImage;
-      GLint bytesPerRow;
+      const GLuint *tempImage =
+         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
+                              srcWidth, srcHeight, srcDepth,
+                              srcFormat, srcType, srcAddr, srcPacking);
+      const GLuint *src = tempImage;
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
-      bytesPerRow = srcWidth * components * sizeof(GLfloat);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
+            GLushort *dstTexel = (GLushort *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
+            }
             dstRow += dstRowStride;
-            srcRow += srcWidth * components;
+            src += srcWidth * components;
          }
       }
 
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
-/**
- * As above, but store 16-bit floats.
- */
-GLboolean
-_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
+/* non-normalized, unsigned int32 */
+static GLboolean
+_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
 {
-   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
-          dstFormat == &_mesa_texformat_rgb_float16 ||
-          dstFormat == &_mesa_texformat_alpha_float16 ||
-          dstFormat == &_mesa_texformat_luminance_float16 ||
-          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
-          dstFormat == &_mesa_texformat_intensity_float16);
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT32);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
           baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
+   ASSERT(texelBytes == components * sizeof(GLuint));
 
-   if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
+   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
+    * to integer formats.
+    */
+   if (!srcPacking->SwapBytes &&
        baseInternalFormat == srcFormat &&
-       srcType == GL_HALF_FLOAT_ARB) {
+       srcType == GL_UNSIGNED_INT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
@@ -2979,75 +3870,71 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
    }
    else {
       /* general path */
-      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 dstFormat->BaseFormat,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLfloat *src = tempImage;
+      const GLuint *tempImage =
+         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
+                              srcWidth, srcHeight, srcDepth,
+                              srcFormat, srcType, srcAddr, srcPacking);
+      const GLuint *src = tempImage;
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
-      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
-            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
+            GLuint *dstTexel = (GLuint *) dstRow;
             GLint i;
             for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = _mesa_float_to_half(src[i]);
+               dstTexel[i] = src[i];
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
          }
       }
 
-      _mesa_free((void *) tempImage);
+      free((void *) tempImage);
    }
    return GL_TRUE;
 }
 
 
+
+
 #if FEATURE_EXT_texture_sRGB
-GLboolean
+static GLboolean
 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
 {
-   const struct gl_texture_format *newDstFormat;
-   StoreTexImageFunc store;
+   gl_format newDstFormat;
    GLboolean k;
 
-   ASSERT(dstFormat == &_mesa_texformat_srgb8);
+   ASSERT(dstFormat == MESA_FORMAT_SRGB8);
 
    /* reuse normal rgb texstore code */
-   newDstFormat = &_mesa_texformat_rgb888;
-   store = _mesa_texstore_rgb888;
-
-   k = store(ctx, dims, baseInternalFormat,
-             newDstFormat, dstAddr,
-             dstXoffset, dstYoffset, dstZoffset,
-             dstRowStride, dstImageOffsets,
-             srcWidth, srcHeight, srcDepth,
-             srcFormat, srcType,
-             srcAddr, srcPacking);
+   newDstFormat = MESA_FORMAT_RGB888;
+
+   k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
+                             newDstFormat, dstAddr,
+                             dstXoffset, dstYoffset, dstZoffset,
+                             dstRowStride, dstImageOffsets,
+                             srcWidth, srcHeight, srcDepth,
+                             srcFormat, srcType,
+                             srcAddr, srcPacking);
    return k;
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
 {
-   const struct gl_texture_format *newDstFormat;
+   gl_format newDstFormat;
    GLboolean k;
 
-   ASSERT(dstFormat == &_mesa_texformat_srgba8);
+   ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
 
    /* reuse normal rgba texstore code */
-   newDstFormat = &_mesa_texformat_rgba8888;
-
+   newDstFormat = MESA_FORMAT_RGBA8888;
    k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
                                newDstFormat, dstAddr,
                                dstXoffset, dstYoffset, dstZoffset,
@@ -3059,16 +3946,16 @@ _mesa_texstore_srgba8(TEXSTORE_PARAMS)
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
 {
-   const struct gl_texture_format *newDstFormat;
+   gl_format newDstFormat;
    GLboolean k;
 
-   ASSERT(dstFormat == &_mesa_texformat_sargb8);
+   ASSERT(dstFormat == MESA_FORMAT_SARGB8);
 
    /* reuse normal rgba texstore code */
-   newDstFormat = &_mesa_texformat_argb8888;
+   newDstFormat = MESA_FORMAT_ARGB8888;
 
    k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
                                newDstFormat, dstAddr,
@@ -3081,15 +3968,15 @@ _mesa_texstore_sargb8(TEXSTORE_PARAMS)
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_sl8(TEXSTORE_PARAMS)
 {
-   const struct gl_texture_format *newDstFormat;
+   gl_format newDstFormat;
    GLboolean k;
 
-   ASSERT(dstFormat == &_mesa_texformat_sl8);
+   ASSERT(dstFormat == MESA_FORMAT_SL8);
 
-   newDstFormat = &_mesa_texformat_l8;
+   newDstFormat = MESA_FORMAT_L8;
 
    /* _mesa_textore_a8 handles luminance8 too */
    k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
@@ -3103,30 +3990,210 @@ _mesa_texstore_sl8(TEXSTORE_PARAMS)
 }
 
 
-GLboolean
+static GLboolean
 _mesa_texstore_sla8(TEXSTORE_PARAMS)
 {
-   const struct gl_texture_format *newDstFormat;
+   gl_format newDstFormat;
    GLboolean k;
 
-   ASSERT(dstFormat == &_mesa_texformat_sla8);
+   ASSERT(dstFormat == MESA_FORMAT_SLA8);
 
    /* reuse normal luminance/alpha texstore code */
-   newDstFormat = &_mesa_texformat_al88;
-
-   k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
-                           newDstFormat, dstAddr,
-                           dstXoffset, dstYoffset, dstZoffset,
-                           dstRowStride, dstImageOffsets,
-                           srcWidth, srcHeight, srcDepth,
-                           srcFormat, srcType,
-                           srcAddr, srcPacking);
+   newDstFormat = MESA_FORMAT_AL88;
+
+   k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
+                             newDstFormat, dstAddr,
+                             dstXoffset, dstYoffset, dstZoffset,
+                             dstRowStride, dstImageOffsets,
+                             srcWidth, srcHeight, srcDepth,
+                             srcFormat, srcType,
+                             srcAddr, srcPacking);
    return k;
 }
 
+#else
+
+/* these are used only in texstore_funcs[] below */
+#define _mesa_texstore_srgb8 NULL
+#define _mesa_texstore_srgba8 NULL
+#define _mesa_texstore_sargb8 NULL
+#define _mesa_texstore_sl8 NULL
+#define _mesa_texstore_sla8 NULL
+
 #endif /* FEATURE_EXT_texture_sRGB */
 
 
+
+
+/**
+ * Table mapping MESA_FORMAT_* to _mesa_texstore_*()
+ * XXX this is somewhat temporary.
+ */
+static const struct {
+   gl_format Name;
+   StoreTexImageFunc Store;
+}
+texstore_funcs[MESA_FORMAT_COUNT] =
+{
+   { MESA_FORMAT_NONE, NULL },
+   { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 },
+   { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
+   { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
+   { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
+   { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
+   { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
+   { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
+   { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
+   { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
+   { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
+   { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
+   { MESA_FORMAT_AL44, _mesa_texstore_unorm44 },
+   { MESA_FORMAT_AL88, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_AL88_REV, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_AL1616, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_AL1616_REV, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
+   { MESA_FORMAT_A8, _mesa_texstore_a8 },
+   { MESA_FORMAT_A16, _mesa_texstore_unorm16 },
+   { MESA_FORMAT_L8, _mesa_texstore_a8 },
+   { MESA_FORMAT_L16, _mesa_texstore_unorm16 },
+   { MESA_FORMAT_I8, _mesa_texstore_a8 },
+   { MESA_FORMAT_I16, _mesa_texstore_unorm16 },
+   { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
+   { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
+   { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
+   { MESA_FORMAT_R8, _mesa_texstore_a8 },
+   { MESA_FORMAT_RG88, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_RG88_REV, _mesa_texstore_unorm88 },
+   { MESA_FORMAT_R16, _mesa_texstore_unorm16 },
+   { MESA_FORMAT_RG1616, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_RG1616_REV, _mesa_texstore_unorm1616 },
+   { MESA_FORMAT_ARGB2101010, _mesa_texstore_argb2101010 },
+   { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
+   { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
+   { MESA_FORMAT_Z16, _mesa_texstore_z16 },
+   { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
+   { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 },
+   { MESA_FORMAT_Z32, _mesa_texstore_z32 },
+   { MESA_FORMAT_S8, _mesa_texstore_s8 },
+   { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
+   { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 },
+   { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 },
+   { MESA_FORMAT_SL8, _mesa_texstore_sl8 },
+   { MESA_FORMAT_SLA8, _mesa_texstore_sla8 },
+   { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 },
+   { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 },
+   { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 },
+   { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 },
+   { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 },
+   { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 },
+   { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 },
+   { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
+   { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
+   { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
+   { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
+
+   { MESA_FORMAT_RGBA_INT8, _mesa_texstore_rgba_int8 },
+   { MESA_FORMAT_RGBA_INT16, _mesa_texstore_rgba_int16 },
+   { MESA_FORMAT_RGBA_INT32, _mesa_texstore_rgba_int32 },
+   { MESA_FORMAT_RGBA_UINT8, _mesa_texstore_rgba_uint8 },
+   { MESA_FORMAT_RGBA_UINT16, _mesa_texstore_rgba_uint16 },
+   { MESA_FORMAT_RGBA_UINT32, _mesa_texstore_rgba_uint32 },
+
+   { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
+
+   { MESA_FORMAT_SIGNED_R8, _mesa_texstore_signed_r8 },
+   { MESA_FORMAT_SIGNED_RG88, _mesa_texstore_signed_rg88 },
+   { MESA_FORMAT_SIGNED_RGBX8888, _mesa_texstore_signed_rgbx8888 },
+
+   { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
+   { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
+
+   { MESA_FORMAT_SIGNED_R_16, _mesa_texstore_signed_rgba_16 },
+   { MESA_FORMAT_SIGNED_RG_16, _mesa_texstore_signed_rgba_16 },
+   { MESA_FORMAT_SIGNED_RGB_16, _mesa_texstore_signed_rgba_16 },
+   { MESA_FORMAT_SIGNED_RGBA_16, _mesa_texstore_signed_rgba_16 },
+   { MESA_FORMAT_RGBA_16, _mesa_texstore_rgba_16 }
+};
+
+
+static GLboolean
+_mesa_texstore_null(TEXSTORE_PARAMS)
+{
+   (void) ctx; (void) dims;
+   (void) baseInternalFormat;
+   (void) dstFormat;
+   (void) dstAddr;
+   (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
+   (void) dstRowStride; (void) dstImageOffsets;
+   (void) srcWidth; (void) srcHeight; (void) srcDepth;
+   (void) srcFormat; (void) srcType;
+   (void) srcAddr;
+   (void) srcPacking;
+
+   /* should never happen */
+   _mesa_problem(NULL, "_mesa_texstore_null() is called");
+   return GL_FALSE;
+}
+
+
+/**
+ * Return the StoreTexImageFunc pointer to store an image in the given format.
+ */
+static StoreTexImageFunc
+_mesa_get_texstore_func(gl_format format)
+{
+#ifdef DEBUG
+   GLuint i;
+   for (i = 0; i < MESA_FORMAT_COUNT; i++) {
+      ASSERT(texstore_funcs[i].Name == i);
+   }
+#endif
+   ASSERT(texstore_funcs[format].Name == format);
+
+   if (texstore_funcs[format].Store)
+      return texstore_funcs[format].Store;
+   else
+      return _mesa_texstore_null;
+}
+
+
+/**
+ * Store user data into texture memory.
+ * Called via glTex[Sub]Image1/2/3D()
+ */
+GLboolean
+_mesa_texstore(TEXSTORE_PARAMS)
+{
+   StoreTexImageFunc storeImage;
+   GLboolean success;
+
+   storeImage = _mesa_get_texstore_func(dstFormat);
+
+   success = storeImage(ctx, dims, baseInternalFormat,
+                        dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                        dstRowStride, dstImageOffsets,
+                        srcWidth, srcHeight, srcDepth,
+                        srcFormat, srcType, srcAddr, srcPacking);
+   return success;
+}
+
+
 /**
  * Check if an unpack PBO is active prior to fetching a texture image.
  * If so, do bounds checking and map the buffer into main memory.
@@ -3134,7 +4201,7 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
  * The caller _must_ call _mesa_unmap_teximage_pbo() too!
  */
 const GLvoid *
-_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
+_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions,
                            GLsizei width, GLsizei height, GLsizei depth,
                            GLenum format, GLenum type, const GLvoid *pixels,
                            const struct gl_pixelstore_attrib *unpack,
@@ -3148,14 +4215,14 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
    }
    if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
                                   format, type, pixels)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)");
       return NULL;
    }
 
    buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
                                           GL_READ_ONLY_ARB, unpack->BufferObj);
    if (!buf) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
+      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped)");
       return NULL;
    }
 
@@ -3171,7 +4238,7 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
  * The caller _must_ call _mesa_unmap_teximage_pbo() too!
  */
 const GLvoid *
-_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
+_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx,
                                  GLsizei imageSize, const GLvoid *pixels,
                                  const struct gl_pixelstore_attrib *packing,
                                  const char *funcName)
@@ -3185,7 +4252,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
    if ((const GLubyte *) pixels + imageSize >
        ((const GLubyte *) 0) + packing->BufferObj->Size) {
       /* out of bounds read! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)");
       return NULL;
    }
 
@@ -3205,7 +4272,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
  * functions.  It unmaps the PBO buffer if it was mapped earlier.
  */
 void
-_mesa_unmap_teximage_pbo(GLcontext *ctx,
+_mesa_unmap_teximage_pbo(struct gl_context *ctx,
                          const struct gl_pixelstore_attrib *unpack)
 {
    if (_mesa_is_bufferobj(unpack->BufferObj)) {
@@ -3215,136 +4282,23 @@ _mesa_unmap_teximage_pbo(GLcontext *ctx,
 }
 
 
-
-/**
- * Adaptor for fetching a GLchan texel from a float-valued texture.
- */
-static void
-fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
-                          GLint i, GLint j, GLint k, GLchan *texelOut)
-{
-   GLfloat temp[4];
-   ASSERT(texImage->FetchTexelf);
-   texImage->FetchTexelf(texImage, i, j, k, temp);
-   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
-       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
-      /* just one channel */
-      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
-   }
-   else {
-      /* four channels */
-      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
-      UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
-      UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
-      UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
-   }
-}
-
-
-/**
- * Adaptor for fetching a float texel from a GLchan-valued texture.
- */
-static void
-fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
-                          GLint i, GLint j, GLint k, GLfloat *texelOut)
-{
-   GLchan temp[4];
-   ASSERT(texImage->FetchTexelc);
-   texImage->FetchTexelc(texImage, i, j, k, temp);
-   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
-       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
-      /* just one channel */
-      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
-   }
-   else {
-      /* four channels */
-      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
-      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
-      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
-      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
-   }
-}
-
-
-/**
- * Initialize the texture image's FetchTexelc and FetchTexelf methods.
- */
-void
-_mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
+/** Return texture size in bytes */
+static GLuint
+texture_size(const struct gl_texture_image *texImage)
 {
-   ASSERT(dims == 1 || dims == 2 || dims == 3);
-   ASSERT(texImage->TexFormat);
-
-   switch (dims) {
-   case 1:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
-      break;
-   case 2:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
-      break;
-   case 3:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
-      break;
-   default:
-      ;
-   }
-
-   /* now check if we need to use a float/chan adaptor */
-   if (!texImage->FetchTexelc) {
-      texImage->FetchTexelc = fetch_texel_float_to_chan;
-   }
-   else if (!texImage->FetchTexelf) {
-      texImage->FetchTexelf = fetch_texel_chan_to_float;
-   }
-
-
-   ASSERT(texImage->FetchTexelc);
-   ASSERT(texImage->FetchTexelf);
+   GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
+                                       texImage->Height, texImage->Depth);
+   return sz;
 }
 
 
-/**
- * Choose the actual storage format for a new texture image.
- * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
- * Also set some other texImage fields related to texture compression, etc.
- * \param ctx  rendering context
- * \param texImage  the gl_texture_image
- * \param dims  texture dimensions (1, 2 or 3)
- * \param format  the user-specified format parameter
- * \param type  the user-specified type parameter
- * \param internalFormat  the user-specified internal format hint
- */
-static void
-choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
-                      GLuint dims,
-                      GLenum format, GLenum type, GLint internalFormat)
+/** Return row stride in bytes */
+static GLuint
+texture_row_stride(const struct gl_texture_image *texImage)
 {
-   ASSERT(dims == 1 || dims == 2 || dims == 3);
-   ASSERT(ctx->Driver.ChooseTextureFormat);
-
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-
-   ASSERT(texImage->TexFormat);
-
-   _mesa_set_fetch_functions(texImage, dims);
-
-   if (texImage->TexFormat->TexelBytes == 0) {
-      /* must be a compressed format */
-      texImage->IsCompressed = GL_TRUE;
-      texImage->CompressedSize =
-         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
-                                           texImage->Height, texImage->Depth,
-                                           texImage->TexFormat->MesaFormat);
-   }
-   else {
-      /* non-compressed format */
-      texImage->IsCompressed = GL_FALSE;
-      texImage->CompressedSize = 0;
-   }
+   GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
+                                           texImage->Width);
+   return stride;
 }
 
 
@@ -3353,12 +4307,9 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
  * This is the software fallback for Driver.TexImage1D()
  * and Driver.CopyTexImage1D().
  * \sa _mesa_store_teximage2d()
- * Note that the width may not be the actual texture width since it may
- * be changed by convolution w/ GL_REDUCE.  The texImage->Width field will
- * have the actual texture size.
  */
 void
-_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
                        GLint internalFormat,
                        GLint width, GLint border,
                        GLenum format, GLenum type, const GLvoid *pixels,
@@ -3366,16 +4317,11 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLint sizeInBytes;
+   GLuint sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
-
    /* allocate memory */
-   if (texImage->IsCompressed)
-      sizeInBytes = texImage->CompressedSize;
-   else
-      sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes;
+   sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    if (!texImage->Data) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
@@ -3392,26 +4338,19 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    }
    else {
       const GLint dstRowStride = 0;
-      GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         0, 0, 0,  /* dstX/Y/Zoffset */
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, 1, 1,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3422,12 +4361,9 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
  *
  * This function is oriented toward storing images in main memory, rather
  * than VRAM.  Device driver's can easily plug in their own replacement.
- *
- * Note: width and height may be pre-convolved dimensions, but
- * texImage->Width and texImage->Height will be post-convolved dimensions.
  */
 void
-_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
                        GLint internalFormat,
                        GLint width, GLint height, GLint border,
                        GLenum format, GLenum type, const void *pixels,
@@ -3435,18 +4371,11 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLint texelBytes, sizeInBytes;
+   GLuint sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
-
-   texelBytes = texImage->TexFormat->TexelBytes;
-
    /* allocate memory */
-   if (texImage->IsCompressed)
-      sizeInBytes = texImage->CompressedSize;
-   else
-      sizeInBytes = texImage->Width * texImage->Height * texelBytes;
+   sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    if (!texImage->Data) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
@@ -3462,34 +4391,20 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
    else {
-      GLint dstRowStride;
-      GLboolean success;
-      if (texImage->IsCompressed) {
-         dstRowStride
-            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
-      }
-      else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, 1,
-                                                format, type, pixels, packing);
+      GLint dstRowStride = texture_row_stride(texImage);
+      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         0, 0, 0,  /* dstX/Y/Zoffset */
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, height, 1,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3501,7 +4416,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
  * \sa _mesa_store_teximage2d()
  */
 void
-_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
                        GLint internalFormat,
                        GLint width, GLint height, GLint depth, GLint border,
                        GLenum format, GLenum type, const void *pixels,
@@ -3509,18 +4424,11 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLint texelBytes, sizeInBytes;
+   GLuint sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
-
-   texelBytes = texImage->TexFormat->TexelBytes;
-
    /* allocate memory */
-   if (texImage->IsCompressed)
-      sizeInBytes = texImage->CompressedSize;
-   else
-      sizeInBytes = width * height * depth * texelBytes;
+   sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    if (!texImage->Data) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
@@ -3536,34 +4444,20 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
    else {
-      GLint dstRowStride;
-      GLboolean success;
-      if (texImage->IsCompressed) {
-         dstRowStride
-            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
-      }
-      else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, depth,
-                                                format, type, pixels, packing);
+      GLint dstRowStride = texture_row_stride(texImage);
+      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         0, 0, 0,  /* dstX/Y/Zoffset */
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, height, depth,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3575,7 +4469,7 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
  * and Driver.CopyTexSubImage1D().
  */
 void
-_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
                           GLint xoffset, GLint width,
                           GLenum format, GLenum type, const void *pixels,
                           const struct gl_pixelstore_attrib *packing,
@@ -3590,26 +4484,19 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
 
    {
       const GLint dstRowStride = 0;
-      GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, 0, 0,  /* offsets */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         xoffset, 0, 0,  /* offsets */
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, 1, 1,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3620,7 +4507,7 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
  * and Driver.CopyTexSubImage2D().
  */
 void
-_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
                           GLint xoffset, GLint yoffset,
                           GLint width, GLint height,
                           GLenum format, GLenum type, const void *pixels,
@@ -3635,34 +4522,20 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
 
    {
-      GLint dstRowStride = 0;
-      GLboolean success;
-      if (texImage->IsCompressed) {
-         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
-                                                    texImage->Width);
-      }
-      else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, yoffset, 0,
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, 1,
-                                                format, type, pixels, packing);
+      GLint dstRowStride = texture_row_stride(texImage);
+      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         xoffset, yoffset, 0,
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, height, 1,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3672,7 +4545,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
  * and Driver.CopyTexSubImage3D().
  */
 void
-_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
                           GLint xoffset, GLint yoffset, GLint zoffset,
                           GLint width, GLint height, GLint depth,
                           GLenum format, GLenum type, const void *pixels,
@@ -3688,34 +4561,20 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
       return;
 
    {
-      GLint dstRowStride;
-      GLboolean success;
-      if (texImage->IsCompressed) {
-         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
-                                                    texImage->Width);
-      }
-      else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, yoffset, zoffset,
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, depth,
-                                                format, type, pixels, packing);
+      GLint dstRowStride = texture_row_stride(texImage);
+      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                                         texImage->TexFormat,
+                                         texImage->Data,
+                                         xoffset, yoffset, zoffset,
+                                         dstRowStride,
+                                         texImage->ImageOffsets,
+                                         width, height, depth,
+                                         format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3724,7 +4583,8 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
  * Fallback for Driver.CompressedTexImage1D()
  */
 void
-_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_compressed_teximage1d(struct gl_context *ctx,
+                                  GLenum target, GLint level,
                                   GLint internalFormat,
                                   GLint width, GLint border,
                                   GLsizei imageSize, const GLvoid *data,
@@ -3747,7 +4607,8 @@ _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
  * Fallback for Driver.CompressedTexImage2D()
  */
 void
-_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_compressed_teximage2d(struct gl_context *ctx,
+                                  GLenum target, GLint level,
                                   GLint internalFormat,
                                   GLint width, GLint height, GLint border,
                                   GLsizei imageSize, const GLvoid *data,
@@ -3766,8 +4627,6 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    ASSERT(texImage->Depth == 1);
    ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
 
-   choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
-
    /* allocate storage */
    texImage->Data = _mesa_alloc_texmemory(imageSize);
    if (!texImage->Data) {
@@ -3782,13 +4641,7 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
 
    /* copy the data */
-   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
-   MEMCPY(texImage->Data, data, imageSize);
-
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
+   memcpy(texImage->Data, data, imageSize);
 
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
@@ -3799,7 +4652,8 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
  * Fallback for Driver.CompressedTexImage3D()
  */
 void
-_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+_mesa_store_compressed_teximage3d(struct gl_context *ctx,
+                                  GLenum target, GLint level,
                                   GLint internalFormat,
                                   GLint width, GLint height, GLint depth,
                                   GLint border,
@@ -3824,7 +4678,7 @@ _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
  * Fallback for Driver.CompressedTexSubImage1D()
  */
 void
-_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
+_mesa_store_compressed_texsubimage1d(struct gl_context *ctx, GLenum target,
                                      GLint level,
                                      GLint xoffset, GLsizei width,
                                      GLenum format,
@@ -3847,7 +4701,7 @@ _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
  * Fallback for Driver.CompressedTexSubImage2D()
  */
 void
-_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
+_mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
                                      GLint level,
                                      GLint xoffset, GLint yoffset,
                                      GLsizei width, GLsizei height,
@@ -3860,15 +4714,20 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    GLint i, rows;
    GLubyte *dest;
    const GLubyte *src;
-   const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
+   const gl_format texFormat = texImage->TexFormat;
+   const GLint destWidth = texImage->Width;
+   GLuint bw, bh;
+
+   _mesa_get_format_block_size(texFormat, &bw, &bh);
 
+   (void) level;
    (void) format;
 
    /* these should have been caught sooner */
-   ASSERT((width & 3) == 0 || width == 2 || width == 1);
-   ASSERT((height & 3) == 0 || height == 2 || height == 1);
-   ASSERT((xoffset & 3) == 0);
-   ASSERT((yoffset & 3) == 0);
+   ASSERT((width % bw) == 0 || width == 2 || width == 1);
+   ASSERT((height % bh) == 0 || height == 2 || height == 1);
+   ASSERT((xoffset % bw) == 0);
+   ASSERT((yoffset % bh) == 0);
 
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
@@ -3877,29 +4736,24 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    if (!data)
       return;
 
-   srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
+   srcRowStride = _mesa_format_row_stride(texFormat, width);
    src = (const GLubyte *) data;
 
-   destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
+   destRowStride = _mesa_format_row_stride(texFormat, destWidth);
    dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
-                                         texImage->TexFormat->MesaFormat,
-                                         texImage->Width,
+                                         texFormat, destWidth,
                                          (GLubyte *) texImage->Data);
 
-   bytesPerRow = srcRowStride;
-   rows = height / 4;
+   bytesPerRow = srcRowStride;  /* bytes per row of blocks */
+   rows = height / bh;  /* rows in blocks */
 
+   /* copy rows of blocks */
    for (i = 0; i < rows; i++) {
-      MEMCPY(dest, src, bytesPerRow);
+      memcpy(dest, src, bytesPerRow);
       dest += destRowStride;
       src += srcRowStride;
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
 
@@ -3908,7 +4762,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
  * Fallback for Driver.CompressedTexSubImage3D()
  */
 void
-_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
+_mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target,
                                 GLint level,
                                 GLint xoffset, GLint yoffset, GLint zoffset,
                                 GLsizei width, GLsizei height, GLsizei depth,