mesa: sort texstore_funcs[] array, remove search loop
[mesa.git] / src / mesa / main / texstore.c
index e50c6658c7f624104cbb5158ed2b8047339c5dd0..d47f71d0e2153799909ffd55070b151ccf60c657 100644 (file)
 #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"
@@ -942,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 */
@@ -951,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 &&
@@ -982,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;
@@ -1010,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 ||
@@ -1023,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 &&
@@ -1047,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);
@@ -1123,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);
@@ -1136,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;
@@ -1159,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 &&
@@ -1182,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);
@@ -1207,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 &&
@@ -1230,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);
@@ -1254,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 &&
@@ -1286,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;
@@ -1312,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);
@@ -1323,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 */
@@ -1361,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 &&
@@ -1437,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);
@@ -1448,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) {
@@ -1484,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 &&
@@ -1533,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++) {
@@ -1569,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++) {
@@ -1628,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);
@@ -1639,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) {
@@ -1675,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 &&
@@ -1705,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];
@@ -1747,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);
@@ -1758,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) {
@@ -1800,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 &&
@@ -1830,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];
@@ -1872,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);
@@ -1883,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]);
@@ -1904,8 +1920,11 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
 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(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -1925,7 +1944,7 @@ _mesa_texstore_rgba4444(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 +1955,9 @@ _mesa_texstore_rgba4444(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;
            for (col = 0; col < srcWidth; col++) {
@@ -1959,9 +1978,12 @@ _mesa_texstore_rgba4444(TEXSTORE_PARAMS)
 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 &&
@@ -1981,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);
@@ -1992,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) {
@@ -2026,8 +2048,11 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
 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(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2047,7 +2072,7 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
       /* general path */
       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2058,9 +2083,9 @@ _mesa_texstore_rgba5551(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;
            for (col = 0; col < srcWidth; col++) {
@@ -2081,9 +2106,12 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
 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 &&
@@ -2103,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);
@@ -2114,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) {
@@ -2150,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 &&
@@ -2206,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);
@@ -2217,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) {
@@ -2250,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 &&
@@ -2269,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);
@@ -2280,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]),
@@ -2305,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 &&
@@ -2355,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);
@@ -2366,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]);
@@ -2387,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 &&
@@ -2409,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);
@@ -2433,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) ||
@@ -2461,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;
@@ -2477,9 +2517,10 @@ 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(dstFormat->TexelBytes == 2);
+   ASSERT(texelBytes == 2);
    ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
    ASSERT((srcFormat == GL_DU8DV8_ATI) ||
          (srcFormat == GL_DUDV_ATI));
@@ -2552,11 +2593,11 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
       src = tempImage;
       dst = (GLbyte *) dstAddr
             + dstYoffset * dstRowStride
-            + dstXoffset * dstFormat->TexelBytes;
+            + dstXoffset * texelBytes;
       for (row = 0; row < srcHeight; row++) {
-         memcpy(dst, src, srcWidth * dstFormat->TexelBytes);
+         memcpy(dst, src, srcWidth * texelBytes);
          dst += dstRowStride;
-         src += srcWidth * dstFormat->TexelBytes;
+         src += srcWidth * texelBytes;
       }
       _mesa_free((void *) tempImage);
    }
@@ -2570,10 +2611,12 @@ 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(dstFormat->TexelBytes == 4);
+   ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
@@ -2640,7 +2683,7 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
       /* general path */
       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
                                                  baseInternalFormat,
-                                                 dstFormat->BaseFormat,
+                                                 baseFormat,
                                                  srcWidth, srcHeight, srcDepth,
                                                  srcFormat, srcType, srcAddr,
                                                  srcPacking);
@@ -2651,9 +2694,9 @@ _mesa_texstore_signed_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_signed_rgba8888) {
@@ -2878,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 ||
@@ -2892,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 &&
@@ -2910,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);
@@ -2923,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;
@@ -2945,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 ||
@@ -2959,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 &&
@@ -2977,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);
@@ -2988,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;
@@ -3013,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,
@@ -3123,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.
@@ -3220,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]);
    }
@@ -3245,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]);
    }
@@ -3271,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) {
@@ -3302,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,
@@ -3338,7 +3449,6 @@ choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
    }
    else {
       /* non-compressed format */
-      texImage->IsCompressed = GL_FALSE;
       texImage->CompressedSize = 0;
    }
 }
@@ -3365,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");
@@ -3389,15 +3504,19 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    else {
       const GLint dstRowStride = 0;
       GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                0, 0, 0,  /* dstX/Y/Zoffset */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      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");
       }
@@ -3429,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);
+
+   _mesa_set_fetch_functions(texImage, 2);
+   compute_texture_size(ctx, texImage);
 
-   texelBytes = texImage->TexFormat->TexelBytes;
+   texelBytes = _mesa_get_format_bytes(texImage->TexFormat->MesaFormat);
 
    /* allocate memory */
    if (texImage->IsCompressed)
@@ -3455,22 +3579,27 @@ _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");
       }
@@ -3498,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)
@@ -3524,22 +3658,27 @@ _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");
       }
@@ -3572,15 +3711,19 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
    {
       const GLint dstRowStride = 0;
       GLboolean success;
-      ASSERT(texImage->TexFormat->StoreImage);
-      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
-                                                texImage->TexFormat,
-                                                texImage->Data,
-                                                xoffset, 0, 0,  /* offsets */
-                                                dstRowStride,
-                                                texImage->ImageOffsets,
-                                                width, 1, 1,
-                                                format, type, pixels, packing);
+      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");
       }
@@ -3613,22 +3756,28 @@ _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");
       }
@@ -3661,22 +3810,28 @@ _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");
       }
@@ -3732,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);
@@ -3821,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;
 
@@ -3838,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);