In gl_texture_image, replace ImageStride with an ImageOffsets array.
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 20 May 2006 16:19:48 +0000 (16:19 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 20 May 2006 16:19:48 +0000 (16:19 +0000)
Some hardware lays out 3D mipmaps in a manner that can't be expressed
with a simple image stride.
The ImageOffsets array is allocated and initialized to typical defaults
in the _mesa_init_teximage_fields() function.  If needed, a driver will
then have to replace these offsets.
TexStore and TexelFetch routines updated to use offsets array.

src/mesa/drivers/dri/savage/savagetex.c
src/mesa/drivers/dri/tdfx/tdfx_tex.c
src/mesa/drivers/dri/unichrome/via_tex.c
src/mesa/main/mtypes.h
src/mesa/main/texcompress_fxt1.c
src/mesa/main/texcompress_s3tc.c
src/mesa/main/texformat_tmp.h
src/mesa/main/teximage.c
src/mesa/main/texstore.c
src/mesa/main/texstore.h

index b2802904bdadaefd702f6a542eb502baabbc945b..f0fe0c525947f31c57b4d1c7f0e8c432f9cf36d1 100644 (file)
@@ -525,80 +525,11 @@ savageAllocTexObj( struct gl_texture_object *texObj )
  * because we can't tell the hardware to ignore the color components
  * and only use the alpha component. So we define our own texture
  * formats that promote to ARGB8888 or ARGB4444 and set the color
- * components to white. This way we get the correct result. */
-static GLboolean
-_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
-                          GLenum baseInternalFormat,
-                          const struct gl_texture_format *dstFormat,
-                          GLvoid *dstAddr,
-                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                          GLint dstRowStride, GLint dstImageStride,
-                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcAddr,
-                          const struct gl_pixelstore_attrib *srcPacking);
-static GLboolean
-_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
-                          GLenum baseInternalFormat,
-                          const struct gl_texture_format *dstFormat,
-                          GLvoid *dstAddr,
-                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                          GLint dstRowStride, GLint dstImageStride,
-                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcAddr,
-                          const struct gl_pixelstore_attrib *srcPacking);
-
-static struct gl_texture_format _savage_texformat_a1114444 = {
-    MESA_FORMAT_ARGB4444,              /* MesaFormat */
-    GL_RGBA,                           /* BaseFormat */
-    GL_UNSIGNED_NORMALIZED_ARB,                /* DataType */
-    4,                                 /* RedBits */
-    4,                                 /* GreenBits */
-    4,                                 /* BlueBits */
-    4,                                 /* AlphaBits */
-    0,                                 /* LuminanceBits */
-    0,                                 /* IntensityBits */
-    0,                                 /* IndexBits */
-    0,                                 /* DepthBits */
-    0,                                 /* StencilBits */
-    2,                                 /* TexelBytes */
-    _savage_texstore_a1114444,         /* StoreTexImageFunc */
-    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
-                                        * savageDDInitTextureFuncs */
-};
-static struct gl_texture_format _savage_texformat_a1118888 = {
-    MESA_FORMAT_ARGB8888,              /* MesaFormat */
-    GL_RGBA,                           /* BaseFormat */
-    GL_UNSIGNED_NORMALIZED_ARB,                /* DataType */
-    8,                                 /* RedBits */
-    8,                                 /* GreenBits */
-    8,                                 /* BlueBits */
-    8,                                 /* AlphaBits */
-    0,                                 /* LuminanceBits */
-    0,                                 /* IntensityBits */
-    0,                                 /* IndexBits */
-    0,                                 /* DepthBits */
-    0,                                 /* StencilBits */
-    4,                                 /* TexelBytes */
-    _savage_texstore_a1118888,         /* StoreTexImageFunc */
-    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
-                                        * savageDDInitTextureFuncs */
-};
-
+ * components to white. This way we get the correct result.
+ */
 static GLboolean
-_savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
-                          GLenum baseInternalFormat,
-                          const struct gl_texture_format *dstFormat,
-                          GLvoid *dstAddr,
-                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                          GLint dstRowStride, GLint dstImageStride,
-                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcAddr,
-                          const struct gl_pixelstore_attrib *srcPacking)
+_savage_texstore_a1114444(TEXSTORE_PARAMS)
 {
-    /* general path */
     const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseInternalFormat,
@@ -606,10 +537,6 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
     const GLchan *src = tempImage;
-    GLubyte *dstImage = (GLubyte *) dstAddr
-       + dstZoffset * dstImageStride
-       + dstYoffset * dstRowStride
-       + dstXoffset * dstFormat->TexelBytes;
     GLint img, row, col;
 
     ASSERT(dstFormat == &_savage_texformat_a1114444);
@@ -619,7 +546,10 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
        return GL_FALSE;
     _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
     for (img = 0; img < srcDepth; img++) {
-       GLubyte *dstRow = dstImage;
+        GLubyte *dstRow = (GLubyte *) dstAddr
+           + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+           + dstYoffset * dstRowStride
+           + dstXoffset * dstFormat->TexelBytes;
        for (row = 0; row < srcHeight; row++) {
             GLushort *dstUI = (GLushort *) dstRow;
            for (col = 0; col < srcWidth; col++) {
@@ -629,25 +559,16 @@ _savage_texstore_a1114444 (GLcontext *ctx, GLuint dims,
             }
             dstRow += dstRowStride;
        }
-       dstImage += dstImageStride;
     }
     _mesa_free((void *) tempImage);
 
     return GL_TRUE;
 }
+
+
 static GLboolean
-_savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
-                          GLenum baseInternalFormat,
-                          const struct gl_texture_format *dstFormat,
-                          GLvoid *dstAddr,
-                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                          GLint dstRowStride, GLint dstImageStride,
-                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcAddr,
-                          const struct gl_pixelstore_attrib *srcPacking)
+_savage_texstore_a1118888(TEXSTORE_PARAMS)
 {
-    /* general path */
     const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
                                                  baseInternalFormat,
@@ -655,10 +576,6 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
     const GLchan *src = tempImage;
-    GLubyte *dstImage = (GLubyte *) dstAddr
-       + dstZoffset * dstImageStride
-       + dstYoffset * dstRowStride
-       + dstXoffset * dstFormat->TexelBytes;
     GLint img, row, col;
 
     ASSERT(dstFormat == &_savage_texformat_a1118888);
@@ -668,7 +585,10 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
        return GL_FALSE;
     _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
     for (img = 0; img < srcDepth; img++) {
-       GLubyte *dstRow = dstImage;
+        GLubyte *dstRow = (GLubyte *) dstAddr
+           + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+           + dstYoffset * dstRowStride
+           + dstXoffset * dstFormat->TexelBytes;
        for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
            for (col = 0; col < srcWidth; col++) {
@@ -678,13 +598,51 @@ _savage_texstore_a1118888 (GLcontext *ctx, GLuint dims,
             }
             dstRow += dstRowStride;
        }
-       dstImage += dstImageStride;
     }
     _mesa_free((void *) tempImage);
 
     return GL_TRUE;
 }
 
+
+static struct gl_texture_format _savage_texformat_a1114444 = {
+    MESA_FORMAT_ARGB4444,              /* MesaFormat */
+    GL_RGBA,                           /* BaseFormat */
+    GL_UNSIGNED_NORMALIZED_ARB,                /* DataType */
+    4,                                 /* RedBits */
+    4,                                 /* GreenBits */
+    4,                                 /* BlueBits */
+    4,                                 /* AlphaBits */
+    0,                                 /* LuminanceBits */
+    0,                                 /* IntensityBits */
+    0,                                 /* IndexBits */
+    0,                                 /* DepthBits */
+    0,                                 /* StencilBits */
+    2,                                 /* TexelBytes */
+    _savage_texstore_a1114444,         /* StoreTexImageFunc */
+    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
+                                        * savageDDInitTextureFuncs */
+};
+static struct gl_texture_format _savage_texformat_a1118888 = {
+    MESA_FORMAT_ARGB8888,              /* MesaFormat */
+    GL_RGBA,                           /* BaseFormat */
+    GL_UNSIGNED_NORMALIZED_ARB,                /* DataType */
+    8,                                 /* RedBits */
+    8,                                 /* GreenBits */
+    8,                                 /* BlueBits */
+    8,                                 /* AlphaBits */
+    0,                                 /* LuminanceBits */
+    0,                                 /* IntensityBits */
+    0,                                 /* IndexBits */
+    0,                                 /* DepthBits */
+    0,                                 /* StencilBits */
+    4,                                 /* TexelBytes */
+    _savage_texstore_a1118888,         /* StoreTexImageFunc */
+    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
+                                        * savageDDInitTextureFuncs */
+};
+
+
 /* Called by the _mesa_store_teximage[123]d() functions. */
 static const struct gl_texture_format *
 savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
index 0be6a823a38ca16f6abdfa3e89aa00156bb9747b..04ddfaad24bd01396f4b6cea582a752112ea4be2 100644 (file)
@@ -52,7 +52,7 @@
 
 
 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
-void
+static void
 _mesa_halve2x2_teximage2d ( GLcontext *ctx,
                            struct gl_texture_image *texImage,
                            GLuint bytesPerPixel,
@@ -65,6 +65,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
    GLint srcRowStride = srcWidth * bytesPerPixel;
    GLubyte *src = (GLubyte *)srcImage;
    GLubyte *dst = dstImage;
+   GLuint dstImageOffsets = 0;
 
    GLuint bpt = 0;
    GLubyte *_s = NULL;
@@ -96,7 +97,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
                               &_mesa_texformat_rgba8888_rev, src,
                               0, 0, 0, /* dstX/Y/Zoffset */
                               srcRowStride, /* dstRowStride */
-                              0, /* dstImageStride */
+                              &dstImageOffsets,
                               srcWidth, srcHeight, 1,
                               texImage->_BaseFormat, _t, srcImage, &ctx->DefaultPacking);
    }
@@ -143,7 +144,7 @@ _mesa_halve2x2_teximage2d ( GLcontext *ctx,
                                       texImage->TexFormat, dstImage,
                                       0, 0, 0, /* dstX/Y/Zoffset */
                                       dstWidth * bpt,
-                                      0, /* dstImageStride */
+                                      &dstImageOffsets,
                                       dstWidth, dstHeight, 1,
                                       GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);
       FREE(dst);
@@ -1177,6 +1178,7 @@ adjust2DRatio (GLcontext *ctx,
    const GLint newWidth = width * mml->wScale;
    const GLint newHeight = height * mml->hScale;
    GLvoid *tempImage;
+   GLuint dstImageOffsets = 0;
 
    if (!texImage->IsCompressed) {
       GLubyte *destAddr;
@@ -1189,7 +1191,7 @@ adjust2DRatio (GLcontext *ctx,
                                       texImage->TexFormat, tempImage,
                                       0, 0, 0, /* dstX/Y/Zoffset */
                                       width * texelBytes, /* dstRowStride */
-                                      0, /* dstImageStride */
+                                      &dstImageOffsets,
                                       width, height, 1,
                                       format, type, pixels, packing);
 
@@ -1221,7 +1223,7 @@ adjust2DRatio (GLcontext *ctx,
                               &_mesa_texformat_rgba8888_rev, rawImage,
                               0, 0, 0, /* dstX/Y/Zoffset */
                               width * rawBytes, /* dstRowStride */
-                              0, /* dstImageStride */
+                              &dstImageOffsets,
                               width, height, 1,
                               format, type, pixels, packing);
       _mesa_rescale_teximage2d(rawBytes,
@@ -1234,7 +1236,7 @@ adjust2DRatio (GLcontext *ctx,
                                       texImage->TexFormat, texImage->Data,
                                       xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */
                                       dstRowStride,
-                                      0, /* dstImageStride */
+                                      &dstImageOffsets,
                                       newWidth, newHeight, 1,
                                       GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking);
       FREE(rawImage);
@@ -1391,12 +1393,12 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
           /* no rescaling needed */
           /* unpack image, apply transfer ops and store in texImage->Data */
           texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                         texImage->TexFormat, texImage->Data,
-                                         0, 0, 0, /* dstX/Y/Zoffset */
-                                         dstRowStride,
-                                         0, /* dstImageStride */
-                                         width, height, 1,
-                                         format, type, pixels, packing);
+                                          texImage->TexFormat, texImage->Data,
+                                          0, 0, 0, /* dstX/Y/Zoffset */
+                                          dstRowStride,
+                                          texImage->ImageOffsets,
+                                          width, height, 1,
+                                          format, type, pixels, packing);
        }
 
       /* GL_SGIS_generate_mipmap */
@@ -1501,12 +1503,12 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
     else {
         /* no rescaling needed */
         texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                    texImage->TexFormat, texImage->Data,
-                                    xoffset, yoffset, 0,
-                                    dstRowStride,
-                                    0, /* dstImageStride */
-                                    width, height, 1,
-                                    format, type, pixels, packing);
+                                        texImage->TexFormat, texImage->Data,
+                                        xoffset, yoffset, 0,
+                                        dstRowStride,
+                                        texImage->ImageOffsets,
+                                        width, height, 1,
+                                        format, type, pixels, packing);
     }
 
    /* GL_SGIS_generate_mipmap */
index 0cbecd4146dd501cae9475deb4fc097d74eb51b4..b344c00931874c019b1e7cd8ca02d41ed7f414f8 100644 (file)
@@ -787,7 +787,7 @@ static void viaTexImage(GLcontext *ctx,
       return;
    }
    else {
-      GLint dstRowStride, dstImageStride = 0;
+      GLint dstRowStride;
       GLboolean success;
       if (texImage->IsCompressed) {
          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
@@ -801,7 +801,8 @@ static void viaTexImage(GLcontext *ctx,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, height, 1,
                                                 format, type, pixels, packing);
       if (!success) {
index 68dcd63fe3419848974e6c0d0c5bb6dd0a09cc18..e52e0bae5e53f7da05cdfa4287e18020449fba91 100644 (file)
@@ -1216,22 +1216,40 @@ typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage,
                                GLint col, GLint row, GLint img,
                                const void *texel);
 
+
 /**
- * TexImage store function.  This is called by the glTex[Sub]Image
- * functions and is responsible for converting the user-specified texture
- * image into a specific (hardware) image format.
+ * This macro defines the (many) parameters to the texstore functions.
+ * \param dims  either 1 or 2 or 3
+ * \param baseInternalFormat  user-specified base internal format
+ * \param dstFormat  destination Mesa texture format
+ * \param dstAddr  destination image address
+ * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
+ * \param dstRowStride  destination image row stride, in bytes
+ * \param dstImageOffsets  offset of each 2D slice within 3D texture, in texels
+ * \param srcWidth/Height/Depth  source image size, in pixels
+ * \param srcFormat  incoming image format
+ * \param srcType  incoming image data type
+ * \param srcAddr  source image address
+ * \param srcPacking  source image packing parameters
  */
-typedef GLboolean (*StoreTexImageFunc)(GLcontext *ctx, GLuint dims,
-                          GLenum baseInternalFormat,
-                          const struct gl_texture_format *dstFormat,
-                          GLvoid *dstAddr,
-                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                          GLint dstRowStride, GLint dstImageStride,
-                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcAddr,
-                          const struct gl_pixelstore_attrib *srcPacking);
+#define TEXSTORE_PARAMS \
+       GLcontext *ctx, GLuint dims, \
+       GLenum baseInternalFormat, \
+       const struct gl_texture_format *dstFormat, \
+       GLvoid *dstAddr, \
+       GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, \
+       GLint dstRowStride, const GLuint *dstImageOffsets, \
+       GLint srcWidth, GLint srcHeight, GLint srcDepth, \
+       GLenum srcFormat, GLenum srcType, \
+       const GLvoid *srcAddr, \
+       const struct gl_pixelstore_attrib *srcPacking
+
+
 
+/**
+ * Texture image storage function.
+ */
+typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
 
 
 /**
@@ -1277,6 +1295,8 @@ struct gl_texture_format
 };
 
 
+#define MAX_3D_TEXTURE_SIZE (1 << (MAX_3D_TEXTURE_LEVELS - 1))
+
 /**
  * Texture image state.  Describes the dimensions of a texture image,
  * the texel format and pointers to Texel Fetch functions.
@@ -1294,8 +1314,6 @@ struct gl_texture_image
    GLuint Width;               /**< = 2^WidthLog2 + 2*Border */
    GLuint Height;              /**< = 2^HeightLog2 + 2*Border */
    GLuint Depth;               /**< = 2^DepthLog2 + 2*Border */
-   GLuint RowStride;           /**< == Width unless IsClientData and padded */
-   GLuint ImageStride;          /**< Stride between images, in texels */
    GLuint Width2;              /**< = Width - 2*Border */
    GLuint Height2;             /**< = Height - 2*Border */
    GLuint Depth2;              /**< = Depth - 2*Border */
@@ -1306,7 +1324,6 @@ struct gl_texture_image
    GLfloat WidthScale;         /**< used for mipmap LOD computation */
    GLfloat HeightScale;                /**< used for mipmap LOD computation */
    GLfloat DepthScale;         /**< used for mipmap LOD computation */
-   GLvoid *Data;               /**< Image data, accessed via FetchTexel() */
    GLboolean IsClientData;     /**< Data owned by client? */
    GLboolean _IsPowerOfTwo;    /**< Are all dimensions powers of two? */
 
@@ -1320,6 +1337,11 @@ struct gl_texture_image
    GLboolean IsCompressed;     /**< GL_ARB_texture_compression */
    GLuint CompressedSize;      /**< GL_ARB_texture_compression */
 
+   GLuint RowStride;           /**< == Width unless IsClientData and padded */
+   GLuint *ImageOffsets;        /**< if 3D texture: array [Depth] of offsets to
+                                     each 2D slice in 'Data', in texels */
+   GLvoid *Data;               /**< Image data, accessed via FetchTexel() */
+
    /**
     * \name For device driver:
     */
index a3d5db93fc2af889475b65f2932ef6975e4c4494..18180e12eaf0e820778a3064f2a7680c6e3183ea 100644 (file)
@@ -64,7 +64,7 @@ _mesa_init_texture_fxt1( GLcontext *ctx )
  * Called via TexFormat->StoreImage to store an RGB_FXT1 texture.
  */
 static GLboolean
-texstore_rgb_fxt1(STORE_PARAMS)
+texstore_rgb_fxt1(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -76,7 +76,8 @@ texstore_rgb_fxt1(STORE_PARAMS)
    ASSERT(dstXoffset % 8 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset     == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGB ||
        srcType != CHAN_TYPE ||
@@ -120,7 +121,7 @@ texstore_rgb_fxt1(STORE_PARAMS)
  * Called via TexFormat->StoreImage to store an RGBA_FXT1 texture.
  */
 static GLboolean
-texstore_rgba_fxt1(STORE_PARAMS)
+texstore_rgba_fxt1(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -132,7 +133,8 @@ texstore_rgba_fxt1(STORE_PARAMS)
    ASSERT(dstXoffset % 8 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset     == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGBA ||
        srcType != CHAN_TYPE ||
index c572e19e49890464c18dcb830b6ff56206f60142..656a3d329c10d76ec13ddafaee4580bc5aae1325 100644 (file)
@@ -88,7 +88,7 @@ _mesa_init_texture_s3tc( GLcontext *ctx )
       dxtlibhandle = dlopen (DXTN_EXT, RTLD_LAZY | RTLD_GLOBAL);
       if (!dxtlibhandle) {
         _mesa_warning(ctx, "couldn't open " DXTN_EXT ", software DXTn "
-           "compression/decompression unavailable\n");
+           "compression/decompression unavailable");
       }
       else {
          /* the fetch functions are not per context! Might be problematic... */
@@ -109,7 +109,7 @@ _mesa_init_texture_s3tc( GLcontext *ctx )
          if (ext_tx_compress_dxtn == NULL) {
            _mesa_warning(ctx, "couldn't reference all symbols in "
               DXTN_EXT ", software DXTn compression/decompression "
-              "unavailable\n");
+              "unavailable");
             fetch_ext_rgb_dxt1 = NULL;
             fetch_ext_rgba_dxt1 = NULL;
             fetch_ext_rgba_dxt3 = NULL;
@@ -122,7 +122,7 @@ _mesa_init_texture_s3tc( GLcontext *ctx )
    }
    if (dxtlibhandle) {
       ctx->Mesa_DXTn = GL_TRUE;
-      _mesa_warning(ctx, "software DXTn compression/decompression available\n");
+      _mesa_warning(ctx, "software DXTn compression/decompression available");
    }
 #else
    (void) ctx;
@@ -133,7 +133,7 @@ _mesa_init_texture_s3tc( GLcontext *ctx )
  * Called via TexFormat->StoreImage to store an RGB_DXT1 texture.
  */
 static GLboolean
-texstore_rgb_dxt1(STORE_PARAMS)
+texstore_rgb_dxt1(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -145,7 +145,8 @@ texstore_rgb_dxt1(STORE_PARAMS)
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGB ||
        srcType != CHAN_TYPE ||
@@ -195,7 +196,7 @@ texstore_rgb_dxt1(STORE_PARAMS)
  * Called via TexFormat->StoreImage to store an RGBA_DXT1 texture.
  */
 static GLboolean
-texstore_rgba_dxt1(STORE_PARAMS)
+texstore_rgba_dxt1(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -207,7 +208,8 @@ texstore_rgba_dxt1(STORE_PARAMS)
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGBA ||
        srcType != CHAN_TYPE ||
@@ -256,7 +258,7 @@ texstore_rgba_dxt1(STORE_PARAMS)
  * Called via TexFormat->StoreImage to store an RGBA_DXT3 texture.
  */
 static GLboolean
-texstore_rgba_dxt3(STORE_PARAMS)
+texstore_rgba_dxt3(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -268,7 +270,8 @@ texstore_rgba_dxt3(STORE_PARAMS)
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGBA ||
        srcType != CHAN_TYPE ||
@@ -316,7 +319,7 @@ texstore_rgba_dxt3(STORE_PARAMS)
  * Called via TexFormat->StoreImage to store an RGBA_DXT5 texture.
  */
 static GLboolean
-texstore_rgba_dxt5(STORE_PARAMS)
+texstore_rgba_dxt5(TEXSTORE_PARAMS)
 {
    const GLchan *pixels;
    GLint srcRowStride;
@@ -328,7 +331,8 @@ texstore_rgba_dxt5(STORE_PARAMS)
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
-   (void) dstZoffset; (void) dstImageStride;
+   (void) dstZoffset;
+   (void) dstImageOffsets;
 
    if (srcFormat != GL_RGBA ||
        srcType != CHAN_TYPE ||
index 1c41278059483f818278d1c300b7f900dc884d04..186fe23514cd91cc9f43a6d485347b95f6adc52c 100644 (file)
@@ -59,8 +59,8 @@
 #elif DIM == 3
 
 #define TEXEL_ADDR( type, image, i, j, k, size )                       \
-       ((type *)(image)->Data + (((image)->Height * (k) + (j)) *       \
-         (image)->RowStride + (i)) * (size))
+       ((type *)(image)->Data + ((image)->ImageOffsets[k]              \
+             + (image)->RowStride * (j) + (i)) * (size))
 
 #define FETCH(x) fetch_texel_3d_##x
 
index 91a96e871b063a043e8239160a76551764327e4c..02d2aa362cbcfaaa20c28b733e87b0b1edfa724b 100644 (file)
@@ -662,7 +662,9 @@ _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
       ctx->Driver.FreeTexImageData( ctx, texImage );
    }
    ASSERT(texImage->Data == NULL);
-   FREE( texImage );
+   if (texImage->ImageOffsets)
+      _mesa_free(texImage->ImageOffsets);
+   _mesa_free(texImage);
 }
 
 
@@ -1050,7 +1052,10 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->Height = 0;
    img->Depth = 0;
    img->RowStride = 0;
-   img->ImageStride = 0;
+   if (img->ImageOffsets) {
+      _mesa_free(img->ImageOffsets);
+      img->ImageOffsets = NULL;
+   }
    img->Width2 = 0;
    img->Height2 = 0;
    img->Depth2 = 0;
@@ -1070,7 +1075,7 @@ clear_teximage_fields(struct gl_texture_image *img)
  * Initialize basic fields of the gl_texture_image struct.
  *
  * \param ctx GL context.
- * \param target texture target.
+ * \param target texture target (GL_TEXTURE_1D, GL_TEXTURE_RECTANGLE, etc).
  * \param img texture image structure to be initialized.
  * \param width image width.
  * \param height image height.
@@ -1087,7 +1092,13 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
                            GLsizei width, GLsizei height, GLsizei depth,
                            GLint border, GLenum internalFormat)
 {
+   GLint i;
+
    ASSERT(img);
+   ASSERT(width > 0);
+   ASSERT(height > 0);
+   ASSERT(depth > 0);
+
    img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
    ASSERT(img->_BaseFormat > 0);
    img->InternalFormat = internalFormat;
@@ -1095,8 +1106,6 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
    img->Width = width;
    img->Height = height;
    img->Depth = depth;
-   img->RowStride = width;
-   img->ImageStride = width * height;
    img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
    img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
    img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
@@ -1120,6 +1129,17 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
    else
       img->_IsPowerOfTwo = GL_FALSE;
 
+   /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
+   img->RowStride = width;
+   /* Allocate the ImageOffsets array and initialize to typical values.
+    * We allocate the array for 1D/2D textures too in order to avoid special-
+    * case code in the texstore routines.
+    */
+   img->ImageOffsets = (GLuint *) _mesa_malloc(depth * sizeof(GLuint));
+   for (i = 0; i < depth; i++) {
+      img->ImageOffsets[i] = i * width * height;
+   }
+
    /* Compute Width/Height/DepthScale for mipmap lod computation */
    if (target == GL_TEXTURE_RECTANGLE_NV) {
       /* scale = 1.0 since texture coords directly map to texels */
index 4868b806ea7aa8b2d669aefaea73afd7e235f21e..28f6a191fdb834b65b284e3b76d5b6c1f0cb8cd6 100644 (file)
@@ -611,7 +611,8 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx,
 
                          GLvoid *dstAddr,
                          GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                         GLint dstRowStride, GLint dstImageStride,
+                         GLint dstRowStride,
+                          const GLuint *dstImageOffsets,
 
                          GLint srcWidth, GLint srcHeight, GLint srcDepth,
                          const GLvoid *srcAddr,
@@ -632,11 +633,6 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx,
                                               srcWidth, srcHeight, srcFormat,
                                               GL_UNSIGNED_BYTE, 0, 0, 0);
 
-   GLubyte *dstImage = (GLubyte *) dstAddr
-                     + dstZoffset * dstImageStride
-                     + dstYoffset * dstRowStride
-                     + dstXoffset * dstComponents;
-
    (void) ctx;
 
    compute_component_mapping(srcFormat, GL_RGBA, srcmap);
@@ -645,23 +641,28 @@ _mesa_swizzle_ubyte_image(GLcontext *ctx,
       map[i] = srcmap[dstmap[i]];
 
    if (srcRowStride == srcWidth * srcComponents &&
-       (srcImageStride == srcWidth * srcHeight * srcComponents ||
-        srcDepth == 1)) {
+       dimensions < 3) {
+      /* 1 and 2D images only */
+      GLubyte *dstImage = (GLubyte *) dstAddr
+         + dstYoffset * dstRowStride
+         + dstXoffset * dstComponents;
       swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 
-                  srcWidth * srcHeight * srcDepth);
+                  srcWidth * srcHeight);
    }
    else {
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          const GLubyte *srcRow = srcImage;
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstComponents
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstComponents;
          for (row = 0; row < srcHeight; row++) {
            swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
          srcImage += srcImageStride;
-         dstImage += dstImageStride;
       }
    }
 }
@@ -678,7 +679,8 @@ memcpy_texture(GLcontext *ctx,
                const struct gl_texture_format *dstFormat,
                GLvoid *dstAddr,
                GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-               GLint dstRowStride, GLint dstImageStride,
+               GLint dstRowStride,
+               const GLuint *dstImageOffsets,
                GLint srcWidth, GLint srcHeight, GLint srcDepth,
                GLenum srcFormat, GLenum srcType,
                const GLvoid *srcAddr,
@@ -691,6 +693,9 @@ memcpy_texture(GLcontext *ctx,
    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
    const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
+
+#if 0
+   /* XXX update/re-enable for dstImageOffsets array */
    const GLint bytesPerImage = srcHeight * bytesPerRow;
    const GLint bytesPerTexture = srcDepth * bytesPerImage;
    GLubyte *dstImage = (GLubyte *) dstAddr
@@ -706,7 +711,8 @@ memcpy_texture(GLcontext *ctx,
       /* one big memcpy */
       ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
    }
-   else {
+   else
+   {
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          const GLubyte *srcRow = srcImage;
@@ -720,6 +726,22 @@ memcpy_texture(GLcontext *ctx,
          dstImage += dstImageStride;
       }
    }
+#endif
+
+   GLint img, row;
+   for (img = 0; img < srcDepth; img++) {
+      const GLubyte *srcRow = srcImage;
+      GLubyte *dstRow = (GLubyte *) dstAddr
+         + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+         + dstYoffset * dstRowStride
+         + dstXoffset * dstFormat->TexelBytes;
+      for (row = 0; row < srcHeight; row++) {
+         ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
+         dstRow += dstRowStride;
+         srcRow += srcRowStride;
+      }
+      srcImage += srcImageStride;
+   }
 }
 
 
@@ -733,30 +755,9 @@ memcpy_texture(GLcontext *ctx,
  *   _mesa_texformat_luminance_alpha
  *   _mesa_texformat_intensity
  * 
- * \param dims  either 1 or 2 or 3
- * \param baseInternalFormat  user-specified base internal format
- * \param dstFormat  destination Mesa texture format
- * \param dstAddr  destination image address
- * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
- * \param dstRowStride  destination image row stride, in bytes
- * \param dstImageStride  destination image layer stride, in bytes
- * \param srcWidth/Height/Depth  source image size, in pixels
- * \param srcFormat  incoming image format
- * \param srcType  incoming image data type
- * \param srcAddr  source image address
- * \param srcPacking  source image packing parameters
  */
 GLboolean
-_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
-                    GLenum baseInternalFormat,
-                    const struct gl_texture_format *dstFormat,
-                    GLvoid *dstAddr,
-                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
-                    GLint dstRowStride, GLint dstImageStride,
-                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                    GLenum srcFormat, GLenum srcType,
-                    const GLvoid *srcAddr,
-                    const struct gl_pixelstore_attrib *srcPacking)
+_mesa_texstore_rgba(TEXSTORE_PARAMS)
 {
    const GLint components = _mesa_components_in_format(baseInternalFormat);
 
@@ -781,7 +782,8 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -791,12 +793,14 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
             srcFormat == GL_RGBA &&
             srcType == CHAN_TYPE) {
       /* extract RGB from RGBA */
-      int img, row, col;
-      GLchan *dstImage = (GLchan *) ((GLubyte *) dstAddr
-                                     + dstZoffset * dstImageStride
-                                     + dstYoffset * dstRowStride
-                                     + dstXoffset * dstFormat->TexelBytes);
+      GLint img, row, col;
       for (img = 0; img < srcDepth; img++) {
+         GLchan *dstImage = (GLchan *)
+            ((GLubyte *) dstAddr
+             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+             + dstYoffset * dstRowStride
+             + dstXoffset * dstFormat->TexelBytes);
+
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
          GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
@@ -811,7 +815,6 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
             dstRow += dstRowStride / sizeof(GLchan);
             srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
          }
-         dstImage += dstImageStride / sizeof(GLchan);
       }
    }
    else {
@@ -824,23 +827,21 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
                                                  srcPacking);
       const GLchan *src = tempImage;
       GLint bytesPerRow;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       bytesPerRow = srcWidth * components * sizeof(GLchan);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             _mesa_memcpy(dstRow, src, bytesPerRow);
             dstRow += dstRowStride;
             src += srcWidth * components;
          }
-         dstImage += dstImageStride;
       }
 
       _mesa_free((void *) tempImage);
@@ -853,7 +854,7 @@ _mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
  * Store a 32-bit integer depth component texture image.
  */
 GLboolean
-_mesa_texstore_z32(STORE_PARAMS)
+_mesa_texstore_z32(TEXSTORE_PARAMS)
 {
    const GLfloat depthScale = (GLfloat) 0xffffffff;
    (void) dims;
@@ -868,19 +869,19 @@ _mesa_texstore_z32(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -889,18 +890,18 @@ _mesa_texstore_z32(STORE_PARAMS)
                                     depthScale, srcType, src, srcPacking);
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    return GL_TRUE;
 }
 
+#define STRIDE_3D 0
 
 /**
  * Store a 16-bit integer depth component texture image.
  */
 GLboolean
-_mesa_texstore_z16(STORE_PARAMS)
+_mesa_texstore_z16(TEXSTORE_PARAMS)
 {
    const GLfloat depthScale = 65535.0f;
    (void) dims;
@@ -915,19 +916,19 @@ _mesa_texstore_z16(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -937,7 +938,6 @@ _mesa_texstore_z16(STORE_PARAMS)
                                     srcType, src, srcPacking);
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    return GL_TRUE;
@@ -948,7 +948,7 @@ _mesa_texstore_z16(STORE_PARAMS)
  * Store an rgb565 or rgb565_rev texture image.
  */
 GLboolean
-_mesa_texstore_rgb565(STORE_PARAMS)
+_mesa_texstore_rgb565(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
           dstFormat == &_mesa_texformat_rgb565_rev);
@@ -963,7 +963,8 @@ _mesa_texstore_rgb565(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -980,7 +981,6 @@ _mesa_texstore_rgb565(STORE_PARAMS)
          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
                              srcFormat, srcType, 0, 0, 0);
       GLubyte *dst = (GLubyte *) dstAddr
-                   + dstZoffset * dstImageStride
                    + dstYoffset * dstRowStride
                    + dstXoffset * dstFormat->TexelBytes;
       GLint row, col;
@@ -1013,16 +1013,15 @@ _mesa_texstore_rgb565(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             /* check for byteswapped format */
@@ -1044,7 +1043,6 @@ _mesa_texstore_rgb565(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1053,7 +1051,7 @@ _mesa_texstore_rgb565(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_rgba8888(STORE_PARAMS)
+_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1072,11 +1070,13 @@ _mesa_texstore_rgba8888(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
 #if 0
+   /* broken? */
    else if (!ctx->_ImageTransferState &&
            !srcPacking->SwapBytes &&
            srcType == GL_UNSIGNED_BYTE && 
@@ -1118,16 +1118,15 @@ _mesa_texstore_rgba8888(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
             if (dstFormat == &_mesa_texformat_rgba8888) {
@@ -1150,7 +1149,6 @@ _mesa_texstore_rgba8888(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1159,7 +1157,7 @@ _mesa_texstore_rgba8888(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_argb8888(STORE_PARAMS)
+_mesa_texstore_argb8888(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1178,7 +1176,8 @@ _mesa_texstore_argb8888(STORE_PARAMS)
       /* simple memcpy path (little endian) */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1192,7 +1191,8 @@ _mesa_texstore_argb8888(STORE_PARAMS)
       /* simple memcpy path (big endian) */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1203,16 +1203,15 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             srcType == GL_UNSIGNED_BYTE) {
 
       int img, row, col;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       for (img = 0; img < srcDepth; img++) {
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
@@ -1223,7 +1222,6 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    else if (!ctx->_ImageTransferState &&
@@ -1231,13 +1229,7 @@ _mesa_texstore_argb8888(STORE_PARAMS)
            dstFormat == &_mesa_texformat_argb8888 &&
             srcFormat == GL_RGBA &&
             (srcType == GL_UNSIGNED_BYTE && littleEndian)) {
-
-      int img, row, col;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
-
+      GLint img, row, col;
       /* For some reason, streaming copies to write-combined regions
        * are extremely sensitive to the characteristics of how the
        * source data is retrieved.  By reordering the source reads to
@@ -1249,7 +1241,11 @@ _mesa_texstore_argb8888(STORE_PARAMS)
                                                  srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
+
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                *(GLuint *)(dstRow + col * 4)  = (srcRow[col * 4 + RCOMP] << 16 |
@@ -1260,7 +1256,6 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    else if (!ctx->_ImageTransferState &&
@@ -1269,17 +1264,16 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             srcFormat == GL_RGBA &&
             srcType == GL_UNSIGNED_BYTE) {
 
-      int img, row, col;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
+      GLint img, row, col;
       for (img = 0; img < srcDepth; img++) {
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
@@ -1290,7 +1284,6 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    else if (!ctx->_ImageTransferState &&
@@ -1319,7 +1312,8 @@ _mesa_texstore_argb8888(STORE_PARAMS)
                                srcFormat,
                                dstmap, 4,
                                dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                               dstRowStride, dstImageStride,
+                               dstRowStride,
+                                dstImageOffsets,
                                srcWidth, srcHeight, srcDepth, srcAddr,
                                srcPacking);      
    }
@@ -1332,16 +1326,15 @@ _mesa_texstore_argb8888(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
             if (dstFormat == &_mesa_texformat_argb8888) {
@@ -1364,7 +1357,6 @@ _mesa_texstore_argb8888(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1373,7 +1365,7 @@ _mesa_texstore_argb8888(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_rgb888(STORE_PARAMS)
+_mesa_texstore_rgb888(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1390,7 +1382,8 @@ _mesa_texstore_rgb888(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1399,17 +1392,16 @@ _mesa_texstore_rgb888(STORE_PARAMS)
             srcFormat == GL_RGBA &&
             srcType == GL_UNSIGNED_BYTE) {
       /* extract RGB from RGBA */
-      int img, row, col;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
+      GLint img, row, col;
       for (img = 0; img < srcDepth; img++) {
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
@@ -1419,7 +1411,6 @@ _mesa_texstore_rgb888(STORE_PARAMS)
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    else {
@@ -1431,16 +1422,15 @@ _mesa_texstore_rgb888(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = (const GLchan *) tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
 #if 0
             if (littleEndian) {
@@ -1469,7 +1459,6 @@ _mesa_texstore_rgb888(STORE_PARAMS)
 #endif
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1478,7 +1467,7 @@ _mesa_texstore_rgb888(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_bgr888(STORE_PARAMS)
+_mesa_texstore_bgr888(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1495,7 +1484,8 @@ _mesa_texstore_bgr888(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1505,16 +1495,15 @@ _mesa_texstore_bgr888(STORE_PARAMS)
             srcType == GL_UNSIGNED_BYTE) {
       /* extract BGR from RGBA */
       int img, row, col;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       for (img = 0; img < srcDepth; img++) {
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
@@ -1524,7 +1513,6 @@ _mesa_texstore_bgr888(STORE_PARAMS)
             dstRow += dstRowStride;
             srcRow += srcRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    else {
@@ -1536,16 +1524,15 @@ _mesa_texstore_bgr888(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = (const GLchan *) tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
@@ -1555,7 +1542,6 @@ _mesa_texstore_bgr888(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1564,7 +1550,7 @@ _mesa_texstore_bgr888(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_argb4444(STORE_PARAMS)
+_mesa_texstore_argb4444(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
           dstFormat == &_mesa_texformat_argb4444_rev);
@@ -1579,7 +1565,8 @@ _mesa_texstore_argb4444(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1592,16 +1579,15 @@ _mesa_texstore_argb4444(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_argb4444) {
@@ -1624,7 +1610,6 @@ _mesa_texstore_argb4444(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1634,7 +1619,7 @@ _mesa_texstore_argb4444(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_argb1555(STORE_PARAMS)
+_mesa_texstore_argb1555(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
           dstFormat == &_mesa_texformat_argb1555_rev);
@@ -1649,7 +1634,8 @@ _mesa_texstore_argb1555(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1662,16 +1648,15 @@ _mesa_texstore_argb1555(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src =tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_argb1555) {
@@ -1694,7 +1679,6 @@ _mesa_texstore_argb1555(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1703,7 +1687,7 @@ _mesa_texstore_argb1555(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_al88(STORE_PARAMS)
+_mesa_texstore_al88(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1722,7 +1706,8 @@ _mesa_texstore_al88(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1735,16 +1720,15 @@ _mesa_texstore_al88(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_al88) {
@@ -1765,7 +1749,6 @@ _mesa_texstore_al88(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1774,7 +1757,7 @@ _mesa_texstore_al88(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_rgb332(STORE_PARAMS)
+_mesa_texstore_rgb332(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_rgb332);
    ASSERT(dstFormat->TexelBytes == 1);
@@ -1786,7 +1769,8 @@ _mesa_texstore_rgb332(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1799,16 +1783,15 @@ _mesa_texstore_rgb332(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
@@ -1818,7 +1801,6 @@ _mesa_texstore_rgb332(STORE_PARAMS)
             }
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1830,7 +1812,7 @@ _mesa_texstore_rgb332(STORE_PARAMS)
  * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
  */
 GLboolean
-_mesa_texstore_a8(STORE_PARAMS)
+_mesa_texstore_a8(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_a8 ||
           dstFormat == &_mesa_texformat_l8 ||
@@ -1844,7 +1826,8 @@ _mesa_texstore_a8(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -1857,16 +1840,15 @@ _mesa_texstore_a8(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLchan *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row, col;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col] = CHAN_TO_UBYTE(src[col]);
@@ -1874,7 +1856,6 @@ _mesa_texstore_a8(STORE_PARAMS)
             dstRow += dstRowStride;
             src += srcWidth;
          }
-         dstImage += dstImageStride;
       }
       _mesa_free((void *) tempImage);
    }
@@ -1884,7 +1865,7 @@ _mesa_texstore_a8(STORE_PARAMS)
 
 
 GLboolean
-_mesa_texstore_ci8(STORE_PARAMS)
+_mesa_texstore_ci8(TEXSTORE_PARAMS)
 {
    (void) dims; (void) baseInternalFormat;
    ASSERT(dstFormat == &_mesa_texformat_ci8);
@@ -1898,19 +1879,19 @@ _mesa_texstore_ci8(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
    else {
       /* general path */
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -1919,7 +1900,6 @@ _mesa_texstore_ci8(STORE_PARAMS)
                                     ctx->_ImageTransferState);
             dstRow += dstRowStride;
          }
-         dstImage += dstImageStride;
       }
    }
    return GL_TRUE;
@@ -1930,7 +1910,7 @@ _mesa_texstore_ci8(STORE_PARAMS)
  * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
  */
 GLboolean
-_mesa_texstore_ycbcr(STORE_PARAMS)
+_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 {
    const GLuint ui = 1;
    const GLubyte littleEndian = *((const GLubyte *) &ui);
@@ -1948,7 +1928,8 @@ _mesa_texstore_ycbcr(STORE_PARAMS)
    /* always just memcpy since no pixel transfer ops apply */
    memcpy_texture(ctx, dims,
                   dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                  dstRowStride, dstImageStride,
+                  dstRowStride,
+                  dstImageOffsets,
                   srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                   srcAddr, srcPacking);
 
@@ -1958,18 +1939,16 @@ _mesa_texstore_ycbcr(STORE_PARAMS)
        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
        (dstFormat == &_mesa_texformat_ycbcr_rev) ^
        !littleEndian) {
-      GLubyte *pImage = (GLubyte *) dstAddr
-                      + dstZoffset * dstImageStride
-                      + dstYoffset * dstRowStride
-                      + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *pRow = pImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
-            _mesa_swap2((GLushort *) pRow, srcWidth);
-            pRow += dstRowStride;
+            _mesa_swap2((GLushort *) dstRow, srcWidth);
+            dstRow += dstRowStride;
          }
-         pImage += dstImageStride;
       }
    }
    return GL_TRUE;
@@ -1981,7 +1960,7 @@ _mesa_texstore_ycbcr(STORE_PARAMS)
  * Store a combined depth/stencil texture image.
  */
 GLboolean
-_mesa_texstore_z24_s8(STORE_PARAMS)
+_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
    ASSERT(dstFormat == &_mesa_texformat_z24_s8);
    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
@@ -1992,7 +1971,8 @@ _mesa_texstore_z24_s8(STORE_PARAMS)
       /* simple path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2001,11 +1981,13 @@ _mesa_texstore_z24_s8(STORE_PARAMS)
       const GLint srcRowStride
          = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
          / sizeof(GLuint);
-      GLuint *dstImage = (GLuint *) dstAddr;
       GLint img, row;
 
       for (img = 0; img < srcDepth; img++) {
-         GLuint *dst = dstImage;
+         GLuint *dstRow = (GLuint *) dstAddr
+            + dstImageOffsets[dstZoffset + img]
+            + dstYoffset * dstRowStride / sizeof(GLuint)
+            + dstXoffset;
          const GLuint *src
             = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
                                                    srcWidth, srcHeight,
@@ -2017,7 +1999,7 @@ _mesa_texstore_z24_s8(STORE_PARAMS)
             /* the 24 depth bits will be in the high position: */
             _mesa_unpack_depth_span(ctx, srcWidth,
                                     GL_UNSIGNED_INT, /* dst type */
-                                    dst, /* dst addr */
+                                    dstRow, /* dst addr */
                                     (GLfloat) 0xffffff, /* depthScale */
                                     srcType, src, srcPacking);
             /* get the 8-bit stencil values */
@@ -2028,16 +2010,13 @@ _mesa_texstore_z24_s8(STORE_PARAMS)
                                       ctx->_ImageTransferState);
             /* merge stencil values into depth values */
             for (i = 0; i < srcWidth; i++)
-               dst[i] |= stencil[i];
+               dstRow[i] |= stencil[i];
 
             src += srcRowStride;
-            dst += dstRowStride / sizeof(GLuint);
+            dstRow += dstRowStride / sizeof(GLuint);
          }
-         dstImage += dstImageStride / sizeof(GLuint);
       }
    }
-
-
    return GL_TRUE;
 }
 
@@ -2053,7 +2032,7 @@ _mesa_texstore_z24_s8(STORE_PARAMS)
  *   _mesa_texformat_intensity_float32
  */
 GLboolean
-_mesa_texstore_rgba_float32(STORE_PARAMS)
+_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
 {
    const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
 
@@ -2078,7 +2057,8 @@ _mesa_texstore_rgba_float32(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2090,25 +2070,23 @@ _mesa_texstore_rgba_float32(STORE_PARAMS)
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
-      const GLfloat *src = tempImage;
+      const GLfloat *srcRow = tempImage;
       GLint bytesPerRow;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       bytesPerRow = srcWidth * components * sizeof(GLfloat);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dst = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
-            _mesa_memcpy(dst, src, bytesPerRow);
-            dst += dstRowStride;
-            src += srcWidth * components;
+            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
+            dstRow += dstRowStride;
+            srcRow += srcWidth * components;
          }
-         dstImage += dstImageStride;
       }
 
       _mesa_free((void *) tempImage);
@@ -2121,7 +2099,7 @@ _mesa_texstore_rgba_float32(STORE_PARAMS)
  * As above, but store 16-bit floats.
  */
 GLboolean
-_mesa_texstore_rgba_float16(STORE_PARAMS)
+_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
 {
    const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
 
@@ -2146,7 +2124,8 @@ _mesa_texstore_rgba_float16(STORE_PARAMS)
       /* simple memcpy path */
       memcpy_texture(ctx, dims,
                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
-                     dstRowStride, dstImageStride,
+                     dstRowStride,
+                     dstImageOffsets,
                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
                      srcAddr, srcPacking);
    }
@@ -2159,16 +2138,15 @@ _mesa_texstore_rgba_float16(STORE_PARAMS)
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
       const GLfloat *src = tempImage;
-      GLubyte *dstImage = (GLubyte *) dstAddr
-                        + dstZoffset * dstImageStride
-                        + dstYoffset * dstRowStride
-                        + dstXoffset * dstFormat->TexelBytes;
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
-         GLubyte *dstRow = dstImage;
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * dstFormat->TexelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
             GLint i;
@@ -2178,7 +2156,6 @@ _mesa_texstore_rgba_float16(STORE_PARAMS)
             dstRow += dstRowStride;
             src += srcWidth * components;
          }
-         dstImage += dstImageStride;
       }
 
       _mesa_free((void *) tempImage);
@@ -2454,14 +2431,15 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
    else {
-      const GLint dstRowStride = 0, dstImageStride = 0;
+      const GLint dstRowStride = 0;
       GLboolean success;
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, 1, 1,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2483,16 +2461,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
 /**
  * This is the software fallback for Driver.TexImage2D()
  * and Driver.CopyTexImage2D().
- * We store the image in heap memory.  We know nothing about on-board
- * VRAM here.  But since most DRI drivers rely on keeping a copy of all
- * textures in main memory, this routine will typically be used by
- * hardware drivers too.
  *
- * Reasons why a driver might override this function:
- *  - Special memory allocation needs (VRAM, AGP, etc)
- *  - Unusual row/image strides or padding
- *  - Special housekeeping
- *  - Using VRAM-based Pixel Buffer Objects
+ * This function is oriented toward storing images in main memory, rather
+ * than VRAM.  Device driver's can easily plug in their own replacement.
+ *
+ * Note: width and height may be pre-convolved dimensions, but
+ * texImage->Width and texImage->Height will be post-convolved dimensions.
  */
 void
 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
@@ -2536,21 +2510,22 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
    else {
-      GLint dstRowStride, dstImageStride = 0;
+      GLint dstRowStride;
       GLboolean success;
       if (texImage->IsCompressed) {
          dstRowStride
             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
       }
       else {
-         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
+         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
       }
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, height, 1,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2611,23 +2586,22 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
       return;
    }
    else {
-      GLint dstRowStride, dstImageStride;
+      GLint dstRowStride;
       GLboolean success;
       if (texImage->IsCompressed) {
          dstRowStride
             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
-         dstImageStride = 0;
       }
       else {
-         dstRowStride = width * texImage->TexFormat->TexelBytes;
-         dstImageStride = dstRowStride * height;
+         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
       }
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, height, depth,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2660,20 +2634,22 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   /* 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, dstImageStride = 0;
+      const GLint dstRowStride = 0;
       GLboolean success;
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 xoffset, 0, 0,  /* offsets */
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, 1, 1,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2706,27 +2682,29 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   /* 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 = 0, dstImageStride = 0;
+      GLint dstRowStride = 0;
       GLboolean success;
       if (texImage->IsCompressed) {
          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
                                                     texImage->Width);
       }
       else {
-         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
       }
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 xoffset, yoffset, 0,
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, height, 1,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2758,6 +2736,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   /* 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,
                                         "glTexSubImage3D");
@@ -2765,23 +2744,22 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
       return;
 
    {
-      GLint dstRowStride, dstImageStride;
+      GLint dstRowStride;
       GLboolean success;
       if (texImage->IsCompressed) {
          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
                                                     texImage->Width);
-         dstImageStride = 0; /* XXX fix */
       }
       else {
-         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
-         dstImageStride = dstRowStride * texImage->Height;
+         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
       }
       ASSERT(texImage->TexFormat->StoreImage);
       success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
                                                 texImage->TexFormat,
                                                 texImage->Data,
                                                 xoffset, yoffset, zoffset,
-                                                dstRowStride, dstImageStride,
+                                                dstRowStride,
+                                                texImage->ImageOffsets,
                                                 width, height, depth,
                                                 format, type, pixels, packing);
       if (!success) {
@@ -2823,7 +2801,7 @@ _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
 
 
 
-/*
+/**
  * Fallback for Driver.CompressedTexImage2D()
  */
 void
@@ -2952,6 +2930,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    ASSERT((xoffset & 3) == 0);
    ASSERT((yoffset & 3) == 0);
 
+   /* get pointer to src pixels (may be in a pbo which we'll map here) */
    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
                                                  &ctx->Unpack,
                                                  "glCompressedTexSubImage2D");
@@ -3495,6 +3474,9 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border,
 }
 
 
+/**
+ * XXX need to use the tex image's row stride!
+ */
 static void
 make_2d_mipmap(const struct gl_texture_format *format, GLint border,
                GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
index 7fef20d7b8d10593a5ba4e7509bcc54cb7a6b5d2..3f5b7b0145cbdb0155bc4410fb0884ffa47f88da 100644 (file)
 
 #include "mtypes.h"
 
-/* Macro just to save some typing */
-#define STORE_PARAMS \
-       GLcontext *ctx, GLuint dims, \
-       GLenum baseInternalFormat, \
-       const struct gl_texture_format *dstFormat, \
-       GLvoid *dstAddr, \
-       GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, \
-       GLint dstRowStride, GLint dstImageStride, \
-       GLint srcWidth, GLint srcHeight, GLint srcDepth, \
-       GLenum srcFormat, GLenum srcType, \
-       const GLvoid *srcAddr, \
-       const struct gl_pixelstore_attrib *srcPacking
-
-
-extern GLboolean _mesa_texstore_rgba(STORE_PARAMS);
-extern GLboolean _mesa_texstore_color_index(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba8888(STORE_PARAMS);
-extern GLboolean _mesa_texstore_argb8888(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb888(STORE_PARAMS);
-extern GLboolean _mesa_texstore_bgr888(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb565(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb565_rev(STORE_PARAMS);
-extern GLboolean _mesa_texstore_argb4444(STORE_PARAMS);
-extern GLboolean _mesa_texstore_argb4444_rev(STORE_PARAMS);
-extern GLboolean _mesa_texstore_argb1555(STORE_PARAMS);
-extern GLboolean _mesa_texstore_argb1555_rev(STORE_PARAMS);
-extern GLboolean _mesa_texstore_al88(STORE_PARAMS);
-extern GLboolean _mesa_texstore_al88_rev(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb332(STORE_PARAMS);
-extern GLboolean _mesa_texstore_a8(STORE_PARAMS);
-extern GLboolean _mesa_texstore_ci8(STORE_PARAMS);
-extern GLboolean _mesa_texstore_ycbcr(STORE_PARAMS);
-extern GLboolean _mesa_texstore_z24_s8(STORE_PARAMS);
-extern GLboolean _mesa_texstore_z16(STORE_PARAMS);
-extern GLboolean _mesa_texstore_z32(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_float32(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_float16(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb_fxt1(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_fxt1(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgb_dxt1(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_dxt1(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_dxt3(STORE_PARAMS);
-extern GLboolean _mesa_texstore_rgba_dxt5(STORE_PARAMS);
+
+extern GLboolean _mesa_texstore_rgba(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_color_index(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba8888(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_argb8888(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb888(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_bgr888(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb565(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb565_rev(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_argb4444(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_argb4444_rev(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_argb1555(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_argb1555_rev(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_al88(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_al88_rev(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb332(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_a8(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_ci8(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_ycbcr(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_z24_s8(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_z16(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_z32(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_float32(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_float16(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb_fxt1(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_fxt1(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS);
+extern GLboolean _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS);
 
 
 extern GLchan *