mesa: remove FEATURE_EXT_texture_sRGB define.
[mesa.git] / src / mesa / main / texstore.c
index 2f5686e7f45364d0934e3fd2e22c0876dee9c583..e2598a1dcea700935ddfe4baac66633d0183c5ff 100644 (file)
@@ -37,9 +37,8 @@
  * However, most device drivers will be able to use the fallback functions
  * in this file.  That is, most drivers will have the following bit of
  * code:
- *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
- *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ *   ctx->Driver.TexImage = _mesa_store_teximage;
+ *   ctx->Driver.TexSubImage = _mesa_store_texsubimage;
  *   etc...
  *
  * Texture image processing is actually kind of complicated.  We have to do:
@@ -72,6 +71,7 @@
 #include "teximage.h"
 #include "texstore.h"
 #include "enums.h"
+#include "glformats.h"
 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
 
@@ -354,7 +354,7 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_INTENSITY ||
           textureBaseFormat == GL_DEPTH_COMPONENT);
 
-   tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+   tempImage = malloc(srcWidth * srcHeight * srcDepth
                                  * components * sizeof(GLfloat));
    if (!tempImage)
       return NULL;
@@ -392,7 +392,7 @@ _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
+      newImage = malloc(srcWidth * srcHeight * srcDepth
                                           * texComponents * sizeof(GLfloat));
       if (!newImage) {
          free(tempImage);
@@ -463,7 +463,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_INTENSITY ||
           textureBaseFormat == GL_ALPHA);
 
-   tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+   tempImage = malloc(srcWidth * srcHeight * srcDepth
                                  * components * sizeof(GLuint));
    if (!tempImage)
       return NULL;
@@ -501,7 +501,7 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
+      newImage = malloc(srcWidth * srcHeight * srcDepth
                                    * texComponents * sizeof(GLuint));
       if (!newImage) {
          free(tempImage);
@@ -591,7 +591,7 @@ _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
           textureBaseFormat == GL_INTENSITY);
 
    /* unpack and transfer the source image */
-   tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+   tempImage = malloc(srcWidth * srcHeight * srcDepth
                                        * components * sizeof(GLubyte));
    if (!tempImage) {
       return NULL;
@@ -632,7 +632,7 @@ _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
        */
       ASSERT(texComponents >= logComponents);
 
-      newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
+      newImage = malloc(srcWidth * srcHeight * srcDepth
                                          * texComponents * sizeof(GLubyte));
       if (!newImage) {
          free(tempImage);
@@ -968,6 +968,41 @@ memcpy_texture(struct gl_context *ctx,
 }
 
 
+/**
+ * General-case function for storing a color texture images with
+ * components that can be represented with ubytes.  Example destination
+ * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
+ */
+static GLboolean
+store_ubyte_texture(TEXSTORE_PARAMS)
+{
+   const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
+   GLubyte *tempImage, *src;
+   GLint img;
+
+   tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
+                                           baseInternalFormat,
+                                           GL_RGBA,
+                                           srcWidth, srcHeight, srcDepth,
+                                           srcFormat, srcType, srcAddr,
+                                           srcPacking);
+   if (!tempImage)
+      return GL_FALSE;
+
+   src = tempImage;
+   for (img = 0; img < srcDepth; img++) {
+      _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
+                                 src, srcRowStride,
+                                 dstSlices[img], dstRowStride);
+      src += srcHeight * srcRowStride;
+   }
+   free(tempImage);
+
+   return GL_TRUE;
+}
+
+
+
 
 /**
  * Store a 32-bit integer or float depth component texture image.
@@ -1183,25 +1218,10 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS)
       }
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1269,25 +1289,10 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
                                srcPacking);      
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1343,6 +1348,32 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
          }
       }
    }
+   else if (!ctx->_ImageTransferState &&
+            !srcPacking->SwapBytes &&
+            dstFormat == MESA_FORMAT_ARGB8888 &&
+            srcFormat == GL_LUMINANCE_ALPHA &&
+            baseInternalFormat == GL_RGBA &&
+            srcType == GL_UNSIGNED_BYTE) {
+      /* special case of storing LA -> ARGB8888 */
+      int img, row, col;
+      const GLint srcRowStride =
+         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+      for (img = 0; img < srcDepth; img++) {
+         const GLubyte *srcRow = (const GLubyte *)
+            _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
+                                srcHeight, srcFormat, srcType, img, 0, 0);
+         GLubyte *dstRow = dstSlices[img];
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *d4 = (GLuint *) dstRow;
+            for (col = 0; col < srcWidth; col++) {
+               GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
+               d4[col] = PACK_COLOR_8888(a, l, l, l);
+            }
+            dstRow += dstRowStride;
+            srcRow += srcRowStride;
+         }
+      }
+   }
    else if (!ctx->_ImageTransferState &&
             !srcPacking->SwapBytes &&
            dstFormat == MESA_FORMAT_ARGB8888 &&
@@ -1418,25 +1449,10 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS)
                                srcPacking);      
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1506,25 +1522,10 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS)
                                srcPacking);      
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = (const GLubyte *) tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1594,25 +1595,10 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS)
                                srcPacking);      
    }   
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = (const GLubyte *) tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1637,25 +1623,10 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1678,25 +1649,10 @@ _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src =tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -1720,25 +1676,10 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src =tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -2263,25 +2204,10 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS)
                      srcAddr, srcPacking);
    }
    else {
-      /* general path */
-      const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
-                                                 baseInternalFormat,
-                                                 GL_RGBA,
-                                                 srcWidth, srcHeight, srcDepth,
-                                                 srcFormat, srcType, srcAddr,
-                                                 srcPacking);
-      const GLubyte *src = tempImage;
-      const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
-      GLint img;
-      if (!tempImage)
-         return GL_FALSE;
-      for (img = 0; img < srcDepth; img++) {
-         _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
-                                    src, srcRowStride,
-                                    dstSlices[img], dstRowStride);
-         src += srcHeight * srcRowStride;
-      }
-      free((void *) tempImage);
+      return store_ubyte_texture(ctx, dims, baseInternalFormat,
+                                 dstFormat, dstRowStride, dstSlices,
+                                 srcWidth, srcHeight, srcDepth,
+                                 srcFormat, srcType, srcAddr, srcPacking);
    }
    return GL_TRUE;
 }
@@ -2467,7 +2393,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS)
       GLbyte *tempImage, *dst, *src;
       GLint row;
 
-      tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
+      tempImage = malloc(srcWidth * srcHeight * srcDepth
                                           * components * sizeof(GLbyte));
       if (!tempImage)
          return GL_FALSE;
@@ -2871,6 +2797,15 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
    }
    else if (srcFormat == GL_DEPTH_COMPONENT ||
             srcFormat == GL_STENCIL_INDEX) {
+      GLuint *depth = malloc(srcWidth * sizeof(GLuint));
+      GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
+
+      if (!depth || !stencil) {
+         free(depth);
+         free(stencil);
+         return GL_FALSE;
+      }
+
       /* In case we only upload depth we need to preserve the stencil */
       for (img = 0; img < srcDepth; img++) {
         GLuint *dstRow = (GLuint *) dstSlices[img];
@@ -2880,8 +2815,6 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
                   srcFormat, srcType,
                   img, 0, 0);
          for (row = 0; row < srcHeight; row++) {
-            GLuint depth[MAX_WIDTH];
-           GLubyte stencil[MAX_WIDTH];
             GLint i;
            GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
 
@@ -2919,6 +2852,9 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
             dstRow += dstRowStride / sizeof(GLuint);
          }
       }
+
+      free(depth);
+      free(stencil);
    }
    return GL_TRUE;
 }
@@ -2934,6 +2870,8 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
    const GLint srcRowStride
       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    GLint img, row;
+   GLuint *depth;
+   GLubyte *stencil;
 
    ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
@@ -2942,6 +2880,15 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
           srcType == GL_UNSIGNED_INT_24_8_EXT);
 
+   depth = malloc(srcWidth * sizeof(GLuint));
+   stencil = malloc(srcWidth * sizeof(GLubyte));
+
+   if (!depth || !stencil) {
+      free(depth);
+      free(stencil);
+      return GL_FALSE;
+   }
+
    for (img = 0; img < srcDepth; img++) {
       GLuint *dstRow = (GLuint *) dstSlices[img];
       const GLubyte *src
@@ -2950,8 +2897,6 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
                                                srcFormat, srcType,
                                                img, 0, 0);
       for (row = 0; row < srcHeight; row++) {
-        GLuint depth[MAX_WIDTH];
-        GLubyte stencil[MAX_WIDTH];
         GLint i;
         GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
         
@@ -2990,6 +2935,10 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
         dstRow += dstRowStride / sizeof(GLuint);
       }
    }
+
+   free(depth);
+   free(stencil);
+
    return GL_TRUE;
 }
 
@@ -3018,7 +2967,11 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
       const GLint srcRowStride
         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
       GLint img, row;
-      
+      GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
+
+      if (!stencil)
+         return GL_FALSE;
+
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = dstSlices[img];
          const GLubyte *src
@@ -3027,7 +2980,6 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
                                                    srcFormat, srcType,
                                                    img, 0, 0);
          for (row = 0; row < srcHeight; row++) {
-            GLubyte stencil[MAX_WIDTH];
             GLint i;
 
             /* get the 8-bit stencil values */
@@ -3045,6 +2997,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS)
          }
       }
 
+      free(stencil);
    }
 
    return GL_TRUE;
@@ -3247,6 +3200,7 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
                                                     srcPacking);
       const GLuint *src = tempImage;
       GLint img, row;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3254,8 +3208,14 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLbyte *dstTexel = (GLbyte *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = (GLbyte) src[i];
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
+               }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3317,6 +3277,7 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
                                                     srcPacking);
       const GLuint *src = tempImage;
       GLint img, row;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3324,8 +3285,14 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLshort *dstTexel = (GLshort *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = (GLint) src[i];
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
+               }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3387,6 +3354,7 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
                                                     srcPacking);
       const GLuint *src = tempImage;
       GLint img, row;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3394,8 +3362,14 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLint *dstTexel = (GLint *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = (GLint) src[i];
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
+               }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLint) src[i];
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3454,6 +3428,7 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
                               srcFormat, srcType, srcAddr, srcPacking);
       const GLuint *src = tempImage;
       GLint img, row;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3461,8 +3436,14 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLubyte *dstTexel = (GLubyte *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
+               }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3521,6 +3502,7 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
                               srcFormat, srcType, srcAddr, srcPacking);
       const GLuint *src = tempImage;
       GLint img, row;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3528,8 +3510,14 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLushort *dstTexel = (GLushort *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
+              }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3587,6 +3575,7 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
                               srcWidth, srcHeight, srcDepth,
                               srcFormat, srcType, srcAddr, srcPacking);
       const GLuint *src = tempImage;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       GLint img, row;
       if (!tempImage)
          return GL_FALSE;
@@ -3595,8 +3584,14 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstTexel = (GLuint *) dstRow;
             GLint i;
-            for (i = 0; i < srcWidth * components; i++) {
-               dstTexel[i] = src[i];
+            if (is_unsigned) {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = src[i];
+               }
+            } else {
+               for (i = 0; i < srcWidth * components; i++) {
+                  dstTexel[i] = MAX2((GLint) src[i], 0);
+               }
             }
             dstRow += dstRowStride;
             src += srcWidth * components;
@@ -3609,9 +3604,6 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
 }
 
 
-
-
-#if FEATURE_EXT_texture_sRGB
 static GLboolean
 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
 {
@@ -3715,17 +3707,6 @@ _mesa_texstore_sla8(TEXSTORE_PARAMS)
    return k;
 }
 
-#else
-
-/* these are used only in texstore_funcs[] below */
-#define _mesa_texstore_srgb8 NULL
-#define _mesa_texstore_srgba8 NULL
-#define _mesa_texstore_sargb8 NULL
-#define _mesa_texstore_sl8 NULL
-#define _mesa_texstore_sla8 NULL
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
 static GLboolean
 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
 {
@@ -3914,6 +3895,7 @@ _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
                                                      srcPacking);
       const GLuint *src = tempImage;
       GLint img, row, col;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
       if (!tempImage)
          return GL_FALSE;
       for (img = 0; img < srcDepth; img++) {
@@ -3921,14 +3903,92 @@ _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
 
          for (row = 0; row < srcHeight; row++) {
             GLuint *dstUI = (GLuint *) dstRow;
-            for (col = 0; col < srcWidth; col++) {
-               GLushort a,r,g,b;
-               r = src[RCOMP];
-               g = src[GCOMP];
-               b = src[BCOMP];
-               a = src[ACOMP];
-               dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
-               src += 4;
+            if (is_unsigned) {
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort a,r,g,b;
+                  r = MIN2(src[RCOMP], 0x3ff);
+                  g = MIN2(src[GCOMP], 0x3ff);
+                  b = MIN2(src[BCOMP], 0x3ff);
+                  a = MIN2(src[ACOMP], 0x003);
+                  dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
+                  src += 4;
+               }
+            } else {
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort a,r,g,b;
+                  r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
+                  g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
+                  b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
+                  a = CLAMP((GLint) src[ACOMP], 0, 0x003);
+                  dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
+                  src += 4;
+               }
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+static GLboolean
+_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
+{
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
+   ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+
+   if (baseInternalFormat == GL_RGBA &&
+       _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
+                                            srcPacking->SwapBytes)) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat,
+                     dstRowStride, dstSlices,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLuint *tempImage = make_temp_uint_image(ctx, dims,
+                                                     baseInternalFormat,
+                                                     baseFormat,
+                                                     srcWidth, srcHeight,
+                                                     srcDepth, srcFormat,
+                                                     srcType, srcAddr,
+                                                     srcPacking);
+      const GLuint *src = tempImage;
+      GLint img, row, col;
+      GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
+      if (!tempImage)
+         return GL_FALSE;
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = dstSlices[img];
+
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            if (is_unsigned) {
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort a,r,g,b;
+                  r = MIN2(src[RCOMP], 0x3ff);
+                  g = MIN2(src[GCOMP], 0x3ff);
+                  b = MIN2(src[BCOMP], 0x3ff);
+                  a = MIN2(src[ACOMP], 0x003);
+                  dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
+                  src += 4;
+               }
+            } else {
+               for (col = 0; col < srcWidth; col++) {
+                  GLushort a,r,g,b;
+                  r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
+                  g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
+                  b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
+                  a = CLAMP((GLint) src[ACOMP], 0, 0x003);
+                  dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
+                  src += 4;
+               }
             }
             dstRow += dstRowStride;
          }
@@ -4132,6 +4192,7 @@ _mesa_get_texstore_func(gl_format format)
       table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
 
       table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
+      table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
       initialized = GL_TRUE;
    }
 
@@ -4308,170 +4369,65 @@ store_texsubimage(struct gl_context *ctx,
 
 
 /**
- * This is the fallback for Driver.TexImage1D().
+ * Fallback code for ctx->Driver.TexImage().
+ * Basically, allocate storage for the texture image, then copy the
+ * user's image into it.
  */
 void
-_mesa_store_teximage1d(struct gl_context *ctx,
-                       struct gl_texture_image *texImage,
-                       GLint internalFormat,
-                       GLint width, GLint border,
-                       GLenum format, GLenum type, const GLvoid *pixels,
-                       const struct gl_pixelstore_attrib *packing)
+_mesa_store_teximage(struct gl_context *ctx,
+                     GLuint dims,
+                     struct gl_texture_image *texImage,
+                     GLenum format, GLenum type, const GLvoid *pixels,
+                     const struct gl_pixelstore_attrib *packing)
 {
-   if (width == 0)
-      return;
+   assert(dims == 1 || dims == 2 || dims == 3);
 
-   /* allocate storage for texture data */
-   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
-                                            width, 1, 1)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
-      return;
-   }
-
-   store_texsubimage(ctx, texImage,
-                     0, 0, 0, width, 1, 1,
-                     format, type, pixels, packing, "glTexImage1D");
-}
-
-
-/**
- * This is the fallback for Driver.TexImage2D().
- */
-void
-_mesa_store_teximage2d(struct gl_context *ctx,
-                       struct gl_texture_image *texImage,
-                       GLint internalFormat,
-                       GLint width, GLint height, GLint border,
-                       GLenum format, GLenum type, const void *pixels,
-                       const struct gl_pixelstore_attrib *packing)
-{
-   if (width == 0 || height == 0)
-      return;
-
-   /* allocate storage for texture data */
-   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
-                                            width, height, 1)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-      return;
-   }
-
-   store_texsubimage(ctx, texImage,
-                     0, 0, 0, width, height, 1,
-                     format, type, pixels, packing, "glTexImage2D");
-}
-
-
-
-/**
- * This is the fallback for Driver.TexImage3D().
- */
-void
-_mesa_store_teximage3d(struct gl_context *ctx,
-                       struct gl_texture_image *texImage,
-                       GLint internalFormat,
-                       GLint width, GLint height, GLint depth, GLint border,
-                       GLenum format, GLenum type, const void *pixels,
-                       const struct gl_pixelstore_attrib *packing)
-{
-   if (width == 0 || height == 0 || depth == 0)
+   if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
       return;
 
    /* allocate storage for texture data */
-   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
-                                            width, height, depth)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
       return;
    }
 
    store_texsubimage(ctx, texImage,
-                     0, 0, 0, width, height, depth,
-                     format, type, pixels, packing, "glTexImage3D");
-}
-
-
-
-
-/*
- * This is the fallback for Driver.TexSubImage1D().
- */
-void
-_mesa_store_texsubimage1d(struct gl_context *ctx,
-                          struct gl_texture_image *texImage,
-                          GLint xoffset, GLint width,
-                          GLenum format, GLenum type, const void *pixels,
-                          const struct gl_pixelstore_attrib *packing)
-{
-   store_texsubimage(ctx, texImage,
-                     xoffset, 0, 0, width, 1, 1,
-                     format, type, pixels, packing, "glTexSubImage1D");
-}
-
-
-
-/**
- * This is the fallback for Driver.TexSubImage2D().
- */
-void
-_mesa_store_texsubimage2d(struct gl_context *ctx,
-                          struct gl_texture_image *texImage,
-                          GLint xoffset, GLint yoffset,
-                          GLint width, GLint height,
-                          GLenum format, GLenum type, const void *pixels,
-                          const struct gl_pixelstore_attrib *packing)
-{
-   store_texsubimage(ctx, texImage,
-                     xoffset, yoffset, 0, width, height, 1,
-                     format, type, pixels, packing, "glTexSubImage2D");
+                     0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
+                     format, type, pixels, packing, "glTexImage");
 }
 
 
 /*
- * This is the fallback for Driver.TexSubImage3D().
+ * Fallback for Driver.TexSubImage().
  */
 void
-_mesa_store_texsubimage3d(struct gl_context *ctx,
-                          struct gl_texture_image *texImage,
-                          GLint xoffset, GLint yoffset, GLint zoffset,
-                          GLint width, GLint height, GLint depth,
-                          GLenum format, GLenum type, const void *pixels,
-                          const struct gl_pixelstore_attrib *packing)
+_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
+                        struct gl_texture_image *texImage,
+                        GLint xoffset, GLint yoffset, GLint zoffset,
+                        GLint width, GLint height, GLint depth,
+                        GLenum format, GLenum type, const void *pixels,
+                        const struct gl_pixelstore_attrib *packing)
 {
    store_texsubimage(ctx, texImage,
                      xoffset, yoffset, zoffset, width, height, depth,
-                     format, type, pixels, packing, "glTexSubImage3D");
+                     format, type, pixels, packing, "glTexSubImage");
 }
 
 
-/*
- * Fallback for Driver.CompressedTexImage1D()
- */
-void
-_mesa_store_compressed_teximage1d(struct gl_context *ctx,
-                                  struct gl_texture_image *texImage,
-                                  GLint internalFormat,
-                                  GLint width, GLint border,
-                                  GLsizei imageSize, const GLvoid *data)
-{
-   /* no compressed 1D image formats at this time */
-   (void) ctx;
-   (void) internalFormat;
-   (void) width; (void) border;
-   (void) imageSize; (void) data;
-   (void) texImage;
-}
-
-
-
 /**
- * Fallback for Driver.CompressedTexImage2D()
+ * Fallback for Driver.CompressedTexImage()
  */
 void
-_mesa_store_compressed_teximage2d(struct gl_context *ctx,
-                                  struct gl_texture_image *texImage,
-                                  GLint internalFormat,
-                                  GLint width, GLint height, GLint border,
-                                  GLsizei imageSize, const GLvoid *data)
+_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
+                                struct gl_texture_image *texImage,
+                                GLsizei imageSize, const GLvoid *data)
 {
+   /* only 2D compressed images are supported at this time */
+   if (dims != 2) {
+      _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
+      return;
+   }
+
    /* This is pretty simple, because unlike the general texstore path we don't
     * have to worry about the usual image unpacking or image transfer
     * operations.
@@ -4482,72 +4438,29 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
    ASSERT(texImage->Depth == 1);
 
    /* allocate storage for texture data */
-   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
-                                            width, height, 1)) {
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
       return;
    }
 
-   _mesa_store_compressed_texsubimage2d(ctx, texImage,
-                                       0, 0,
-                                       width, height,
-                                       texImage->TexFormat,
-                                       imageSize, data);
-}
-
-
-
-/*
- * Fallback for Driver.CompressedTexImage3D()
- */
-void
-_mesa_store_compressed_teximage3d(struct gl_context *ctx,
-                                  struct gl_texture_image *texImage,
-                                  GLint internalFormat,
-                                  GLint width, GLint height, GLint depth,
-                                  GLint border,
-                                  GLsizei imageSize, const GLvoid *data)
-{
-   /* this space intentionally left blank */
-   (void) ctx;
-   (void) internalFormat;
-   (void) width; (void) height; (void) depth;
-   (void) border;
-   (void) imageSize; (void) data;
-   (void) texImage;
-}
-
-
-
-/**
- * Fallback for Driver.CompressedTexSubImage1D()
- */
-void
-_mesa_store_compressed_texsubimage1d(struct gl_context *ctx,
-                                     struct gl_texture_image *texImage,
-                                     GLint xoffset, GLsizei width,
-                                     GLenum format,
-                                     GLsizei imageSize, const GLvoid *data)
-{
-   /* there are no compressed 1D texture formats yet */
-   (void) ctx;
-   (void) xoffset; (void) width;
-   (void) format;
-   (void) imageSize; (void) data;
-   (void) texImage;
+   _mesa_store_compressed_texsubimage(ctx, dims, texImage,
+                                      0, 0, 0,
+                                      texImage->Width, texImage->Height, texImage->Depth,
+                                      texImage->TexFormat,
+                                      imageSize, data);
 }
 
 
 /**
- * Fallback for Driver.CompressedTexSubImage2D()
+ * Fallback for Driver.CompressedTexSubImage()
  */
 void
-_mesa_store_compressed_texsubimage2d(struct gl_context *ctx,
-                                     struct gl_texture_image *texImage,
-                                     GLint xoffset, GLint yoffset,
-                                     GLsizei width, GLsizei height,
-                                     GLenum format,
-                                     GLsizei imageSize, const GLvoid *data)
+_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
+                                   struct gl_texture_image *texImage,
+                                   GLint xoffset, GLint yoffset, GLint zoffset,
+                                   GLsizei width, GLsizei height, GLsizei depth,
+                                   GLenum format,
+                                   GLsizei imageSize, const GLvoid *data)
 {
    GLint bytesPerRow, dstRowStride, srcRowStride;
    GLint i, rows;
@@ -4556,6 +4469,11 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx,
    const gl_format texFormat = texImage->TexFormat;
    GLuint bw, bh;
 
+   if (dims != 2) {
+      _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
+      return;
+   }
+
    _mesa_get_format_block_size(texFormat, &bw, &bh);
 
    /* these should have been caught sooner */
@@ -4599,24 +4517,3 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx,
 
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
-
-
-/**
- * Fallback for Driver.CompressedTexSubImage3D()
- */
-void
-_mesa_store_compressed_texsubimage3d(struct gl_context *ctx,
-                                     struct gl_texture_image *texImage,
-                                     GLint xoffset, GLint yoffset, GLint zoffset,
-                                     GLsizei width, GLsizei height, GLsizei depth,
-                                     GLenum format,
-                                     GLsizei imageSize, const GLvoid *data)
-{
-   /* there are no compressed 3D texture formats yet */
-   (void) ctx;
-   (void) xoffset; (void) yoffset; (void) zoffset;
-   (void) width; (void) height; (void) depth;
-   (void) format;
-   (void) imageSize; (void) data;
-   (void) texImage;
-}