mesa: sort texstore_funcs[] array, remove search loop
[mesa.git] / src / mesa / main / texstore.c
index 8afb947fa1772d4c77b4952a8e138ae1cfba1947..d47f71d0e2153799909ffd55070b151ccf60c657 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.3
+ * Version:  7.5
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- * Copyright (c) 2008 VMware, Inc.
+ * Copyright (c) 2008-2009  VMware, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "bufferobj.h"
 #include "colormac.h"
 #include "context.h"
-#if FEATURE_convolve
 #include "convolve.h"
-#endif
 #include "image.h"
 #include "macros.h"
 #include "mipmap.h"
 #include "imports.h"
 #include "texcompress.h"
+#include "texcompress_fxt1.h"
+#include "texcompress_s3tc.h"
 #include "texformat.h"
 #include "teximage.h"
 #include "texstore.h"
@@ -798,6 +798,7 @@ static const GLubyte *
 type_mapping( GLenum srcType )
 {
    switch (srcType) {
+   case GL_BYTE:
    case GL_UNSIGNED_BYTE:
       return map_identity;
    case GL_UNSIGNED_INT_8_8_8_8:
@@ -819,6 +820,7 @@ byteswap_mapping( GLboolean swapBytes,
       return map_identity;
 
    switch (srcType) {
+   case GL_BYTE:
    case GL_UNSIGNED_BYTE:
       return map_identity;
    case GL_UNSIGNED_INT_8_8_8_8:
@@ -940,7 +942,8 @@ memcpy_texture(GLcontext *ctx,
                                       srcWidth, srcHeight, srcFormat, srcType);
    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
-   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLint bytesPerRow = srcWidth * texelBytes;
 
 #if 0
    /* XXX update/re-enable for dstImageOffsets array */
@@ -949,7 +952,7 @@ memcpy_texture(GLcontext *ctx,
    GLubyte *dstImage = (GLubyte *) dstAddr
                      + dstZoffset * dstImageStride
                      + dstYoffset * dstRowStride
-                     + dstXoffset * dstFormat->TexelBytes;
+                     + dstXoffset * texelBytes;
 
    if (dstRowStride == srcRowStride &&
        dstRowStride == bytesPerRow &&
@@ -980,9 +983,9 @@ memcpy_texture(GLcontext *ctx,
    for (img = 0; img < srcDepth; img++) {
       const GLubyte *srcRow = srcImage;
       GLubyte *dstRow = (GLubyte *) dstAddr
-         + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+         + dstImageOffsets[dstZoffset + img] * texelBytes
          + dstYoffset * dstRowStride
-         + dstXoffset * dstFormat->TexelBytes;
+         + dstXoffset * texelBytes;
       for (row = 0; row < srcHeight; row++) {
          ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
          dstRow += dstRowStride;
@@ -1008,6 +1011,8 @@ GLboolean
 _mesa_texstore_rgba(TEXSTORE_PARAMS)
 {
    const GLint components = _mesa_components_in_format(baseInternalFormat);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_rgba ||
           dstFormat == &_mesa_texformat_rgb ||
@@ -1021,7 +1026,7 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
           baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
+   ASSERT(texelBytes == components * sizeof(GLchan));
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1045,9 +1050,9 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
       for (img = 0; img < srcDepth; img++) {
          GLchan *dstImage = (GLchan *)
             ((GLubyte *) dstAddr
-             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+             + dstImageOffsets[dstZoffset + img] * texelBytes
              + dstYoffset * dstRowStride
-             + dstXoffset * dstFormat->TexelBytes);
+             + dstXoffset * texelBytes);
 
          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
                                                  srcWidth, srcFormat, srcType);
@@ -1121,7 +1126,7 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1134,9 +1139,9 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS)
       bytesPerRow = srcWidth * components * sizeof(GLchan);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             _mesa_memcpy(dstRow, src, bytesPerRow);
             dstRow += dstRowStride;
@@ -1157,9 +1162,10 @@ GLboolean
 _mesa_texstore_z32(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffffffff;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
    (void) dims;
    ASSERT(dstFormat == &_mesa_texformat_z32);
-   ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
+   ASSERT(texelBytes == sizeof(GLuint));
 
    if (ctx->Pixel.DepthScale == 1.0f &&
        ctx->Pixel.DepthBias == 0.0f &&
@@ -1180,9 +1186,9 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -1205,9 +1211,10 @@ GLboolean
 _mesa_texstore_z16(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffff;
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
    (void) dims;
    ASSERT(dstFormat == &_mesa_texformat_z16);
-   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
+   ASSERT(texelBytes == sizeof(GLushort));
 
    if (ctx->Pixel.DepthScale == 1.0f &&
        ctx->Pixel.DepthBias == 0.0f &&
@@ -1228,9 +1235,9 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -1252,9 +1259,12 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
    ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
           dstFormat == &_mesa_texformat_rgb565_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1284,7 +1294,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
                              srcFormat, srcType, 0, 0, 0);
       GLubyte *dst = (GLubyte *) dstAddr
                    + dstYoffset * dstRowStride
-                   + dstXoffset * dstFormat->TexelBytes;
+                   + dstXoffset * texelBytes;
       GLint row, col;
       for (row = 0; row < srcHeight; row++) {
          const GLubyte *srcUB = (const GLubyte *) src;
@@ -1310,7 +1320,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1321,9 +1331,9 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             /* check for byteswapped format */
@@ -1359,10 +1369,12 @@ GLboolean
 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
           dstFormat == &_mesa_texformat_rgba8888_rev);
-   ASSERT(dstFormat->TexelBytes == 4);
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1435,7 +1447,7 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1446,9 +1458,9 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
             if (dstFormat == &_mesa_texformat_rgba8888) {
@@ -1482,10 +1494,12 @@ GLboolean
 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
           dstFormat == &_mesa_texformat_argb8888_rev);
-   ASSERT(dstFormat->TexelBytes == 4);
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1531,9 +1545,9 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *d4 = (GLuint *) dstRow;
             for (col = 0; col < srcWidth; col++) {
@@ -1567,9 +1581,9 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *d4 = (GLuint *) dstRow;
             for (col = 0; col < srcWidth; col++) {
@@ -1626,7 +1640,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1637,9 +1651,9 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
             if (dstFormat == &_mesa_texformat_argb8888) {
@@ -1673,9 +1687,11 @@ GLboolean
 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_rgb888);
-   ASSERT(dstFormat->TexelBytes == 3);
+   ASSERT(texelBytes == 3);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1703,9 +1719,9 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
@@ -1745,7 +1761,7 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1756,9 +1772,9 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
 #if 0
             if (littleEndian) {
@@ -1798,9 +1814,11 @@ GLboolean
 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_bgr888);
-   ASSERT(dstFormat->TexelBytes == 3);
+   ASSERT(texelBytes == 3);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1828,9 +1846,9 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
@@ -1870,7 +1888,7 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1881,9 +1899,9 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
@@ -1899,13 +1917,73 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
+GLboolean
+_mesa_texstore_rgba4444(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
+   ASSERT(dstFormat == &_mesa_texformat_rgba4444);
+   ASSERT(texelBytes == 2);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == &_mesa_texformat_rgba4444 &&
+       baseInternalFormat == GL_RGBA &&
+       srcFormat == GL_RGBA &&
+       srcType == GL_UNSIGNED_SHORT_4_4_4_4){
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLchan *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLushort *dstUS = (GLushort *) dstRow;
+           for (col = 0; col < srcWidth; col++) {
+             dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
+                                           CHAN_TO_UBYTE(src[GCOMP]),
+                                           CHAN_TO_UBYTE(src[BCOMP]),
+                                           CHAN_TO_UBYTE(src[ACOMP]) );
+             src += 4;
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
 
 GLboolean
 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
    ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
           dstFormat == &_mesa_texformat_argb4444_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1925,7 +2003,7 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -1936,9 +2014,9 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_argb4444) {
@@ -1967,14 +2045,73 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
+GLboolean
+_mesa_texstore_rgba5551(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
+   ASSERT(dstFormat == &_mesa_texformat_rgba5551);
+   ASSERT(texelBytes == 2);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == &_mesa_texformat_rgba5551 &&
+       baseInternalFormat == GL_RGBA &&
+       srcFormat == GL_RGBA &&
+       srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLchan *src =tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLushort *dstUS = (GLushort *) dstRow;
+           for (col = 0; col < srcWidth; col++) {
+              dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
+                                            CHAN_TO_UBYTE(src[GCOMP]),
+                                            CHAN_TO_UBYTE(src[BCOMP]),
+                                            CHAN_TO_UBYTE(src[ACOMP]) );
+             src += 4;
+           }
+            dstRow += dstRowStride;
+         }
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
 
 GLboolean
 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
    ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
           dstFormat == &_mesa_texformat_argb1555_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1994,7 +2131,7 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2005,9 +2142,9 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_argb1555) {
@@ -2041,10 +2178,12 @@ GLboolean
 _mesa_texstore_al88(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_al88 ||
           dstFormat == &_mesa_texformat_al88_rev);
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2097,7 +2236,7 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2108,9 +2247,9 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstUS = (GLushort *) dstRow;
             if (dstFormat == &_mesa_texformat_al88) {
@@ -2141,8 +2280,11 @@ _mesa_texstore_al88(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
    ASSERT(dstFormat == &_mesa_texformat_rgb332);
-   ASSERT(dstFormat->TexelBytes == 1);
+   ASSERT(texelBytes == 1);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2160,7 +2302,7 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2171,9 +2313,9 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
@@ -2196,10 +2338,13 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_a8(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
    ASSERT(dstFormat == &_mesa_texformat_a8 ||
           dstFormat == &_mesa_texformat_l8 ||
           dstFormat == &_mesa_texformat_i8);
-   ASSERT(dstFormat->TexelBytes == 1);
+   ASSERT(texelBytes == 1);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2246,7 +2391,7 @@ _mesa_texstore_a8(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2257,9 +2402,9 @@ _mesa_texstore_a8(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             for (col = 0; col < srcWidth; col++) {
                dstRow[col] = CHAN_TO_UBYTE(src[col]);
@@ -2278,9 +2423,11 @@ _mesa_texstore_a8(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_ci8(TEXSTORE_PARAMS)
 {
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+
    (void) dims; (void) baseInternalFormat;
    ASSERT(dstFormat == &_mesa_texformat_ci8);
-   ASSERT(dstFormat->TexelBytes == 1);
+   ASSERT(texelBytes == 1);
    ASSERT(baseInternalFormat == GL_COLOR_INDEX);
 
    if (!ctx->_ImageTransferState &&
@@ -2300,9 +2447,9 @@ _mesa_texstore_ci8(TEXSTORE_PARAMS)
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             const GLvoid *src = _mesa_image_address(dims, srcPacking,
                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
@@ -2324,11 +2471,13 @@ GLboolean
 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 {
    const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+
    (void) ctx; (void) dims; (void) baseInternalFormat;
 
    ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
           (dstFormat == &_mesa_texformat_ycbcr_rev));
-   ASSERT(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
    ASSERT(ctx->Extensions.MESA_ycbcr_texture);
    ASSERT(srcFormat == GL_YCBCR_MESA);
    ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
@@ -2352,9 +2501,9 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             _mesa_swap2((GLushort *) dstRow, srcWidth);
             dstRow += dstRowStride;
@@ -2364,7 +2513,217 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
+GLboolean
+_mesa_texstore_dudv8(TEXSTORE_PARAMS)
+{
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+
+   ASSERT(dstFormat == &_mesa_texformat_dudv8);
+   ASSERT(texelBytes == 2);
+   ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
+   ASSERT((srcFormat == GL_DU8DV8_ATI) ||
+         (srcFormat == GL_DUDV_ATI));
+   ASSERT(baseInternalFormat == GL_DUDV_ATI);
+
+   if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
+       littleEndian) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (srcType == GL_BYTE) {
 
+      GLubyte dstmap[4];
+
+      /* dstmap - how to swizzle from RGBA to dst format:
+       */
+      if (littleEndian) {
+        dstmap[0] = 0;
+        dstmap[1] = 3;
+      }
+      else {
+        dstmap[0] = 3;
+        dstmap[1] = 0;
+      }
+      dstmap[2] = ZERO;                /* ? */
+      dstmap[3] = ONE;         /* ? */
+      
+      _mesa_swizzle_ubyte_image(ctx, dims,
+                               GL_LUMINANCE_ALPHA, /* hack */
+                               GL_UNSIGNED_BYTE, /* hack */
+                               GL_LUMINANCE_ALPHA, /* hack */
+                               dstmap, 2,
+                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstImageOffsets,
+                               srcWidth, srcHeight, srcDepth, srcAddr,
+                               srcPacking);      
+   }   
+   else {
+      /* general path - note this is defined for 2d textures only */
+      const GLint components = _mesa_components_in_format(baseInternalFormat);
+      const GLint srcStride = _mesa_image_row_stride(srcPacking,
+                                                 srcWidth, srcFormat, srcType);
+      GLbyte *tempImage, *dst, *src;
+      GLint row;
+
+      tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
+                                          * components * sizeof(GLbyte));
+      if (!tempImage)
+         return GL_FALSE;
+
+      src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                           srcWidth, srcHeight,
+                                           srcFormat, srcType,
+                                           0, 0, 0);
+
+      dst = tempImage;
+      for (row = 0; row < srcHeight; row++) {
+         _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
+                                     dst, srcFormat, srcType, src,
+                                     srcPacking, 0);
+         dst += srcWidth * components;
+         src += srcStride;
+      }
+      src = tempImage;
+      dst = (GLbyte *) dstAddr
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+      for (row = 0; row < srcHeight; row++) {
+         memcpy(dst, src, srcWidth * texelBytes);
+         dst += dstRowStride;
+         src += srcWidth * texelBytes;
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+/**
+ * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
+ */
+GLboolean
+_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
+{
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+
+   ASSERT(dstFormat == &_mesa_texformat_signed_rgba8888 ||
+          dstFormat == &_mesa_texformat_signed_rgba8888_rev);
+   ASSERT(texelBytes == 4);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == &_mesa_texformat_signed_rgba8888 &&
+       baseInternalFormat == GL_RGBA &&
+      ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
+       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
+       /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == &_mesa_texformat_signed_rgba8888_rev &&
+       baseInternalFormat == GL_RGBA &&
+      ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
+       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else if (!ctx->_ImageTransferState &&
+           (srcType == GL_BYTE) &&
+           can_swizzle(baseInternalFormat) &&
+           can_swizzle(srcFormat)) {
+
+      GLubyte dstmap[4];
+
+      /* dstmap - how to swizzle from RGBA to dst format:
+       */
+      if ((littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888) ||
+         (!littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888_rev)) {
+        dstmap[3] = 0;
+        dstmap[2] = 1;
+        dstmap[1] = 2;
+        dstmap[0] = 3;
+      }
+      else {
+        dstmap[3] = 3;
+        dstmap[2] = 2;
+        dstmap[1] = 1;
+        dstmap[0] = 0;
+      }
+      
+      _mesa_swizzle_ubyte_image(ctx, dims,
+                               srcFormat,
+                               srcType,
+                               baseInternalFormat,
+                               dstmap, 4,
+                               dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                               dstRowStride, dstImageOffsets,
+                               srcWidth, srcHeight, srcDepth, srcAddr,
+                               srcPacking);      
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *srcRow = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            if (dstFormat == &_mesa_texformat_signed_rgba8888) {
+               for (col = 0; col < srcWidth; col++) {
+                  dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
+                                                FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
+                                                FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
+                                                FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
+                  srcRow += 4;
+               }
+            }
+            else {
+               for (col = 0; col < srcWidth; col++) {
+                  dstUI[col] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
+                                                    FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
+                                                    FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
+                                                    FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
+                  srcRow += 4;
+               }
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
 
 /**
  * Store a combined depth/stencil texture image.
@@ -2373,12 +2732,45 @@ GLboolean
 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
    const GLfloat depthScale = (GLfloat) 0xffffff;
+   const GLint srcRowStride
+      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
+      / sizeof(GLuint);
+   GLint img, row;
 
    ASSERT(dstFormat == &_mesa_texformat_z24_s8);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
-   ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
+   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
 
-   if (ctx->Pixel.DepthScale == 1.0f &&
+   /* In case we only upload depth we need to preserve the stencil */
+   if (srcFormat == GL_DEPTH_COMPONENT) {
+      for (img = 0; img < srcDepth; img++) {
+         GLuint *dstRow = (GLuint *) dstAddr
+            + dstImageOffsets[dstZoffset + img]
+            + dstYoffset * dstRowStride / sizeof(GLuint)
+            + dstXoffset;
+         const GLuint *src
+            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
+                  srcWidth, srcHeight,
+                  srcFormat, srcType,
+                  img, 0, 0);
+         for (row = 0; row < srcHeight; row++) {
+            GLuint depth[MAX_WIDTH];
+            GLint i;
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, /* dst type */
+                                    depth, /* dst addr */
+                                    depthScale,
+                                    srcType, src, srcPacking);
+
+            for (i = 0; i < srcWidth; i++)
+               dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
+
+            src += srcRowStride;
+            dstRow += dstRowStride / sizeof(GLuint);
+         }
+      }
+   }
+   else if (ctx->Pixel.DepthScale == 1.0f &&
        ctx->Pixel.DepthBias == 0.0f &&
        !srcPacking->SwapBytes) {
       /* simple path */
@@ -2529,7 +2921,9 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
 {
-   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
           dstFormat == &_mesa_texformat_rgb_float32 ||
@@ -2543,7 +2937,7 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
           baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
+   ASSERT(texelBytes == components * sizeof(GLfloat));
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2561,7 +2955,7 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
       /* general path */
       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2574,9 +2968,9 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
       bytesPerRow = srcWidth * components * sizeof(GLfloat);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             _mesa_memcpy(dstRow, srcRow, bytesPerRow);
             dstRow += dstRowStride;
@@ -2596,7 +2990,9 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
 {
-   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat->MesaFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat->MesaFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
 
    ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
           dstFormat == &_mesa_texformat_rgb_float16 ||
@@ -2610,7 +3006,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
           baseInternalFormat == GL_LUMINANCE ||
           baseInternalFormat == GL_LUMINANCE_ALPHA ||
           baseInternalFormat == GL_INTENSITY);
-   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
+   ASSERT(texelBytes == components * sizeof(GLhalfARB));
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2628,7 +3024,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
       /* general path */
       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2639,9 +3035,9 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = (GLubyte *) dstAddr
-            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
+            + dstImageOffsets[dstZoffset + img] * texelBytes
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
          for (row = 0; row < srcHeight; row++) {
             GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
             GLint i;
@@ -2664,16 +3060,14 @@ GLboolean
 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
 {
    const struct gl_texture_format *newDstFormat;
-   StoreTexImageFunc store;
    GLboolean k;
 
    ASSERT(dstFormat == &_mesa_texformat_srgb8);
 
    /* reuse normal rgb texstore code */
    newDstFormat = &_mesa_texformat_rgb888;
-   store = _mesa_texstore_rgb888;
 
-   k = store(ctx, dims, baseInternalFormat,
+   k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
              newDstFormat, dstAddr,
              dstXoffset, dstYoffset, dstZoffset,
              dstRowStride, dstImageOffsets,
@@ -2774,6 +3168,104 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
 #endif /* FEATURE_EXT_texture_sRGB */
 
 
+
+
+/**
+ * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
+ * XXX this is somewhat temporary.
+ */
+static struct {
+   gl_format Name;
+   StoreTexImageFunc Store;
+}
+texstore_funcs[MESA_FORMAT_COUNT] =
+{
+   { MESA_FORMAT_NONE, NULL },
+   { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 },
+   { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
+   { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
+   { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
+   { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
+   { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
+   { MESA_FORMAT_RGBA4444, _mesa_texstore_rgba4444 },
+   { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
+   { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
+   { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
+   { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
+   { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
+   { MESA_FORMAT_AL88, _mesa_texstore_al88 },
+   { MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
+   { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
+   { MESA_FORMAT_A8, _mesa_texstore_a8 },
+   { MESA_FORMAT_L8, _mesa_texstore_a8 },
+   { MESA_FORMAT_I8, _mesa_texstore_a8 },
+   { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
+   { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
+   { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
+   { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
+   { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
+   { MESA_FORMAT_Z16, _mesa_texstore_z16 },
+   { MESA_FORMAT_Z32, _mesa_texstore_z32 },
+   { MESA_FORMAT_S8, NULL/*_mesa_texstore_s8*/ },
+   { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
+   { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 },
+   { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 },
+   { MESA_FORMAT_SL8, _mesa_texstore_sl8 },
+   { MESA_FORMAT_SLA8, _mesa_texstore_sla8 },
+   { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 },
+   { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 },
+   { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 },
+   { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 },
+   { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 },
+   { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 },
+   { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 },
+   { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
+   { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
+   { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
+   { MESA_FORMAT_RGBA, _mesa_texstore_rgba },
+   { MESA_FORMAT_RGB, _mesa_texstore_rgba },
+   { MESA_FORMAT_ALPHA, _mesa_texstore_rgba },
+   { MESA_FORMAT_LUMINANCE, _mesa_texstore_rgba },
+   { MESA_FORMAT_LUMINANCE_ALPHA, _mesa_texstore_rgba },
+   { MESA_FORMAT_INTENSITY, _mesa_texstore_rgba },
+   { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
+   { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
+   { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
+   { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
+   { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
+};
+
+
+/**
+ * Return the StoreTexImageFunc pointer to store an image in the given format.
+ */
+StoreTexImageFunc
+_mesa_get_texstore_func(gl_format format)
+{
+   GLuint i;
+#ifdef DEBUG
+   for (i = 0; i < MESA_FORMAT_COUNT; i++) {
+      ASSERT(texstore_funcs[i].Name == i);
+   }
+#endif
+   ASSERT(texstore_funcs[format].Name == format);
+   return texstore_funcs[format].Store;
+}
+
+
+
 /**
  * Check if an unpack PBO is active prior to fetching a texture image.
  * If so, do bounds checking and map the buffer into main memory.
@@ -2789,7 +3281,7 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
 {
    GLubyte *buf;
 
-   if (unpack->BufferObj->Name == 0) {
+   if (!_mesa_is_bufferobj(unpack->BufferObj)) {
       /* no PBO */
       return pixels;
    }
@@ -2825,7 +3317,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
 {
    GLubyte *buf;
 
-   if (packing->BufferObj->Name == 0) {
+   if (!_mesa_is_bufferobj(packing->BufferObj)) {
       /* not using a PBO - return pointer unchanged */
       return pixels;
    }
@@ -2855,7 +3347,7 @@ void
 _mesa_unmap_teximage_pbo(GLcontext *ctx,
                          const struct gl_pixelstore_attrib *unpack)
 {
-   if (unpack->BufferObj->Name) {
+   if (_mesa_is_bufferobj(unpack->BufferObj)) {
       ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
                               unpack->BufferObj);
    }
@@ -2871,10 +3363,12 @@ fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
                           GLint i, GLint j, GLint k, GLchan *texelOut)
 {
    GLfloat temp[4];
+   GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat->MesaFormat);
+
    ASSERT(texImage->FetchTexelf);
    texImage->FetchTexelf(texImage, i, j, k, temp);
-   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
-       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+   if (baseFormat == GL_DEPTH_COMPONENT ||
+       baseFormat == GL_DEPTH_STENCIL_EXT) {
       /* just one channel */
       UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
    }
@@ -2896,10 +3390,12 @@ fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
                           GLint i, GLint j, GLint k, GLfloat *texelOut)
 {
    GLchan temp[4];
+   GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat->MesaFormat);
+
    ASSERT(texImage->FetchTexelc);
    texImage->FetchTexelc(texImage, i, j, k, temp);
-   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
-       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+   if (baseFormat == GL_DEPTH_COMPONENT ||
+       baseFormat == GL_DEPTH_STENCIL_EXT) {
       /* just one channel */
       texelOut[0] = CHAN_TO_FLOAT(temp[0]);
    }
@@ -2922,22 +3418,8 @@ _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
    ASSERT(dims == 1 || dims == 2 || dims == 3);
    ASSERT(texImage->TexFormat);
 
-   switch (dims) {
-   case 1:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
-      break;
-   case 2:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
-      break;
-   case 3:
-      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
-      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
-      break;
-   default:
-      ;
-   }
+   texImage->FetchTexelf =
+      _mesa_get_texel_fetch_func(texImage->TexFormat->MesaFormat, dims);
 
    /* now check if we need to use a float/chan adaptor */
    if (!texImage->FetchTexelc) {
@@ -2953,35 +3435,13 @@ _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
 }
 
 
-/**
- * Choose the actual storage format for a new texture image.
- * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
- * Also set some other texImage fields related to texture compression, etc.
- * \param ctx  rendering context
- * \param texImage  the gl_texture_image
- * \param dims  texture dimensions (1, 2 or 3)
- * \param format  the user-specified format parameter
- * \param type  the user-specified type parameter
- * \param internalFormat  the user-specified internal format hint
- */
 static void
-choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
-                      GLuint dims,
-                      GLenum format, GLenum type, GLint internalFormat)
+compute_texture_size(GLcontext *ctx, struct gl_texture_image *texImage)
 {
-   ASSERT(dims == 1 || dims == 2 || dims == 3);
-   ASSERT(ctx->Driver.ChooseTextureFormat);
-
-   texImage->TexFormat
-      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-
-   ASSERT(texImage->TexFormat);
+   texImage->IsCompressed =
+      _mesa_is_format_compressed(texImage->TexFormat->MesaFormat);
 
-   _mesa_set_fetch_functions(texImage, dims);
-
-   if (texImage->TexFormat->TexelBytes == 0) {
-      /* must be a compressed format */
-      texImage->IsCompressed = GL_TRUE;
+   if (texImage->IsCompressed) {
       texImage->CompressedSize =
          ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
                                            texImage->Height, texImage->Depth,
@@ -2989,7 +3449,6 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
    }
    else {
       /* non-compressed format */
-      texImage->IsCompressed = GL_FALSE;
       texImage->CompressedSize = 0;
    }
 }
@@ -3016,13 +3475,18 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    GLint sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
+   texImage->TexFormat
+      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+   ASSERT(texImage->TexFormat);
+
+   _mesa_set_fetch_functions(texImage, 1);
+   compute_texture_size(ctx, texImage);
 
    /* allocate memory */
    if (texImage->IsCompressed)
       sizeInBytes = texImage->CompressedSize;
    else
-      sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes;
+      sizeInBytes = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    if (!texImage->Data) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
@@ -3040,25 +3504,24 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    else {
       const GLint dstRowStride = 0;
       GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
+      success = storeImage(ctx, 1, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           0, 0, 0,  /* dstX/Y/Zoffset */
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, 1, 1,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3085,9 +3548,14 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    GLint texelBytes, sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
+   texImage->TexFormat
+      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+   ASSERT(texImage->TexFormat);
 
-   texelBytes = texImage->TexFormat->TexelBytes;
+   _mesa_set_fetch_functions(texImage, 2);
+   compute_texture_size(ctx, texImage);
+
+   texelBytes = _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
 
    /* allocate memory */
    if (texImage->IsCompressed)
@@ -3111,32 +3579,32 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    else {
       GLint dstRowStride;
       GLboolean success;
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
       if (texImage->IsCompressed) {
          dstRowStride
             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
       }
       else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, 1,
-                                                format, type, pixels, packing);
+         dstRowStride = texImage->RowStride * texelBytes;
+      }
+
+      success = storeImage(ctx, 2, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           0, 0, 0,  /* dstX/Y/Zoffset */
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, height, 1,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3159,9 +3627,14 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
    GLint texelBytes, sizeInBytes;
    (void) border;
 
-   choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
+   texImage->TexFormat
+      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+   ASSERT(texImage->TexFormat);
+
+   _mesa_set_fetch_functions(texImage, 3);
+   compute_texture_size(ctx, texImage);
 
-   texelBytes = texImage->TexFormat->TexelBytes;
+   texelBytes = _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
 
    /* allocate memory */
    if (texImage->IsCompressed)
@@ -3185,32 +3658,32 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
    else {
       GLint dstRowStride;
       GLboolean success;
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
       if (texImage->IsCompressed) {
          dstRowStride
             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
       }
       else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, depth,
-                                                format, type, pixels, packing);
+         dstRowStride = texImage->RowStride * texelBytes;
+      }
+
+      success = storeImage(ctx, 3, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           0, 0, 0,  /* dstX/Y/Zoffset */
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, height, depth,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3238,25 +3711,24 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
    {
       const GLint dstRowStride = 0;
       GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, 0, 0,  /* offsets */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
+      success = storeImage(ctx, 1, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           xoffset, 0, 0,  /* offsets */
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, 1, 1,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3284,32 +3756,33 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
    {
       GLint dstRowStride = 0;
       GLboolean success;
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
       if (texImage->IsCompressed) {
          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
                                                     texImage->Width);
       }
       else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, yoffset, 0,
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, 1,
-                                                format, type, pixels, packing);
+         dstRowStride = texImage->RowStride *
+            _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
+      }
+
+      success = storeImage(ctx, 2, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           xoffset, yoffset, 0,
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, height, 1,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3337,32 +3810,33 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
    {
       GLint dstRowStride;
       GLboolean success;
+      const StoreTexImageFunc storeImage =
+         _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
+
+      ASSERT(storeImage);
+
       if (texImage->IsCompressed) {
          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
                                                     texImage->Width);
       }
       else {
-         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
-      }
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, yoffset, zoffset,
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, height, depth,
-                                                format, type, pixels, packing);
+         dstRowStride = texImage->RowStride *
+            _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
+      }
+
+      success = storeImage(ctx, 3, texImage->_BaseFormat,
+                           texImage->TexFormat,
+                           texImage->Data,
+                           xoffset, yoffset, zoffset,
+                           dstRowStride,
+                           texImage->ImageOffsets,
+                           width, height, depth,
+                           format, type, pixels, packing);
       if (!success) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
       }
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
 
@@ -3413,7 +3887,12 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    ASSERT(texImage->Depth == 1);
    ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
 
-   choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
+   texImage->TexFormat
+      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0);
+   ASSERT(texImage->TexFormat);
+
+   _mesa_set_fetch_functions(texImage, 2);
+   compute_texture_size(ctx, texImage);
 
    /* allocate storage */
    texImage->Data = _mesa_alloc_texmemory(imageSize);
@@ -3432,11 +3911,6 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    ASSERT(texImage->CompressedSize == (GLuint) imageSize);
    MEMCPY(texImage->Data, data, imageSize);
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
 
@@ -3507,7 +3981,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    GLint i, rows;
    GLubyte *dest;
    const GLubyte *src;
-   const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
+   const gl_format texFormat = texImage->TexFormat->MesaFormat;
 
    (void) format;
 
@@ -3524,12 +3998,12 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
    if (!data)
       return;
 
-   srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
+   srcRowStride = _mesa_compressed_row_stride(texFormat, width);
    src = (const GLubyte *) data;
 
-   destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
+   destRowStride = _mesa_compressed_row_stride(texFormat, texImage->Width);
    dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
-                                         texImage->TexFormat->MesaFormat,
+                                         texFormat,
                                          texImage->Width,
                                          (GLubyte *) texImage->Data);
 
@@ -3542,11 +4016,6 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
       src += srcRowStride;
    }
 
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      ctx->Driver.GenerateMipmap(ctx, target, texObj);
-   }
-
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
 
@@ -3574,257 +4043,3 @@ _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
    (void) texObj;
    (void) texImage;
 }
-
-
-
-
-#if FEATURE_EXT_texture_sRGB
-
-/**
- * Test if given texture image is an sRGB format.
- */
-static GLboolean
-is_srgb_teximage(const struct gl_texture_image *texImage)
-{
-   switch (texImage->TexFormat->MesaFormat) {
-   case MESA_FORMAT_SRGB8:
-   case MESA_FORMAT_SRGBA8:
-   case MESA_FORMAT_SARGB8:
-   case MESA_FORMAT_SL8:
-   case MESA_FORMAT_SLA8:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
-
-/**
- * This is the software fallback for Driver.GetTexImage().
- * All error checking will have been done before this routine is called.
- */
-void
-_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
-                   GLenum format, GLenum type, GLvoid *pixels,
-                   struct gl_texture_object *texObj,
-                   struct gl_texture_image *texImage)
-{
-   const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
-
-   if (ctx->Pack.BufferObj->Name) {
-      /* Packing texture image into a PBO.
-       * Map the (potentially) VRAM-based buffer into our process space so
-       * we can write into it with the code below.
-       * A hardware driver might use a sophisticated blit to move the
-       * texture data to the PBO if the PBO is in VRAM along with the texture.
-       */
-      GLubyte *buf = (GLubyte *)
-         ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                               GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
-      if (!buf) {
-         /* buffer is already mapped - that's an error */
-         _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
-         return;
-      }
-      /* <pixels> was an offset into the PBO.
-       * Now make it a real, client-side pointer inside the mapped region.
-       */
-      pixels = ADD_POINTERS(buf, pixels);
-   }
-   else if (!pixels) {
-      /* not an error */
-      return;
-   }
-
-   {
-      const GLint width = texImage->Width;
-      const GLint height = texImage->Height;
-      const GLint depth = texImage->Depth;
-      GLint img, row;
-      for (img = 0; img < depth; img++) {
-         for (row = 0; row < height; row++) {
-            /* compute destination address in client memory */
-            GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
-                                                width, height, format, type,
-                                                img, row, 0);
-            assert(dest);
-
-            if (format == GL_COLOR_INDEX) {
-               GLuint indexRow[MAX_WIDTH];
-               GLint col;
-               /* Can't use FetchTexel here because that returns RGBA */
-               if (texImage->TexFormat->IndexBits == 8) {
-                  const GLubyte *src = (const GLubyte *) texImage->Data;
-                  src += width * (img * texImage->Height + row);
-                  for (col = 0; col < width; col++) {
-                     indexRow[col] = src[col];
-                  }
-               }
-               else if (texImage->TexFormat->IndexBits == 16) {
-                  const GLushort *src = (const GLushort *) texImage->Data;
-                  src += width * (img * texImage->Height + row);
-                  for (col = 0; col < width; col++) {
-                     indexRow[col] = src[col];
-                  }
-               }
-               else {
-                  _mesa_problem(ctx,
-                                "Color index problem in _mesa_GetTexImage");
-               }
-               _mesa_pack_index_span(ctx, width, type, dest,
-                                     indexRow, &ctx->Pack,
-                                     0 /* no image transfer */);
-            }
-            else if (format == GL_DEPTH_COMPONENT) {
-               GLfloat depthRow[MAX_WIDTH];
-               GLint col;
-               for (col = 0; col < width; col++) {
-                  (*texImage->FetchTexelf)(texImage, col, row, img,
-                                           depthRow + col);
-               }
-               _mesa_pack_depth_span(ctx, width, dest, type,
-                                     depthRow, &ctx->Pack);
-            }
-            else if (format == GL_DEPTH_STENCIL_EXT) {
-               /* XXX Note: we're bypassing texImage->FetchTexel()! */
-               const GLuint *src = (const GLuint *) texImage->Data;
-               src += width * row + width * height * img;
-               _mesa_memcpy(dest, src, width * sizeof(GLuint));
-               if (ctx->Pack.SwapBytes) {
-                  _mesa_swap4((GLuint *) dest, width);
-               }
-            }
-            else if (format == GL_YCBCR_MESA) {
-               /* No pixel transfer */
-               const GLint rowstride = texImage->RowStride;
-               MEMCPY(dest,
-                      (const GLushort *) texImage->Data + row * rowstride,
-                      width * sizeof(GLushort));
-               /* check for byte swapping */
-               if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
-                    && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
-                   (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
-                    && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
-                  if (!ctx->Pack.SwapBytes)
-                     _mesa_swap2((GLushort *) dest, width);
-               }
-               else if (ctx->Pack.SwapBytes) {
-                  _mesa_swap2((GLushort *) dest, width);
-               }
-            }
-#if FEATURE_EXT_texture_sRGB
-            else if (is_srgb_teximage(texImage)) {
-               /* no pixel transfer and no non-linear to linear conversion */
-               const GLint comps = texImage->TexFormat->TexelBytes;
-               const GLint rowstride = comps * texImage->RowStride;
-               MEMCPY(dest,
-                      (const GLubyte *) texImage->Data + row * rowstride,
-                      comps * width * sizeof(GLubyte));
-               /* FIXME: isn't it necessary to still do component assigning
-                  according to format/type? */
-               /* FIXME: need to do something else for compressed srgb textures
-                         (currently will return values converted to linear) */
-            }
-#endif /* FEATURE_EXT_texture_sRGB */
-            else {
-               /* general case:  convert row to RGBA format */
-               GLfloat rgba[MAX_WIDTH][4];
-               GLint col;
-               GLbitfield transferOps = 0x0;
-
-               if (type == GL_FLOAT && 
-                   ((ctx->Color.ClampReadColor == GL_TRUE) ||
-                    (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
-                     texImage->TexFormat->DataType != GL_FLOAT)))
-                  transferOps |= IMAGE_CLAMP_BIT;
-
-               for (col = 0; col < width; col++) {
-                  (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
-                  if (texImage->TexFormat->BaseFormat == GL_ALPHA) {
-                     rgba[col][RCOMP] = 0.0;
-                     rgba[col][GCOMP] = 0.0;
-                     rgba[col][BCOMP] = 0.0;
-                  }
-                  else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE) {
-                     rgba[col][GCOMP] = 0.0;
-                     rgba[col][BCOMP] = 0.0;
-                     rgba[col][ACOMP] = 1.0;
-                  }
-                  else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE_ALPHA) {
-                     rgba[col][GCOMP] = 0.0;
-                     rgba[col][BCOMP] = 0.0;
-                  }
-                  else if (texImage->TexFormat->BaseFormat == GL_INTENSITY) {
-                     rgba[col][GCOMP] = 0.0;
-                     rgba[col][BCOMP] = 0.0;
-                     rgba[col][ACOMP] = 1.0;
-                  }
-               }
-               _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
-                                          format, type, dest,
-                                          &ctx->Pack, transferOps /*image xfer ops*/);
-            } /* format */
-         } /* row */
-      } /* img */
-   }
-
-   if (ctx->Pack.BufferObj->Name) {
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                              ctx->Pack.BufferObj);
-   }
-}
-
-
-
-/**
- * This is the software fallback for Driver.GetCompressedTexImage().
- * All error checking will have been done before this routine is called.
- */
-void
-_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
-                              GLvoid *img,
-                              struct gl_texture_object *texObj,
-                              struct gl_texture_image *texImage)
-{
-   GLuint size;
-
-   if (ctx->Pack.BufferObj->Name) {
-      /* pack texture image into a PBO */
-      GLubyte *buf;
-      if ((const GLubyte *) img + texImage->CompressedSize >
-          (const GLubyte *) ctx->Pack.BufferObj->Size) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetCompressedTexImage(invalid PBO access)");
-         return;
-      }
-      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                                              GL_WRITE_ONLY_ARB,
-                                              ctx->Pack.BufferObj);
-      if (!buf) {
-         /* buffer is already mapped - that's an error */
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glGetCompressedTexImage(PBO is mapped)");
-         return;
-      }
-      img = ADD_POINTERS(buf, img);
-   }
-   else if (!img) {
-      /* not an error */
-      return;
-   }
-
-   /* don't use texImage->CompressedSize since that may be padded out */
-   size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height,
-                                        texImage->Depth,
-                                        texImage->TexFormat->MesaFormat);
-
-   /* just memcpy, no pixelstore or pixel transfer */
-   _mesa_memcpy(img, texImage->Data, size);
-
-   if (ctx->Pack.BufferObj->Name) {
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
-                              ctx->Pack.BufferObj);
-   }
-}