mesa: rename MESA_FORMAT_RG88 to MESA_FORMAT_GR88
[mesa.git] / src / mesa / main / texstore.c
index 9a690529a83407103812356a42041beadddc1c4d..5f62cf864beb41c73b60f37887e5ac8e6c74328c 100644 (file)
 #include "pack.h"
 #include "pbo.h"
 #include "imports.h"
-#include "pack.h"
 #include "texcompress.h"
 #include "texcompress_fxt1.h"
 #include "texcompress_rgtc.h"
 #include "texcompress_s3tc.h"
+#include "texcompress_etc.h"
 #include "teximage.h"
 #include "texstore.h"
 #include "enums.h"
+#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
+#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
 
 
 enum {
@@ -339,7 +341,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
           logicalBaseFormat == GL_LUMINANCE ||
           logicalBaseFormat == GL_ALPHA ||
           logicalBaseFormat == GL_INTENSITY ||
-          logicalBaseFormat == GL_COLOR_INDEX ||
           logicalBaseFormat == GL_DEPTH_COMPONENT);
 
    ASSERT(textureBaseFormat == GL_RGBA ||
@@ -350,7 +351,6 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_LUMINANCE ||
           textureBaseFormat == GL_ALPHA ||
           textureBaseFormat == GL_INTENSITY ||
-          textureBaseFormat == GL_COLOR_INDEX ||
           textureBaseFormat == GL_DEPTH_COMPONENT);
 
    tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
@@ -459,6 +459,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_RED ||
           textureBaseFormat == GL_LUMINANCE_ALPHA ||
           textureBaseFormat == GL_LUMINANCE ||
+          textureBaseFormat == GL_INTENSITY ||
           textureBaseFormat == GL_ALPHA);
 
    tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
@@ -532,7 +533,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
 
 
 /**
- * Make a temporary (color) texture image with GLchan components.
+ * Make a temporary (color) texture image with GLubyte 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
@@ -552,21 +553,21 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
  * \param srcType  source image type
  * \param srcAddr  source image address
  * \param srcPacking  source image pixel packing
- * \return resulting image with format = textureBaseFormat and type = GLchan.
+ * \return resulting image with format = textureBaseFormat and type = GLubyte.
  */
-GLchan *
-_mesa_make_temp_chan_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)
+GLubyte *
+_mesa_make_temp_ubyte_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 transferOps = ctx->_ImageTransferState;
    const GLint components = _mesa_components_in_format(logicalBaseFormat);
    GLint img, row;
-   GLchan *tempImage, *dst;
+   GLubyte *tempImage, *dst;
 
    ASSERT(dims >= 1 && dims <= 3);
 
@@ -589,8 +590,8 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_INTENSITY);
 
    /* unpack and transfer the source image */
-   tempImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
-                                       * components * sizeof(GLchan));
+   tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+                                       * components * sizeof(GLubyte));
    if (!tempImage) {
       return NULL;
    }
@@ -605,9 +606,9 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
                                                srcFormat, srcType,
                                                img, 0, 0);
       for (row = 0; row < srcHeight; row++) {
-         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
-                                      srcFormat, srcType, src, srcPacking,
-                                      transferOps);
+         _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
+                                       srcFormat, srcType, src, srcPacking,
+                                       transferOps);
          dst += srcWidth * components;
          src += srcStride;
       }
@@ -617,7 +618,7 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
       /* one more conversion step */
       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
-      GLchan *newImage;
+      GLubyte *newImage;
       GLint i, n;
       GLubyte map[6];
 
@@ -630,8 +631,8 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
-                                         * texComponents * sizeof(GLchan));
+      newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+                                         * texComponents * sizeof(GLubyte));
       if (!newImage) {
          free(tempImage);
          return NULL;
@@ -647,7 +648,7 @@ _mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
             if (j == ZERO)
                newImage[i * texComponents + k] = 0;
             else if (j == ONE)
-               newImage[i * texComponents + k] = CHAN_MAX;
+               newImage[i * texComponents + k] = 255;
             else
                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
          }
@@ -850,10 +851,9 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx,
                          const GLubyte *rgba2dst,
                          GLuint dstComponents,
 
-                         GLvoid *dstAddr,
                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
                          GLint dstRowStride,
-                          const GLuint *dstImageOffsets,
+                          GLubyte **dstSlices,
 
                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
                          const GLvoid *srcAddr,
@@ -896,7 +896,7 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx,
        srcRowStride == srcWidth * srcComponents &&
        dimensions < 3) {
       /* 1 and 2D images only */
-      GLubyte *dstImage = (GLubyte *) dstAddr
+      GLubyte *dstImage = dstSlices[0]
          + dstYoffset * dstRowStride
          + dstXoffset * dstComponents;
       swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 
@@ -906,8 +906,7 @@ _mesa_swizzle_ubyte_image(struct gl_context *ctx,
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          const GLubyte *srcRow = srcImage;
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstComponents
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * dstComponents;
          for (row = 0; row < srcHeight; row++) {
@@ -930,10 +929,9 @@ static void
 memcpy_texture(struct gl_context *ctx,
               GLuint dimensions,
                gl_format dstFormat,
-               GLvoid *dstAddr,
                GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
                GLint dstRowStride,
-               const GLuint *dstImageOffsets,
+               GLubyte **dstSlices,
                GLint srcWidth, GLint srcHeight, GLint srcDepth,
                GLenum srcFormat, GLenum srcType,
                const GLvoid *srcAddr,
@@ -948,81 +946,68 @@ memcpy_texture(struct gl_context *ctx,
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
    const GLint bytesPerRow = srcWidth * texelBytes;
 
-#if 0
-   /* XXX update/re-enable for dstImageOffsets array */
-   const GLint bytesPerImage = srcHeight * bytesPerRow;
-   const GLint bytesPerTexture = srcDepth * bytesPerImage;
-   GLubyte *dstImage = (GLubyte *) dstAddr
-                     + dstZoffset * dstImageStride
-                     + dstYoffset * dstRowStride
-                     + dstXoffset * texelBytes;
-
    if (dstRowStride == srcRowStride &&
-       dstRowStride == bytesPerRow &&
-       ((dstImageStride == srcImageStride &&
-         dstImageStride == bytesPerImage) ||
-        (srcDepth == 1))) {
-      /* one big memcpy */
-      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
+       dstRowStride == bytesPerRow) {
+      /* memcpy image by image */
+      GLint img;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstImage = dstSlices[dstZoffset + img]
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         ctx->Driver.TextureMemCpy(dstImage, srcImage,
+                                   bytesPerRow * srcHeight);
+         srcImage += srcImageStride;
+      }
    }
-   else
-   {
+   else {
+      /* memcpy row by row */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          const GLubyte *srcRow = srcImage;
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
          srcImage += srcImageStride;
-         dstImage += dstImageStride;
       }
    }
-#endif
-
-   GLint img, row;
-   for (img = 0; img < srcDepth; img++) {
-      const GLubyte *srcRow = srcImage;
-      GLubyte *dstRow = (GLubyte *) dstAddr
-         + dstImageOffsets[dstZoffset + img] * texelBytes
-         + dstYoffset * dstRowStride
-         + dstXoffset * texelBytes;
-      for (row = 0; row < srcHeight; row++) {
-         ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
-         dstRow += dstRowStride;
-         srcRow += srcRowStride;
-      }
-      srcImage += srcImageStride;
-   }
 }
 
 
 
 /**
- * Store a 32-bit integer depth component texture image.
+ * Store a 32-bit integer or float depth component texture image.
  */
 static GLboolean
 _mesa_texstore_z32(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffffffff;
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   GLenum dstType;
    (void) dims;
-   ASSERT(dstFormat == MESA_FORMAT_Z32);
+   ASSERT(dstFormat == MESA_FORMAT_Z32 ||
+          dstFormat == MESA_FORMAT_Z32_FLOAT);
    ASSERT(texelBytes == sizeof(GLuint));
 
+   if (dstFormat == MESA_FORMAT_Z32)
+      dstType = GL_UNSIGNED_INT;
+   else
+      dstType = GL_FLOAT;
+
    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) {
+       srcType == dstType) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1030,15 +1015,14 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
       /* general path */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + 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_depth_span(ctx, srcWidth,
-                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
+                                    dstType, dstRow,
                                     depthScale, srcType, src, srcPacking);
             dstRow += dstRowStride;
          }
@@ -1064,8 +1048,7 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
       /* general path */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1098,8 +1081,7 @@ _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
       /* general path */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1140,9 +1122,8 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1150,8 +1131,7 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
       /* general path */
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1190,9 +1170,8 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT_5_6_5) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1208,7 +1187,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       const GLubyte *src = (const GLubyte *)
          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
                              srcFormat, srcType, 0, 0, 0);
-      GLubyte *dst = (GLubyte *) dstAddr
+      GLubyte *dst = dstSlices[0]
                    + dstYoffset * dstRowStride
                    + dstXoffset * texelBytes;
       GLint row, col;
@@ -1234,19 +1213,18 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1254,17 +1232,17 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
             /* check for byteswapped format */
             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]),
-                                               CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_565( src[RCOMP],
+                                               src[GCOMP],
+                                               src[BCOMP] );
                   src += 3;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
-                                                   CHAN_TO_UBYTE(src[GCOMP]),
-                                                   CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_565_REV( src[RCOMP],
+                                                   src[GCOMP],
+                                                   src[BCOMP] );
                   src += 3;
                }
             }
@@ -1288,12 +1266,15 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
    ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
-          dstFormat == MESA_FORMAT_RGBA8888_REV);
+          dstFormat == MESA_FORMAT_RGBA8888_REV ||
+          dstFormat == MESA_FORMAT_RGBX8888 ||
+          dstFormat == MESA_FORMAT_RGBX8888_REV);
    ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_RGBA8888 &&
+      (dstFormat == MESA_FORMAT_RGBA8888 ||
+       dstFormat == MESA_FORMAT_RGBX8888) &&
        baseInternalFormat == GL_RGBA &&
       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
@@ -1301,15 +1282,15 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
        /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_RGBA8888_REV &&
+      (dstFormat == MESA_FORMAT_RGBA8888_REV ||
+       dstFormat == MESA_FORMAT_RGBX8888_REV) &&
        baseInternalFormat == GL_RGBA &&
       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
@@ -1317,9 +1298,8 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1334,8 +1314,10 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
 
       /* dstmap - how to swizzle from RGBA to dst format:
        */
-      if ((littleEndian && dstFormat == MESA_FORMAT_RGBA8888) ||
-         (!littleEndian && dstFormat == MESA_FORMAT_RGBA8888_REV)) {
+      if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
+                            dstFormat == MESA_FORMAT_RGBX8888)) ||
+         (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
+                            dstFormat == MESA_FORMAT_RGBX8888_REV))) {
         dstmap[3] = 0;
         dstmap[2] = 1;
         dstmap[1] = 2;
@@ -1353,45 +1335,45 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 4,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            if (dstFormat == MESA_FORMAT_RGBA8888) {
+            if (dstFormat == MESA_FORMAT_RGBA8888 ||
+                dstFormat == MESA_FORMAT_RGBX8888) {
                for (col = 0; col < srcWidth; col++) {
-                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
-                                                CHAN_TO_UBYTE(src[GCOMP]),
-                                                CHAN_TO_UBYTE(src[BCOMP]),
-                                                CHAN_TO_UBYTE(src[ACOMP]) );
+                  dstUI[col] = PACK_COLOR_8888( src[RCOMP],
+                                                src[GCOMP],
+                                                src[BCOMP],
+                                                src[ACOMP] );
                   src += 4;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
-                                                    CHAN_TO_UBYTE(src[GCOMP]),
-                                                    CHAN_TO_UBYTE(src[BCOMP]),
-                                                    CHAN_TO_UBYTE(src[ACOMP]) );
+                  dstUI[col] = PACK_COLOR_8888_REV( src[RCOMP],
+                                                    src[GCOMP],
+                                                    src[BCOMP],
+                                                    src[ACOMP] );
                   src += 4;
                }
             }
@@ -1427,9 +1409,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
         srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
       /* simple memcpy path (little endian) */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1443,9 +1424,8 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
         srcType == GL_UNSIGNED_INT_8_8_8_8)) {
       /* simple memcpy path (big endian) */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1463,8 +1443,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
             _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] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1499,8 +1478,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
             _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] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1552,55 +1530,54 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 4,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                               dstXoffset, dstYoffset, dstZoffset,
                                dstRowStride,
-                                dstImageOffsets,
+                                dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
             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]),
-                                                CHAN_TO_UBYTE(src[GCOMP]),
-                                                CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUI[col] = PACK_COLOR_8888( src[ACOMP],
+                                                src[RCOMP],
+                                                src[GCOMP],
+                                                src[BCOMP] );
                   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[RCOMP],
+                                                src[GCOMP],
+                                                src[BCOMP] );
                   src += 4;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
-                                                    CHAN_TO_UBYTE(src[RCOMP]),
-                                                    CHAN_TO_UBYTE(src[GCOMP]),
-                                                    CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUI[col] = PACK_COLOR_8888_REV( src[ACOMP],
+                                                    src[RCOMP],
+                                                    src[GCOMP],
+                                                    src[BCOMP] );
                   src += 4;
                }
             }
@@ -1631,9 +1608,8 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1648,8 +1624,7 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
             _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] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1682,35 +1657,34 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 3,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = (const GLchan *) tempImage;
+      const GLubyte *src = (const GLubyte *) tempImage;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
 #if 0
             if (littleEndian) {
                for (col = 0; col < srcWidth; col++) {
-                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
-                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
-                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
+                  dstRow[col * 3 + 0] = src[RCOMP];
+                  dstRow[col * 3 + 1] = src[GCOMP];
+                  dstRow[col * 3 + 2] = src[BCOMP];
                   srcUB += 3;
                }
             }
@@ -1724,9 +1698,9 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
             }
 #else
             for (col = 0; col < srcWidth; col++) {
-               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
-               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
-               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
+               dstRow[col * 3 + 0] = src[BCOMP];
+               dstRow[col * 3 + 1] = src[GCOMP];
+               dstRow[col * 3 + 2] = src[RCOMP];
                src += 3;
             }
 #endif
@@ -1757,9 +1731,8 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1774,8 +1747,7 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
             _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] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -1808,33 +1780,32 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 3,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }   
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = (const GLchan *) tempImage;
+      const GLubyte *src = (const GLubyte *) tempImage;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
-               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
-               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
-               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
+               dstRow[col * 3 + 0] = src[RCOMP];
+               dstRow[col * 3 + 1] = src[GCOMP];
+               dstRow[col * 3 + 2] = src[BCOMP];
                src += 3;
             }
             dstRow += dstRowStride;
@@ -1864,46 +1835,44 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             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]),
-                                                CHAN_TO_UBYTE(src[GCOMP]),
-                                                CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_4444( src[ACOMP],
+                                                src[RCOMP],
+                                                src[GCOMP],
+                                                src[BCOMP] );
                   src += 4;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
-                                                    CHAN_TO_UBYTE(src[RCOMP]),
-                                                    CHAN_TO_UBYTE(src[GCOMP]),
-                                                    CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_4444_REV( src[ACOMP],
+                                                    src[RCOMP],
+                                                    src[GCOMP],
+                                                    src[BCOMP] );
                   src += 4;
                }
             }
@@ -1932,36 +1901,34 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src =tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
            for (col = 0; col < srcWidth; col++) {
-              dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
-                                            CHAN_TO_UBYTE(src[GCOMP]),
-                                            CHAN_TO_UBYTE(src[BCOMP]),
-                                            CHAN_TO_UBYTE(src[ACOMP]) );
+              dstUS[col] = PACK_COLOR_5551( src[RCOMP],
+                                            src[GCOMP],
+                                            src[BCOMP],
+                                            src[ACOMP] );
              src += 4;
            }
             dstRow += dstRowStride;
@@ -1990,46 +1957,44 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src =tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             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]),
-                                                CHAN_TO_UBYTE(src[GCOMP]),
-                                                CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_1555( src[ACOMP],
+                                                src[RCOMP],
+                                                src[GCOMP],
+                                                src[BCOMP] );
                   src += 4;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
-                                                    CHAN_TO_UBYTE(src[RCOMP]),
-                                                    CHAN_TO_UBYTE(src[GCOMP]),
-                                                    CHAN_TO_UBYTE(src[BCOMP]) );
+                  dstUS[col] = PACK_COLOR_1555_REV( src[ACOMP],
+                                                    src[RCOMP],
+                                                    src[GCOMP],
+                                                    src[BCOMP] );
                   src += 4;
                }
             }
@@ -2059,9 +2024,8 @@ _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
        baseInternalFormat == GL_RGBA) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2079,8 +2043,7 @@ _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          if (baseInternalFormat == GL_RGBA) {
@@ -2136,27 +2099,26 @@ _mesa_texstore_unorm44(TEXSTORE_PARAMS)
 
    {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + 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]) );
+               dstUS[col] = PACK_COLOR_44( src[1],
+                                           src[0] );
                src += 2;
             }
             dstRow += dstRowStride;
@@ -2180,7 +2142,7 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
 
    ASSERT(dstFormat == MESA_FORMAT_AL88 ||
           dstFormat == MESA_FORMAT_AL88_REV ||
-          dstFormat == MESA_FORMAT_RG88 ||
+          dstFormat == MESA_FORMAT_GR88 ||
           dstFormat == MESA_FORMAT_RG88_REV);
    ASSERT(texelBytes == 2);
 
@@ -2189,15 +2151,14 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
        ((dstFormat == MESA_FORMAT_AL88 &&
          baseInternalFormat == GL_LUMINANCE_ALPHA &&
          srcFormat == GL_LUMINANCE_ALPHA) ||
-        (dstFormat == MESA_FORMAT_RG88 &&
+        (dstFormat == MESA_FORMAT_GR88 &&
          baseInternalFormat == srcFormat)) &&
        srcType == GL_UNSIGNED_BYTE &&
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2222,7 +2183,7 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
         }
       }
       else {
-        if ((littleEndian && dstFormat == MESA_FORMAT_RG88) ||
+        if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
             (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
            dstmap[0] = 0;
            dstmap[1] = 1;
@@ -2240,44 +2201,43 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 2,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }   
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == MESA_FORMAT_AL88 ||
-               dstFormat == MESA_FORMAT_RG88) {
+               dstFormat == MESA_FORMAT_GR88) {
                for (col = 0; col < srcWidth; col++) {
-                  /* src[0] is luminance, src[1] is alpha */
-                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
-                                             CHAN_TO_UBYTE(src[0]) );
+                  /* src[0] is luminance (or R), src[1] is alpha (or G) */
+                 dstUS[col] = PACK_COLOR_88( src[1],
+                                             src[0] );
                  src += 2;
                }
             }
             else {
                for (col = 0; col < srcWidth; col++) {
-                  /* src[0] is luminance, src[1] is alpha */
-                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
-                                                 CHAN_TO_UBYTE(src[0]) );
+                  /* src[0] is luminance (or R), src[1] is alpha (or G) */
+                 dstUS[col] = PACK_COLOR_88_REV( src[1],
+                                                 src[0] );
                  src += 2;
                }
             }
@@ -2317,9 +2277,8 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2337,8 +2296,7 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2394,9 +2352,8 @@ _mesa_texstore_unorm16(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2414,8 +2371,7 @@ _mesa_texstore_unorm16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2452,9 +2408,8 @@ _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2472,8 +2427,7 @@ _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2517,9 +2471,8 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
        srcType == GL_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2543,8 +2496,7 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
        * 3 or 4 components/pixel here.
        */
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2595,34 +2547,32 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
        srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + 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]) );
+               dstRow[col] = PACK_COLOR_332( src[RCOMP],
+                                             src[GCOMP],
+                                             src[BCOMP] );
                src += 3;
             }
             dstRow += dstRowStride;
@@ -2655,9 +2605,8 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_BYTE) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2684,31 +2633,30 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS)
                                srcType,
                                baseInternalFormat,
                                dstmap, 1,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }   
    else {
       /* general path */
-      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLchan *src = tempImage;
+      const GLubyte *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
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
-               dstRow[col] = CHAN_TO_UBYTE(src[col]);
+               dstRow[col] = src[col];
             }
             dstRow += dstRowStride;
             src += srcWidth;
@@ -2721,50 +2669,6 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS)
 
 
 
-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.
  */
@@ -2787,9 +2691,8 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 
    /* always just memcpy since no pixel transfer ops apply */
    memcpy_texture(ctx, dims,
-                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                  dstRowStride,
-                  dstImageOffsets,
+                  dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                  dstRowStride, dstSlices,
                   srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                   srcAddr, srcPacking);
 
@@ -2801,8 +2704,7 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
        !littleEndian) {
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2831,9 +2733,8 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2858,8 +2759,8 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
                                GL_UNSIGNED_BYTE, /* hack */
                                GL_LUMINANCE_ALPHA, /* hack */
                                dstmap, 2,
-                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }   
@@ -2891,7 +2792,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
       }
  
       src = tempImage;
-      dst = (GLbyte *) dstAddr
+      dst = (GLbyte *) dstSlices[0]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
       for (row = 0; row < srcHeight; row++) {
@@ -2926,9 +2827,8 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS)
        srcType == GL_BYTE) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2946,8 +2846,7 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLbyte *dstRow = (GLbyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -2985,9 +2884,8 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3005,8 +2903,7 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLbyte *dstRow = (GLbyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3046,9 +2943,8 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3066,8 +2962,7 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3108,9 +3003,8 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
        littleEndian) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3128,8 +3022,7 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3178,8 +3071,7 @@ _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLbyte *dstRow = (GLbyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3225,9 +3117,8 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
        (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
        /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3239,9 +3130,8 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
        (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3259,8 +3149,7 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLbyte *dstRow = (GLbyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3302,34 +3191,34 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffffff;
    const GLint srcRowStride
-      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-      / sizeof(GLuint);
+      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    GLint img, row;
 
    ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
+   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);
 
-   if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f &&
+   if (srcFormat == GL_DEPTH_STENCIL && 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,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
-   else if (srcFormat == GL_DEPTH_COMPONENT) {
+   else if (srcFormat == GL_DEPTH_COMPONENT ||
+            srcFormat == GL_STENCIL_INDEX) {
       /* In case we only upload depth we need to preserve the stencil */
       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,
+        GLuint *dstRow = (GLuint *) (dstSlices[dstZoffset + img]
+                                      + dstYoffset * dstRowStride
+                                      + dstXoffset * 4);
+         const GLubyte *src
+            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
                   srcWidth, srcHeight,
                   srcFormat, srcType,
                   img, 0, 0);
@@ -3386,8 +3275,7 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffffff;
    const GLint srcRowStride
-      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-      / sizeof(GLuint);
+      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    GLint img, row;
 
    ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
@@ -3398,12 +3286,11 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
           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,
+      GLuint *dstRow = (GLuint *) (dstSlices[dstZoffset + img]
+                                   + dstYoffset * dstRowStride
+                                   + dstXoffset * 4);
+      const GLubyte *src
+        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
                                                srcWidth, srcHeight,
                                                srcFormat, srcType,
                                                img, 0, 0);
@@ -3467,25 +3354,22 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_BYTE) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       const GLint srcRowStride
-        = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-        / sizeof(GLuint);
+        = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
       GLint img, row;
       
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img]
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride / sizeof(GLuint)
             + dstXoffset;
-         const GLuint *src
-            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+         const GLubyte *src
+            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
                                                    srcWidth, srcHeight,
                                                    srcFormat, srcType,
                                                    img, 0, 0);
@@ -3551,12 +3435,12 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
        baseInternalFormat == srcFormat &&
+       baseInternalFormat == baseFormat &&
        srcType == GL_FLOAT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3576,8 +3460,7 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
          return GL_FALSE;
       bytesPerRow = srcWidth * components * sizeof(GLfloat);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3625,12 +3508,12 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
        baseInternalFormat == srcFormat &&
+       baseInternalFormat == baseFormat &&
        srcType == GL_HALF_FLOAT_ARB) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3648,8 +3531,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3677,7 +3559,14 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT8);
+   ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
+          dstFormat == MESA_FORMAT_RG_INT8 ||
+          dstFormat == MESA_FORMAT_RGB_INT8 ||
+          dstFormat == MESA_FORMAT_RGBA_INT8 ||
+          dstFormat == MESA_FORMAT_ALPHA_INT8 ||
+          dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -3694,9 +3583,8 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
        srcType == GL_BYTE) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3713,8 +3601,7 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3742,7 +3629,14 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT16);
+   ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
+          dstFormat == MESA_FORMAT_RG_INT16 ||
+          dstFormat == MESA_FORMAT_RGB_INT16 ||
+          dstFormat == MESA_FORMAT_RGBA_INT16 ||
+          dstFormat == MESA_FORMAT_ALPHA_INT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
+          dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -3759,9 +3653,8 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
        srcType == GL_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3778,8 +3671,7 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3807,7 +3699,14 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT32);
+   ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
+          dstFormat == MESA_FORMAT_RG_INT32 ||
+          dstFormat == MESA_FORMAT_RGB_INT32 ||
+          dstFormat == MESA_FORMAT_RGBA_INT32 ||
+          dstFormat == MESA_FORMAT_ALPHA_INT32 ||
+          dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -3824,9 +3723,8 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
        srcType == GL_INT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3843,8 +3741,7 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3872,7 +3769,14 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT8);
+   ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
+          dstFormat == MESA_FORMAT_RG_UINT8 ||
+          dstFormat == MESA_FORMAT_RGB_UINT8 ||
+          dstFormat == MESA_FORMAT_RGBA_UINT8 ||
+          dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
+          dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -3889,9 +3793,8 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_BYTE) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3906,8 +3809,7 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3935,7 +3837,14 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT16);
+   ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
+          dstFormat == MESA_FORMAT_RG_UINT16 ||
+          dstFormat == MESA_FORMAT_RGB_UINT16 ||
+          dstFormat == MESA_FORMAT_RGBA_UINT16 ||
+          dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
+          dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -3952,9 +3861,8 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_SHORT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -3969,8 +3877,7 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -3998,7 +3905,14 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
    const GLint components = _mesa_components_in_format(baseFormat);
 
-   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT32);
+   ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
+          dstFormat == MESA_FORMAT_RG_UINT32 ||
+          dstFormat == MESA_FORMAT_RGB_UINT32 ||
+          dstFormat == MESA_FORMAT_RGBA_UINT32 ||
+          dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
+          dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
+          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
    ASSERT(baseInternalFormat == GL_RGBA ||
           baseInternalFormat == GL_RGB ||
           baseInternalFormat == GL_ALPHA ||
@@ -4015,9 +3929,8 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
        srcType == GL_UNSIGNED_INT) {
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
-                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride,
-                     dstImageOffsets,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -4032,8 +3945,7 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * texelBytes
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
             + dstYoffset * dstRowStride
             + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
@@ -4068,9 +3980,9 @@ _mesa_texstore_srgb8(TEXSTORE_PARAMS)
    newDstFormat = MESA_FORMAT_RGB888;
 
    k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
-                             newDstFormat, dstAddr,
+                             newDstFormat,
                              dstXoffset, dstYoffset, dstZoffset,
-                             dstRowStride, dstImageOffsets,
+                             dstRowStride, dstSlices,
                              srcWidth, srcHeight, srcDepth,
                              srcFormat, srcType,
                              srcAddr, srcPacking);
@@ -4089,9 +4001,9 @@ _mesa_texstore_srgba8(TEXSTORE_PARAMS)
    /* reuse normal rgba texstore code */
    newDstFormat = MESA_FORMAT_RGBA8888;
    k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
-                               newDstFormat, dstAddr,
+                               newDstFormat,
                                dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth,
                                srcFormat, srcType,
                                srcAddr, srcPacking);
@@ -4111,9 +4023,9 @@ _mesa_texstore_sargb8(TEXSTORE_PARAMS)
    newDstFormat = MESA_FORMAT_ARGB8888;
 
    k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
-                               newDstFormat, dstAddr,
+                               newDstFormat,
                                dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageOffsets,
+                               dstRowStride, dstSlices,
                                srcWidth, srcHeight, srcDepth,
                                srcFormat, srcType,
                                srcAddr, srcPacking);
@@ -4133,12 +4045,12 @@ _mesa_texstore_sl8(TEXSTORE_PARAMS)
 
    /* _mesa_textore_a8 handles luminance8 too */
    k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
-                         newDstFormat, dstAddr,
-                         dstXoffset, dstYoffset, dstZoffset,
-                         dstRowStride, dstImageOffsets,
-                         srcWidth, srcHeight, srcDepth,
-                         srcFormat, srcType,
-                         srcAddr, srcPacking);
+                             newDstFormat,
+                             dstXoffset, dstYoffset, dstZoffset,
+                             dstRowStride, dstSlices,
+                             srcWidth, srcHeight, srcDepth,
+                             srcFormat, srcType,
+                             srcAddr, srcPacking);
    return k;
 }
 
@@ -4155,9 +4067,9 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
    newDstFormat = MESA_FORMAT_AL88;
 
    k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
-                             newDstFormat, dstAddr,
+                             newDstFormat,
                              dstXoffset, dstYoffset, dstZoffset,
-                             dstRowStride, dstImageOffsets,
+                             dstRowStride, dstSlices,
                              srcWidth, srcHeight, srcDepth,
                              srcFormat, srcType,
                              srcAddr, srcPacking);
@@ -4175,151 +4087,239 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
 
 #endif /* FEATURE_EXT_texture_sRGB */
 
+static GLboolean
+_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
+{
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
 
+   ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
+   ASSERT(baseInternalFormat == GL_RGB);
 
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       srcFormat == GL_RGB &&
+       srcType == GL_UNSIGNED_INT_5_9_9_9_REV) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = _mesa_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 = dstSlices[dstZoffset + img]
+            + dstYoffset * dstRowStride
+            + dstXoffset * 4;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint*)dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
+            }
+            dstRow += dstRowStride;
+            srcRow += srcWidth * 3;
+         }
+      }
 
-/**
- * Table mapping MESA_FORMAT_* to _mesa_texstore_*()
- * XXX this is somewhat temporary.
- */
-static const struct {
-   gl_format Name;
-   StoreTexImageFunc Store;
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
 }
-texstore_funcs[MESA_FORMAT_COUNT] =
+
+static GLboolean
+_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
 {
-   { 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_unorm8 },
-   { MESA_FORMAT_A16, _mesa_texstore_unorm16 },
-   { MESA_FORMAT_L8, _mesa_texstore_unorm8 },
-   { MESA_FORMAT_L16, _mesa_texstore_unorm16 },
-   { MESA_FORMAT_I8, _mesa_texstore_unorm8 },
-   { 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_unorm8 },
-   { 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_R_FLOAT32, _mesa_texstore_rgba_float32 },
-   { MESA_FORMAT_R_FLOAT16, _mesa_texstore_rgba_float16 },
-   { MESA_FORMAT_RG_FLOAT32, _mesa_texstore_rgba_float32 },
-   { MESA_FORMAT_RG_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_snorm8 },
-   { MESA_FORMAT_SIGNED_RG88_REV, _mesa_texstore_snorm88 },
-   { 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_R16, _mesa_texstore_snorm16 },
-   { MESA_FORMAT_SIGNED_GR1616, _mesa_texstore_snorm1616 },
-   { 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 },
-
-   { MESA_FORMAT_RED_RGTC1, _mesa_texstore_red_rgtc1 },
-   { MESA_FORMAT_SIGNED_RED_RGTC1, _mesa_texstore_signed_red_rgtc1 },
-   { MESA_FORMAT_RG_RGTC2, _mesa_texstore_rg_rgtc2 },
-   { MESA_FORMAT_SIGNED_RG_RGTC2, _mesa_texstore_signed_rg_rgtc2 },
-
-   /* Re-use the R/RG texstore functions.
-    * The code is generic enough to handle LATC too. */
-   { MESA_FORMAT_L_LATC1, _mesa_texstore_red_rgtc1 },
-   { MESA_FORMAT_SIGNED_L_LATC1, _mesa_texstore_signed_red_rgtc1 },
-   { MESA_FORMAT_LA_LATC2, _mesa_texstore_rg_rgtc2 },
-   { MESA_FORMAT_SIGNED_LA_LATC2, _mesa_texstore_signed_rg_rgtc2 },
-
-   { MESA_FORMAT_SIGNED_A8, _mesa_texstore_snorm8 },
-   { MESA_FORMAT_SIGNED_L8, _mesa_texstore_snorm8 },
-   { MESA_FORMAT_SIGNED_AL88, _mesa_texstore_snorm88 },
-   { MESA_FORMAT_SIGNED_I8, _mesa_texstore_snorm8 },
-
-   { MESA_FORMAT_SIGNED_A16, _mesa_texstore_snorm16 },
-   { MESA_FORMAT_SIGNED_L16, _mesa_texstore_snorm16 },
-   { MESA_FORMAT_SIGNED_AL1616, _mesa_texstore_snorm1616 },
-   { MESA_FORMAT_SIGNED_I16, _mesa_texstore_snorm16 },
-};
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
+   ASSERT(baseInternalFormat == GL_RGB);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       srcFormat == GL_RGB &&
+       srcType == GL_UNSIGNED_INT_10F_11F_11F_REV) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = _mesa_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 = dstSlices[dstZoffset + img]
+            + dstYoffset * dstRowStride
+            + dstXoffset * 4;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint*)dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
+            }
+            dstRow += dstRowStride;
+            srcRow += srcWidth * 3;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
 
 
+static GLboolean
+_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
+{
+   ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
+   ASSERT(srcFormat == GL_DEPTH_STENCIL ||
+          srcFormat == GL_DEPTH_COMPONENT ||
+          srcFormat == GL_STENCIL_INDEX);
+   ASSERT(srcFormat != GL_DEPTH_STENCIL ||
+          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+   if (srcFormat == GL_DEPTH_STENCIL &&
+       ctx->Pixel.DepthScale == 1.0f &&
+       ctx->Pixel.DepthBias == 0.0f &&
+       !srcPacking->SwapBytes) {
+      /* simple path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (srcFormat == GL_DEPTH_COMPONENT ||
+            srcFormat == GL_STENCIL_INDEX) {
+      GLint img, row;
+      const GLint srcRowStride
+         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+         / sizeof(uint64_t);
+
+      /* In case we only upload depth we need to preserve the stencil */
+      for (img = 0; img < srcDepth; img++) {
+         uint64_t *dstRow = (uint64_t *) (dstSlices[dstZoffset + img]
+                                          + dstYoffset * dstRowStride
+                                          + dstXoffset * 8);
+         const uint64_t *src
+            = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
+                  srcWidth, srcHeight,
+                  srcFormat, srcType,
+                  img, 0, 0);
+         for (row = 0; row < srcHeight; row++) {
+            /* The unpack functions with:
+             *    dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+             * only write their own dword, so the other dword (stencil
+             * or depth) is preserved. */
+            if (srcFormat != GL_STENCIL_INDEX)
+               _mesa_unpack_depth_span(ctx, srcWidth,
+                                       GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+                                       dstRow, /* dst addr */
+                                       1.0f, srcType, src, srcPacking);
+
+            if (srcFormat != GL_DEPTH_COMPONENT)
+               _mesa_unpack_stencil_span(ctx, srcWidth,
+                                         GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
+                                         dstRow, /* dst addr */
+                                         srcType, src, srcPacking,
+                                         ctx->_ImageTransferState);
+
+            src += srcRowStride;
+            dstRow += dstRowStride / sizeof(uint64_t);
+         }
+      }
+   }
+   return GL_TRUE;
+}
+
+static GLboolean
+_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
+   ASSERT(texelBytes == 4);
+
+   if (!srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_ARGB2101010_UINT &&
+       srcFormat == GL_BGRA_INTEGER_EXT &&
+       srcType == GL_UNSIGNED_INT_2_10_10_10_REV &&
+       baseInternalFormat == GL_RGBA) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride, dstSlices,
+                     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, col;
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = dstSlices[dstZoffset + img]
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               GLushort a,r,g,b;
+               r = src[RCOMP];
+               g = src[GCOMP];
+               b = src[BCOMP];
+               a = src[ACOMP];
+               dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
+               src += 4;
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
 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) dstRowStride; (void) dstSlices,
    (void) srcWidth; (void) srcHeight; (void) srcDepth;
    (void) srcFormat; (void) srcType;
    (void) srcAddr;
@@ -4337,18 +4337,181 @@ _mesa_texstore_null(TEXSTORE_PARAMS)
 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);
+   static StoreTexImageFunc table[MESA_FORMAT_COUNT];
+   static GLboolean initialized = GL_FALSE;
+
+   if (!initialized) {
+      table[MESA_FORMAT_NONE] = _mesa_texstore_null;
+
+      table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
+      table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
+      table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
+      table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
+      table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
+      table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
+      table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
+      table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
+      table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
+      table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
+      table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
+      table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
+      table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
+      table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
+      table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
+      table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
+      table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
+      table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
+      table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
+      table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
+      table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
+      table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
+      table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
+      table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
+      table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
+      table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
+      table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
+      table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
+      table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
+      table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
+      table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
+      table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
+      table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
+      table[MESA_FORMAT_RG88_REV] = _mesa_texstore_unorm88;
+      table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
+      table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
+      table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
+      table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
+      table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
+      table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
+      table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
+      table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
+      table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
+      table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
+      table[MESA_FORMAT_S8] = _mesa_texstore_s8;
+      table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
+      table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
+      table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
+      table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
+      table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
+      table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
+      table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
+      table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
+      table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
+      table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
+      table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
+      table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
+      table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
+      table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
+      table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
+      table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
+      table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
+      table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
+      table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
+      table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
+      table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
+      table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
+      table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
+      table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
+      table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
+      table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
+      table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
+      table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
+      table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
+      table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
+      table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
+      table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
+      table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
+      table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
+      table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
+      table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
+      table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
+      table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
+      table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
+      table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
+      table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
+      table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
+      table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
+      table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
+      table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
+      table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
+      table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
+      table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
+      table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
+
+      table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
+
+      table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
+
+      table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
+
+      table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
+
+      table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
+      table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
+      table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
+      table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
+      table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
+      table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
+
+      table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
+      table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
+      table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
+      table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
+
+      table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
+      initialized = GL_TRUE;
    }
-#endif
-   ASSERT(texstore_funcs[format].Name == format);
 
-   if (texstore_funcs[format].Store)
-      return texstore_funcs[format].Store;
-   else
-      return _mesa_texstore_null;
+   ASSERT(table[format]);
+   return table[format];
 }
 
 
@@ -4365,38 +4528,34 @@ _mesa_texstore(TEXSTORE_PARAMS)
    storeImage = _mesa_get_texstore_func(dstFormat);
 
    success = storeImage(ctx, dims, baseInternalFormat,
-                        dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                        dstRowStride, dstImageOffsets,
+                        dstFormat, dstXoffset, dstYoffset, dstZoffset,
+                        dstRowStride, dstSlices,
                         srcWidth, srcHeight, srcDepth,
                         srcFormat, srcType, srcAddr, srcPacking);
    return success;
 }
 
 
-/** Return texture size in bytes */
-static GLuint
-texture_size(const struct gl_texture_image *texImage)
-{
-   GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
-                                       texImage->Height, texImage->Depth);
-   return sz;
-}
-
-
-/** Return row stride in bytes */
-static GLuint
-texture_row_stride(const struct gl_texture_image *texImage)
+/**
+ * Normally, we'll only _write_ texel data to a texture when we map it.
+ * But if the user is providing depth or stencil values and the texture
+ * image is a combined depth/stencil format, we'll actually read from
+ * the texture buffer too (in order to insert the depth or stencil values.
+ * \param userFormat  the user-provided image format
+ * \param texFormat  the destination texture format
+ */
+static GLbitfield
+get_read_write_mode(GLenum userFormat, gl_format texFormat)
 {
-   GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
-                                           texImage->Width);
-   return stride;
+   if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
+       && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
+      return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
+   else
+      return GL_MAP_WRITE_BIT;
 }
 
-
-
 /**
- * This is the software fallback for Driver.TexImage1D()
- * and Driver.CopyTexImage1D().
+ * This is the software fallback for Driver.TexImage1D().
  * \sa _mesa_store_teximage2d()
  */
 void
@@ -4408,13 +4567,19 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    (void) border;
 
-   /* allocate memory */
-   sizeInBytes = texture_size(texImage);
-   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
-   if (!texImage->Data) {
+   if (width == 0)
+      return;
+
+   /* allocate storage for texture data */
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
+                                            width, 1, 1)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
       return;
    }
@@ -4427,28 +4592,36 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
        */
       return;
    }
+
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               0, 0, width, 1,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+   if (dstMap) {
+      success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                               texImage->TexFormat,
+                               0, 0, 0,  /* dstX/Y/Zoffset */
+                               0, /* dstRowStride */
+                               &dstMap,
+                               width, 1, 1,
+                               format, type, pixels, packing);
+
+      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+   }
    else {
-      const GLint dstRowStride = 0;
-      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");
-      }
+      success = GL_FALSE;
    }
 
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
 
 /**
- * This is the software fallback for Driver.TexImage2D()
- * and Driver.CopyTexImage2D().
+ * This is the software fallback for Driver.TexImage2D().
  *
  * This function is oriented toward storing images in main memory, rather
  * than VRAM.  Device driver's can easily plug in their own replacement.
@@ -4462,13 +4635,19 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    (void) border;
 
-   /* allocate memory */
-   sizeInBytes = texture_size(texImage);
-   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
-   if (!texImage->Data) {
+   if (width == 0 || height == 0)
+      return;
+
+   /* allocate storage for texture data */
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
+                                            width, height, 1)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
       return;
    }
@@ -4481,29 +4660,71 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
        */
       return;
    }
-   else {
-      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");
+
+   if (target == GL_TEXTURE_1D_ARRAY) {
+      const GLint srcStride =
+         _mesa_image_row_stride(packing, width, format, type);
+      int y;
+
+      success = GL_TRUE;
+
+      for (y = 0; y < height; y++) {
+         /* Map dest texture buffer (write to whole region) */
+         ctx->Driver.MapTextureImage(ctx, texImage, y,
+                                     0, 0, width, 1,
+                                     rwMode,
+                                     &dstMap, &dstRowStride);
+         if (dstMap) {
+            success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                                     texImage->TexFormat,
+                                     0, 0, 0,  /* dstX/Y/Zoffset */
+                                     dstRowStride,
+                                     &dstMap,
+                                     width, 1, 1,
+                                     format, type, pixels, packing);
+            ctx->Driver.UnmapTextureImage(ctx, texImage, y);
+         }
+         else {
+            success = GL_FALSE;
+         }
+
+         if (!success)
+            break;
+
+         pixels = (const GLubyte *) pixels + srcStride;
+      }
+   } else {
+      /* Map dest texture buffer (write to whole region) */
+      ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                                  0, 0, width, height,
+                                  rwMode,
+                                  &dstMap, &dstRowStride);
+      if (dstMap) {
+         success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                                  texImage->TexFormat,
+                                  0, 0, 0,  /* dstX/Y/Zoffset */
+                                  dstRowStride,
+                                  &dstMap,
+                                  width, height, 1,
+                                  format, type, pixels, packing);
+
+         ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+      }
+      else {
+         success = GL_FALSE;
       }
    }
 
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
 
 
 /**
- * This is the software fallback for Driver.TexImage3D()
- * and Driver.CopyTexImage3D().
+ * This is the software fallback for Driver.TexImage3D().
  * \sa _mesa_store_teximage2d()
  */
 void
@@ -4515,41 +4736,76 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLboolean success = GL_TRUE;
+   GLint slice;
+   GLubyte **sliceMaps;
+   GLint dstRowStride;
+
    (void) border;
 
-   /* allocate memory */
-   sizeInBytes = texture_size(texImage);
-   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
-   if (!texImage->Data) {
+   if (width == 0 || height == 0 || depth == 0)
+      return;
+
+   /* allocate storage for texture data */
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
+                                            width, height, depth)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
       return;
    }
 
-   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
-                                        type, pixels, packing, "glTexImage3D");
+   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
+                                        format, type,
+                                        pixels, packing, "glTexImage3D");
    if (!pixels) {
       /* Note: we check for a NULL image pointer here, _after_ we allocated
        * memory for the texture.  That's what the GL spec calls for.
        */
       return;
    }
-   else {
-      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");
+
+   if (target == GL_TEXTURE_1D_ARRAY) {
+      depth = height;
+      height = 1;
+   }
+
+   sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
+
+   /* Map dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.MapTextureImage(ctx, texImage, slice,
+                                  0, 0, width, height,
+                                  rwMode,
+                                  &sliceMaps[slice], &dstRowStride);
+      if (!sliceMaps[slice]) {
+         success = GL_FALSE;
+         break;
       }
    }
 
+   if (success) {
+      success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                               texImage->TexFormat,
+                               0, 0, 0,  /* dstX/Y/Zoffset */
+                               dstRowStride,
+                               sliceMaps,
+                               width, height, depth,
+                               format, type, pixels, packing);
+   }
+
+   /* Unmap dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      if (sliceMaps[slice]) {
+         ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
+      }
+   }
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
+
+   free(sliceMaps);
 }
 
 
@@ -4567,26 +4823,40 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
                                         pixels, packing, "glTexSubImage1D");
    if (!pixels)
       return;
 
-   {
-      const GLint dstRowStride = 0;
-      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");
-      }
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, 0, width, 1,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+
+   if (dstMap) {
+      success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                               texImage->TexFormat,
+                               0, 0, 0,  /* dstX/Y/Zoffset */
+                               dstRowStride,
+                               &dstMap,
+                               width, 1, 1,
+                               format, type, pixels, packing);
+
+      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
    }
+   else {
+      success = GL_FALSE;
+   }
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4606,26 +4876,40 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
                                         pixels, packing, "glTexSubImage2D");
    if (!pixels)
       return;
 
-   {
-      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");
-      }
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, yoffset, width, height,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+
+   if (dstMap) {
+      success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                               texImage->TexFormat,
+                               0, 0, 0,  /* dstX/Y/Zoffset */
+                               dstRowStride,
+                               &dstMap,
+                               width, height, 1,
+                               format, type, pixels, packing);
+
+      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
    }
+   else {
+      success = GL_FALSE;
+   }
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4644,6 +4928,12 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLboolean success = GL_TRUE;
+   GLint slice;
+   GLubyte **sliceMaps;
+   GLint dstRowStride;
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
                                         type, pixels, packing,
@@ -4651,22 +4941,43 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
    if (!pixels)
       return;
 
-   {
-      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");
+   sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
+
+   /* Map dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
+                                  xoffset, yoffset, width, height,
+                                  rwMode,
+                                  &sliceMaps[slice], &dstRowStride);
+      if (!sliceMaps[slice]) {
+         success = GL_FALSE;
+         break;
       }
    }
 
+   if (success) {
+      success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                               texImage->TexFormat,
+                               0, 0, 0,
+                               dstRowStride,
+                               sliceMaps,
+                               width, height, depth,
+                               format, type, pixels, packing);
+   }
+
+   /* Unmap dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      if (sliceMaps[slice]) {
+         ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
+      }
+   }
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
+
+   free(sliceMaps);
 }
 
 
@@ -4706,7 +5017,8 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
                                   struct gl_texture_object *texObj,
                                   struct gl_texture_image *texImage)
 {
-   (void) width; (void) height; (void) border;
+   GLubyte *dstMap;
+   GLint dstRowStride;
 
    /* This is pretty simple, basically just do a memcpy without worrying
     * about the usual image unpacking or image transfer operations.
@@ -4716,12 +5028,11 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
    ASSERT(texImage->Width > 0);
    ASSERT(texImage->Height > 0);
    ASSERT(texImage->Depth == 1);
-   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
 
-   /* allocate storage */
-   texImage->Data = _mesa_alloc_texmemory(imageSize);
-   if (!texImage->Data) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
+   /* allocate storage for texture data */
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
+                                            width, height, 1)) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
       return;
    }
 
@@ -4731,8 +5042,21 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
    if (!data)
       return;
 
-   /* copy the data */
-   memcpy(texImage->Data, data, imageSize);
+
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               0, 0, width, height,
+                               GL_MAP_WRITE_BIT,
+                               &dstMap, &dstRowStride);
+   if (dstMap) {
+      /* copy the data */
+      memcpy(dstMap, data, imageSize);
+
+      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+   }
+   else {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+   }
 
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
@@ -4801,19 +5125,15 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
                                      struct gl_texture_object *texObj,
                                      struct gl_texture_image *texImage)
 {
-   GLint bytesPerRow, destRowStride, srcRowStride;
+   GLint bytesPerRow, dstRowStride, srcRowStride;
    GLint i, rows;
-   GLubyte *dest;
+   GLubyte *dstMap;
    const GLubyte *src;
    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 % bw) == 0 || width == 2 || width == 1);
    ASSERT((height % bh) == 0 || height == 2 || height == 1);
@@ -4830,19 +5150,27 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
    srcRowStride = _mesa_format_row_stride(texFormat, width);
    src = (const GLubyte *) data;
 
-   destRowStride = _mesa_format_row_stride(texFormat, destWidth);
-   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
-                                         texFormat, destWidth,
-                                         (GLubyte *) texImage->Data);
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, yoffset, width, height,
+                               GL_MAP_WRITE_BIT,
+                               &dstMap, &dstRowStride);
 
-   bytesPerRow = srcRowStride;  /* bytes per row of blocks */
-   rows = height / bh;  /* rows in blocks */
+   if (dstMap) {
+      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);
-      dest += destRowStride;
-      src += srcRowStride;
+      /* copy rows of blocks */
+      for (i = 0; i < rows; i++) {
+         memcpy(dstMap, src, bytesPerRow);
+         dstMap += dstRowStride;
+         src += srcRowStride;
+      }
+
+      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+   }
+   else {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
    }
 
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);