mesa/version: only enable GL4.1 with correct limits.
[mesa.git] / src / mesa / main / texstore.c
old mode 100644 (file)
new mode 100755 (executable)
index f858cef..04325a9
@@ -51,9 +51,9 @@
  */
 
 
+#include "errors.h"
 #include "glheader.h"
 #include "bufferobj.h"
-#include "colormac.h"
 #include "format_pack.h"
 #include "format_utils.h"
 #include "image.h"
@@ -62,7 +62,7 @@
 #include "mtypes.h"
 #include "pack.h"
 #include "pbo.h"
-#include "imports.h"
+
 #include "texcompress.h"
 #include "texcompress_fxt1.h"
 #include "texcompress_rgtc.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"
+#include "pixeltransfer.h"
+#include "util/format_rgb9e5.h"
+#include "util/format_r11g11b10f.h"
 
 
 enum {
-   ZERO = 4, 
+   ZERO = 4,
    ONE = 5
 };
 
@@ -89,595 +90,21 @@ enum {
 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
 
 
-enum {
-   IDX_LUMINANCE = 0,
-   IDX_ALPHA,
-   IDX_INTENSITY,
-   IDX_LUMINANCE_ALPHA,
-   IDX_RGB,
-   IDX_RGBA,
-   IDX_RED,
-   IDX_GREEN,
-   IDX_BLUE,
-   IDX_BGR,
-   IDX_BGRA,
-   IDX_ABGR,
-   IDX_RG,
-   MAX_IDX
-};
-
-#define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
-#define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
-#define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
-#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
-
-
-static const struct {
-   GLubyte format_idx;
-   GLubyte to_rgba[6];
-   GLubyte from_rgba[6];
-} mappings[MAX_IDX] = 
-{
-   {
-      IDX_LUMINANCE,
-      MAP4(0,0,0,ONE),
-      MAP1(0)
-   },
-
-   {
-      IDX_ALPHA,
-      MAP4(ZERO, ZERO, ZERO, 0),
-      MAP1(3)
-   },
-
-   {
-      IDX_INTENSITY,
-      MAP4(0, 0, 0, 0),
-      MAP1(0),
-   },
-
-   {
-      IDX_LUMINANCE_ALPHA,
-      MAP4(0,0,0,1),
-      MAP2(0,3)
-   },
-
-   {
-      IDX_RGB,
-      MAP4(0,1,2,ONE),
-      MAP3(0,1,2)
-   },
-
-   {
-      IDX_RGBA,
-      MAP4(0,1,2,3),
-      MAP4(0,1,2,3),
-   },
-
-   {
-      IDX_RED,
-      MAP4(0, ZERO, ZERO, ONE),
-      MAP1(0),
-   },
-
-   {
-      IDX_GREEN,
-      MAP4(ZERO, 0, ZERO, ONE),
-      MAP1(1),
-   },
-
-   {
-      IDX_BLUE,
-      MAP4(ZERO, ZERO, 0, ONE),
-      MAP1(2),
-   },
-
-   {
-      IDX_BGR,
-      MAP4(2,1,0,ONE),
-      MAP3(2,1,0)
-   },
-
-   {
-      IDX_BGRA,
-      MAP4(2,1,0,3),
-      MAP4(2,1,0,3)
-   },
-
-   {
-      IDX_ABGR,
-      MAP4(3,2,1,0),
-      MAP4(3,2,1,0)
-   },
-
-   {
-      IDX_RG,
-      MAP4(0, 1, ZERO, ONE),
-      MAP2(0, 1)
-   },
-};
-
-
-
 /**
- * Convert a GL image format enum to an IDX_* value (see above).
- */
-static int
-get_map_idx(GLenum value)
-{
-   switch (value) {
-   case GL_LUMINANCE:
-   case GL_LUMINANCE_INTEGER_EXT:
-      return IDX_LUMINANCE;
-   case GL_ALPHA:
-   case GL_ALPHA_INTEGER:
-      return IDX_ALPHA;
-   case GL_INTENSITY:
-      return IDX_INTENSITY;
-   case GL_LUMINANCE_ALPHA:
-   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-      return IDX_LUMINANCE_ALPHA;
-   case GL_RGB:
-   case GL_RGB_INTEGER:
-      return IDX_RGB;
-   case GL_RGBA:
-   case GL_RGBA_INTEGER:
-      return IDX_RGBA;
-   case GL_RED:
-   case GL_RED_INTEGER:
-      return IDX_RED;
-   case GL_GREEN:
-      return IDX_GREEN;
-   case GL_BLUE:
-      return IDX_BLUE;
-   case GL_BGR:
-   case GL_BGR_INTEGER:
-      return IDX_BGR;
-   case GL_BGRA:
-   case GL_BGRA_INTEGER:
-      return IDX_BGRA;
-   case GL_ABGR_EXT:
-      return IDX_ABGR;
-   case GL_RG:
-   case GL_RG_INTEGER:
-      return IDX_RG;
-   default:
-      _mesa_problem(NULL, "Unexpected inFormat %s",
-                    _mesa_lookup_enum_by_nr(value));
-      return 0;
-   }
-}   
-
-
-/**
- * When promoting texture formats (see below) we need to compute the
- * mapping of dest components back to source components.
- * This function does that.
- * \param inFormat  the incoming format of the texture
- * \param outFormat  the final texture format
- * \return map[6]  a full 6-component map
- */
-static void
-compute_component_mapping(GLenum inFormat, GLenum outFormat, 
-                         GLubyte *map)
-{
-   const int inFmt = get_map_idx(inFormat);
-   const int outFmt = get_map_idx(outFormat);
-   const GLubyte *in2rgba = mappings[inFmt].to_rgba;
-   const GLubyte *rgba2out = mappings[outFmt].from_rgba;
-   int i;
-   
-   for (i = 0; i < 4; i++)
-      map[i] = in2rgba[rgba2out[i]];
-
-   map[ZERO] = ZERO;
-   map[ONE] = ONE;   
-
-#if 0
-   printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
-         inFormat, _mesa_lookup_enum_by_nr(inFormat),
-         outFormat, _mesa_lookup_enum_by_nr(outFormat),
-         map[0], 
-         map[1], 
-         map[2], 
-         map[3], 
-         map[4], 
-         map[5]); 
-#endif
-}
-
-
-/**
- * Make a temporary (color) texture image with GLfloat components.
- * Apply all needed pixel unpacking and pixel transfer operations.
- * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
- * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures.  So, we might
- * use an RGB hardware format instead.
- * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
- *
- * \param ctx  the rendering context
- * \param dims  image dimensions: 1, 2 or 3
- * \param logicalBaseFormat  basic texture derived from the user's
- *    internal texture format value
- * \param textureBaseFormat  the actual basic format of the texture
- * \param srcWidth  source image width
- * \param srcHeight  source image height
- * \param srcDepth  source image depth
- * \param srcFormat  source image format
- * \param srcType  source image type
- * \param srcAddr  source image address
- * \param srcPacking  source image pixel packing
- * \return resulting image with format = textureBaseFormat and type = GLfloat.
- */
-GLfloat *
-_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
-                           GLenum logicalBaseFormat,
-                           GLenum textureBaseFormat,
-                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                           GLenum srcFormat, GLenum srcType,
-                           const GLvoid *srcAddr,
-                           const struct gl_pixelstore_attrib *srcPacking,
-                           GLbitfield transferOps)
-{
-   GLfloat *tempImage;
-   const GLint components = _mesa_components_in_format(logicalBaseFormat);
-   const GLint srcStride =
-      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-   GLfloat *dst;
-   GLint img, row;
-
-   ASSERT(dims >= 1 && dims <= 3);
-
-   ASSERT(logicalBaseFormat == GL_RGBA ||
-          logicalBaseFormat == GL_RGB ||
-          logicalBaseFormat == GL_RG ||
-          logicalBaseFormat == GL_RED ||
-          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
-          logicalBaseFormat == GL_LUMINANCE ||
-          logicalBaseFormat == GL_ALPHA ||
-          logicalBaseFormat == GL_INTENSITY ||
-          logicalBaseFormat == GL_DEPTH_COMPONENT);
-
-   ASSERT(textureBaseFormat == GL_RGBA ||
-          textureBaseFormat == GL_RGB ||
-          textureBaseFormat == GL_RG ||
-          textureBaseFormat == GL_RED ||
-          textureBaseFormat == GL_LUMINANCE_ALPHA ||
-          textureBaseFormat == GL_LUMINANCE ||
-          textureBaseFormat == GL_ALPHA ||
-          textureBaseFormat == GL_INTENSITY ||
-          textureBaseFormat == GL_DEPTH_COMPONENT);
-
-   tempImage = malloc(srcWidth * srcHeight * srcDepth
-                                 * components * sizeof(GLfloat));
-   if (!tempImage)
-      return NULL;
-
-   dst = tempImage;
-   for (img = 0; img < srcDepth; img++) {
-      const GLubyte *src
-        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                                srcWidth, srcHeight,
-                                                srcFormat, srcType,
-                                                img, 0, 0);
-      for (row = 0; row < srcHeight; row++) {
-        _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
-                                      dst, srcFormat, srcType, src,
-                                      srcPacking, transferOps);
-        dst += srcWidth * components;
-        src += srcStride;
-      }
-   }
-
-   if (logicalBaseFormat != textureBaseFormat) {
-      /* more work */
-      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
-      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
-      GLfloat *newImage;
-      GLint i, n;
-      GLubyte map[6];
-
-      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
-      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
-             textureBaseFormat == GL_LUMINANCE_ALPHA);
-
-      /* The actual texture format should have at least as many components
-       * as the logical texture format.
-       */
-      ASSERT(texComponents >= logComponents);
-
-      newImage = malloc(srcWidth * srcHeight * srcDepth
-                                          * texComponents * sizeof(GLfloat));
-      if (!newImage) {
-         free(tempImage);
-         return NULL;
-      }
-
-      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
-      n = srcWidth * srcHeight * srcDepth;
-      for (i = 0; i < n; i++) {
-         GLint k;
-         for (k = 0; k < texComponents; k++) {
-            GLint j = map[k];
-            if (j == ZERO)
-               newImage[i * texComponents + k] = 0.0F;
-            else if (j == ONE)
-               newImage[i * texComponents + k] = 1.0F;
-            else
-               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
-         }
-      }
-
-      free(tempImage);
-      tempImage = newImage;
-   }
-
-   return tempImage;
-}
-
-
-/**
- * Make temporary image with uint pixel values.  Used for unsigned
- * integer-valued textures.
+ * Teximage storage routine for when a simple memcpy will do.
+ * No pixel transfer operations or special texel encodings allowed.
+ * 1D, 2D and 3D images supported.
  */
-static GLuint *
-make_temp_uint_image(struct gl_context *ctx, GLuint dims,
-                     GLenum logicalBaseFormat,
-                     GLenum textureBaseFormat,
+void
+_mesa_memcpy_texture(struct gl_context *ctx,
+                     GLuint dimensions,
+                     mesa_format dstFormat,
+                     GLint dstRowStride,
+                     GLubyte **dstSlices,
                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
                      GLenum srcFormat, GLenum srcType,
                      const GLvoid *srcAddr,
                      const struct gl_pixelstore_attrib *srcPacking)
-{
-   GLuint *tempImage;
-   const GLint components = _mesa_components_in_format(logicalBaseFormat);
-   const GLint srcStride =
-      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-   GLuint *dst;
-   GLint img, row;
-
-   ASSERT(dims >= 1 && dims <= 3);
-
-   ASSERT(logicalBaseFormat == GL_RGBA ||
-          logicalBaseFormat == GL_RGB ||
-          logicalBaseFormat == GL_RG ||
-          logicalBaseFormat == GL_RED ||
-          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
-          logicalBaseFormat == GL_LUMINANCE ||
-          logicalBaseFormat == GL_INTENSITY ||
-          logicalBaseFormat == GL_ALPHA);
-
-   ASSERT(textureBaseFormat == GL_RGBA ||
-          textureBaseFormat == GL_RGB ||
-          textureBaseFormat == GL_RG ||
-          textureBaseFormat == GL_RED ||
-          textureBaseFormat == GL_LUMINANCE_ALPHA ||
-          textureBaseFormat == GL_LUMINANCE ||
-          textureBaseFormat == GL_INTENSITY ||
-          textureBaseFormat == GL_ALPHA);
-
-   tempImage = malloc(srcWidth * srcHeight * srcDepth
-                                 * components * sizeof(GLuint));
-   if (!tempImage)
-      return NULL;
-
-   dst = tempImage;
-   for (img = 0; img < srcDepth; img++) {
-      const GLubyte *src
-        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                                srcWidth, srcHeight,
-                                                srcFormat, srcType,
-                                                img, 0, 0);
-      for (row = 0; row < srcHeight; row++) {
-        _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
-                                      dst, srcFormat, srcType, src,
-                                      srcPacking);
-        dst += srcWidth * components;
-        src += srcStride;
-      }
-   }
-
-   if (logicalBaseFormat != textureBaseFormat) {
-      /* more work */
-      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
-      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
-      GLuint *newImage;
-      GLint i, n;
-      GLubyte map[6];
-
-      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
-      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
-             textureBaseFormat == GL_LUMINANCE_ALPHA);
-
-      /* The actual texture format should have at least as many components
-       * as the logical texture format.
-       */
-      ASSERT(texComponents >= logComponents);
-
-      newImage = malloc(srcWidth * srcHeight * srcDepth
-                                   * texComponents * sizeof(GLuint));
-      if (!newImage) {
-         free(tempImage);
-         return NULL;
-      }
-
-      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
-      n = srcWidth * srcHeight * srcDepth;
-      for (i = 0; i < n; i++) {
-         GLint k;
-         for (k = 0; k < texComponents; k++) {
-            GLint j = map[k];
-            if (j == ZERO)
-               newImage[i * texComponents + k] = 0;
-            else if (j == ONE)
-               newImage[i * texComponents + k] = 1;
-            else
-               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
-         }
-      }
-
-      free(tempImage);
-      tempImage = newImage;
-   }
-
-   return tempImage;
-}
-
-
-
-/**
- * Make a temporary (color) texture image with GLubyte components.
- * Apply all needed pixel unpacking and pixel transfer operations.
- * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
- * Suppose the user specifies GL_LUMINANCE as the internal texture format
- * but the graphics hardware doesn't support luminance textures.  So, we might
- * use an RGB hardware format instead.
- * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
- *
- * \param ctx  the rendering context
- * \param dims  image dimensions: 1, 2 or 3
- * \param logicalBaseFormat  basic texture derived from the user's
- *    internal texture format value
- * \param textureBaseFormat  the actual basic format of the texture
- * \param srcWidth  source image width
- * \param srcHeight  source image height
- * \param srcDepth  source image depth
- * \param srcFormat  source image format
- * \param srcType  source image type
- * \param srcAddr  source image address
- * \param srcPacking  source image pixel packing
- * \return resulting image with format = textureBaseFormat and type = GLubyte.
- */
-GLubyte *
-_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
-                            GLenum logicalBaseFormat,
-                            GLenum textureBaseFormat,
-                            GLint srcWidth, GLint srcHeight, GLint srcDepth,
-                            GLenum srcFormat, GLenum srcType,
-                            const GLvoid *srcAddr,
-                            const struct gl_pixelstore_attrib *srcPacking)
-{
-   GLuint transferOps = ctx->_ImageTransferState;
-   const GLint components = _mesa_components_in_format(logicalBaseFormat);
-   GLint img, row;
-   GLubyte *tempImage, *dst;
-
-   ASSERT(dims >= 1 && dims <= 3);
-
-   ASSERT(logicalBaseFormat == GL_RGBA ||
-          logicalBaseFormat == GL_RGB ||
-          logicalBaseFormat == GL_RG ||
-          logicalBaseFormat == GL_RED ||
-          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
-          logicalBaseFormat == GL_LUMINANCE ||
-          logicalBaseFormat == GL_ALPHA ||
-          logicalBaseFormat == GL_INTENSITY);
-
-   ASSERT(textureBaseFormat == GL_RGBA ||
-          textureBaseFormat == GL_RGB ||
-          textureBaseFormat == GL_RG ||
-          textureBaseFormat == GL_RED ||
-          textureBaseFormat == GL_LUMINANCE_ALPHA ||
-          textureBaseFormat == GL_LUMINANCE ||
-          textureBaseFormat == GL_ALPHA ||
-          textureBaseFormat == GL_INTENSITY);
-
-   /* unpack and transfer the source image */
-   tempImage = malloc(srcWidth * srcHeight * srcDepth
-                                       * components * sizeof(GLubyte));
-   if (!tempImage) {
-      return NULL;
-   }
-
-   dst = tempImage;
-   for (img = 0; img < srcDepth; img++) {
-      const GLint srcStride =
-         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-      const GLubyte *src =
-         (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                               srcWidth, srcHeight,
-                                               srcFormat, srcType,
-                                               img, 0, 0);
-      for (row = 0; row < srcHeight; row++) {
-         _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
-                                       srcFormat, srcType, src, srcPacking,
-                                       transferOps);
-         dst += srcWidth * components;
-         src += srcStride;
-      }
-   }
-
-   if (logicalBaseFormat != textureBaseFormat) {
-      /* one more conversion step */
-      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
-      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
-      GLubyte *newImage;
-      GLint i, n;
-      GLubyte map[6];
-
-      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
-      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
-             textureBaseFormat == GL_LUMINANCE_ALPHA);
-
-      /* The actual texture format should have at least as many components
-       * as the logical texture format.
-       */
-      ASSERT(texComponents >= logComponents);
-
-      newImage = malloc(srcWidth * srcHeight * srcDepth
-                                         * texComponents * sizeof(GLubyte));
-      if (!newImage) {
-         free(tempImage);
-         return NULL;
-      }
-
-      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
-
-      n = srcWidth * srcHeight * srcDepth;
-      for (i = 0; i < n; i++) {
-         GLint k;
-         for (k = 0; k < texComponents; k++) {
-            GLint j = map[k];
-            if (j == ZERO)
-               newImage[i * texComponents + k] = 0;
-            else if (j == ONE)
-               newImage[i * texComponents + k] = 255;
-            else
-               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
-         }
-      }
-
-      free(tempImage);
-      tempImage = newImage;
-   }
-
-   return tempImage;
-}
-
-
-static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
-static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
-static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
-
-
-/**
- * Teximage storage routine for when a simple memcpy will do.
- * No pixel transfer operations or special texel encodings allowed.
- * 1D, 2D and 3D images supported.
- */
-static void
-memcpy_texture(struct gl_context *ctx,
-              GLuint dimensions,
-               mesa_format dstFormat,
-               GLint dstRowStride,
-               GLubyte **dstSlices,
-               GLint srcWidth, GLint srcHeight, GLint srcDepth,
-               GLenum srcFormat, GLenum srcType,
-               const GLvoid *srcAddr,
-               const struct gl_pixelstore_attrib *srcPacking)
 {
    const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
                                                      srcFormat, srcType);
@@ -715,46 +142,6 @@ 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;
-
-   /* This way we will use the RGB versions of the packing functions and it
-    * will work for both RGB and sRGB textures*/
-   dstFormat = _mesa_get_srgb_format_linear(dstFormat);
-
-   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.
  */
@@ -764,9 +151,9 @@ _mesa_texstore_z32(TEXSTORE_PARAMS)
    const GLuint depthScale = 0xffffffff;
    GLenum dstType;
    (void) dims;
-   ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
+   assert(dstFormat == MESA_FORMAT_Z_UNORM32 ||
           dstFormat == MESA_FORMAT_Z_FLOAT32);
-   ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
+   assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
 
    if (dstFormat == MESA_FORMAT_Z_UNORM32)
       dstType = GL_UNSIGNED_INT;
@@ -801,7 +188,7 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
    const GLuint depthScale = 0xffffff;
 
    (void) dims;
-   ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
+   assert(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
 
    {
       /* general path */
@@ -831,7 +218,7 @@ _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
    const GLuint depthScale = 0xffffff;
 
    (void) dims;
-   ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
+   assert(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
 
    {
       /* general path */
@@ -864,8 +251,8 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
 {
    const GLuint depthScale = 0xffff;
    (void) dims;
-   ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
-   ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
+   assert(dstFormat == MESA_FORMAT_Z_UNORM16);
+   assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
 
    {
       /* general path */
@@ -887,88 +274,36 @@ _mesa_texstore_z16(TEXSTORE_PARAMS)
 }
 
 
-/**
- * Store an rgb565 or rgb565_rev texture image.
- */
-static GLboolean
-_mesa_texstore_rgb565(TEXSTORE_PARAMS)
-{
-   ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM ||
-          dstFormat == MESA_FORMAT_R5G6B5_UNORM);
-   ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
-   if (!ctx->_ImageTransferState &&
-       !srcPacking->SwapBytes &&
-       baseInternalFormat == GL_RGB &&
-       srcFormat == GL_RGB &&
-       srcType == GL_UNSIGNED_BYTE &&
-       dims == 2) {
-      /* do optimized tex store */
-      const GLint srcRowStride =
-         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-      const GLubyte *src = (const GLubyte *)
-         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
-                             srcFormat, srcType, 0, 0, 0);
-      GLubyte *dst = dstSlices[0];
-      GLint row, col;
-      for (row = 0; row < srcHeight; row++) {
-         const GLubyte *srcUB = (const GLubyte *) src;
-         GLushort *dstUS = (GLushort *) dst;
-         /* check for byteswapped format */
-         if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) {
-            for (col = 0; col < srcWidth; col++) {
-               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
-               srcUB += 3;
-            }
-         }
-         else {
-            for (col = 0; col < srcWidth; col++) {
-               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
-               srcUB += 3;
-            }
-         }
-         dst += dstRowStride;
-         src += srcRowStride;
-      }
-      return GL_TRUE;
-   } else {
-      return GL_FALSE;
-   }
-}
-
-
 /**
  * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
  */
 static GLboolean
 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 {
-   const GLboolean littleEndian = _mesa_little_endian();
-
    (void) ctx; (void) dims; (void) baseInternalFormat;
 
-   ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
+   assert((dstFormat == MESA_FORMAT_YCBCR) ||
           (dstFormat == MESA_FORMAT_YCBCR_REV));
-   ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
-   ASSERT(srcFormat == GL_YCBCR_MESA);
-   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
+   assert(_mesa_get_format_bytes(dstFormat) == 2);
+   assert(ctx->Extensions.MESA_ycbcr_texture);
+   assert(srcFormat == GL_YCBCR_MESA);
+   assert((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
           (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
-   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
+   assert(baseInternalFormat == GL_YCBCR_MESA);
 
    /* always just memcpy since no pixel transfer ops apply */
-   memcpy_texture(ctx, dims,
-                  dstFormat,
-                  dstRowStride, dstSlices,
-                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
-                  srcAddr, srcPacking);
+   _mesa_memcpy_texture(ctx, dims,
+                        dstFormat,
+                        dstRowStride, dstSlices,
+                        srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                        srcAddr, srcPacking);
 
    /* Check if we need byte swapping */
    /* XXX the logic here _might_ be wrong */
    if (srcPacking->SwapBytes ^
        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
        (dstFormat == MESA_FORMAT_YCBCR_REV) ^
-       !littleEndian) {
+       !UTIL_ARCH_LITTLE_ENDIAN) {
       GLint img, row;
       for (img = 0; img < srcDepth; img++) {
          GLubyte *dstRow = dstSlices[img];
@@ -995,11 +330,11 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
    GLuint *depth = malloc(srcWidth * sizeof(GLuint));
    GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
 
-   ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+   assert(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
+   assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
           srcFormat == GL_DEPTH_COMPONENT ||
           srcFormat == GL_STENCIL_INDEX);
-   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
+   assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
           srcType == GL_UNSIGNED_INT_24_8_EXT ||
           srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
 
@@ -1074,11 +409,11 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
    GLuint *depth;
    GLubyte *stencil;
 
-   ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+   assert(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
+   assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
           srcFormat == GL_DEPTH_COMPONENT ||
           srcFormat == GL_STENCIL_INDEX);
-   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
+   assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
           srcType == GL_UNSIGNED_INT_24_8_EXT ||
           srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
 
@@ -1094,47 +429,47 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
    for (img = 0; img < srcDepth; img++) {
       GLuint *dstRow = (GLuint *) dstSlices[img];
       const GLubyte *src
-        = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
-                                               srcWidth, srcHeight,
-                                               srcFormat, srcType,
-                                               img, 0, 0);
+         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+                                                srcWidth, srcHeight,
+                                                srcFormat, srcType,
+                                                img, 0, 0);
       for (row = 0; row < srcHeight; row++) {
-        GLint i;
-        GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
-        
-        if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
-           keepstencil = GL_TRUE;
-        }
+         GLint i;
+         GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
+
+         if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
+            keepstencil = GL_TRUE;
+         }
          else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
-           keepdepth = GL_TRUE;
-        }
-
-        if (keepdepth == GL_FALSE)
-           /* the 24 depth bits will be in the low position: */
-           _mesa_unpack_depth_span(ctx, srcWidth,
-                                   GL_UNSIGNED_INT, /* dst type */
-                                   keepstencil ? depth : dstRow, /* dst addr */
-                                   depthScale,
-                                   srcType, src, srcPacking);   
-
-        if (keepstencil == GL_FALSE)
-           /* get the 8-bit stencil values */
-           _mesa_unpack_stencil_span(ctx, srcWidth,
-                                     GL_UNSIGNED_BYTE, /* dst type */
-                                     stencil, /* dst addr */
-                                     srcType, src, srcPacking,
-                                     ctx->_ImageTransferState);
-
-        /* merge stencil values into depth values */
-        for (i = 0; i < srcWidth; i++) {
-           if (keepstencil)
-              dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
-           else
-              dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
-
-        }
-        src += srcRowStride;
-        dstRow += dstRowStride / sizeof(GLuint);
+            keepdepth = GL_TRUE;
+         }
+
+         if (keepdepth == GL_FALSE)
+            /* the 24 depth bits will be in the low position: */
+            _mesa_unpack_depth_span(ctx, srcWidth,
+                                    GL_UNSIGNED_INT, /* dst type */
+                                    keepstencil ? depth : dstRow, /* dst addr */
+                                    depthScale,
+                                    srcType, src, srcPacking);
+
+         if (keepstencil == GL_FALSE)
+            /* get the 8-bit stencil values */
+            _mesa_unpack_stencil_span(ctx, srcWidth,
+                                      GL_UNSIGNED_BYTE, /* dst type */
+                                      stencil, /* dst addr */
+                                      srcType, src, srcPacking,
+                                      ctx->_ImageTransferState);
+
+         /* merge stencil values into depth values */
+         for (i = 0; i < srcWidth; i++) {
+            if (keepstencil)
+               dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
+            else
+               dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
+
+         }
+         src += srcRowStride;
+         dstRow += dstRowStride / sizeof(GLuint);
       }
    }
 
@@ -1151,12 +486,12 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
 static GLboolean
 _mesa_texstore_s8(TEXSTORE_PARAMS)
 {
-   ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
-   ASSERT(srcFormat == GL_STENCIL_INDEX);
+   assert(dstFormat == MESA_FORMAT_S_UINT8);
+   assert(srcFormat == GL_STENCIL_INDEX);
 
    {
       const GLint srcRowStride
-        = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
       GLint img, row;
       GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
 
@@ -1201,21 +536,21 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
    GLint img, row;
    const GLint srcRowStride
       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
-      / sizeof(uint64_t);
+         / sizeof(int32_t);
 
-   ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
-   ASSERT(srcFormat == GL_DEPTH_STENCIL ||
+   assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
+   assert(srcFormat == GL_DEPTH_STENCIL ||
           srcFormat == GL_DEPTH_COMPONENT ||
           srcFormat == GL_STENCIL_INDEX);
-   ASSERT(srcFormat != GL_DEPTH_STENCIL ||
+   assert(srcFormat != GL_DEPTH_STENCIL ||
           srcType == GL_UNSIGNED_INT_24_8 ||
           srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
 
    /* In case we only upload depth we need to preserve the stencil */
    for (img = 0; img < srcDepth; img++) {
       uint64_t *dstRow = (uint64_t *) dstSlices[img];
-      const uint64_t *src
-         = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
+      const int32_t *src
+         = (const int32_t *) _mesa_image_address(dims, srcPacking, srcAddr,
                srcWidth, srcHeight,
                srcFormat, srcType,
                img, 0, 0);
@@ -1244,119 +579,6 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
    return GL_TRUE;
 }
 
-static GLboolean
-_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
-{
-   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
-   ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT);
-   ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
-   {
-      /* 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) | (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_R10G10B10A2_UINT);
-   ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
-   {
-      /* 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;
-         }
-      }
-      free((void *) tempImage);
-   }
-   return GL_TRUE;
-}
-
-
 static GLboolean
 texstore_depth_stencil(TEXSTORE_PARAMS)
 {
@@ -1379,7 +601,7 @@ texstore_depth_stencil(TEXSTORE_PARAMS)
       initialized = GL_TRUE;
    }
 
-   ASSERT(table[dstFormat]);
+   assert(table[dstFormat]);
    return table[dstFormat](ctx, dims, baseInternalFormat,
                            dstFormat, dstRowStride, dstSlices,
                            srcWidth, srcHeight, srcDepth,
@@ -1439,336 +661,166 @@ texstore_compressed(TEXSTORE_PARAMS)
       initialized = GL_TRUE;
    }
 
-   ASSERT(table[dstFormat]);
+   assert(table[dstFormat]);
    return table[dstFormat](ctx, dims, baseInternalFormat,
                            dstFormat, dstRowStride, dstSlices,
                            srcWidth, srcHeight, srcDepth,
                            srcFormat, srcType, srcAddr, srcPacking);
 }
 
-static void
-invert_swizzle(uint8_t dst[4], const uint8_t src[4])
-{
-   int i, j;
-
-   dst[0] = MESA_FORMAT_SWIZZLE_NONE;
-   dst[1] = MESA_FORMAT_SWIZZLE_NONE;
-   dst[2] = MESA_FORMAT_SWIZZLE_NONE;
-   dst[3] = MESA_FORMAT_SWIZZLE_NONE;
-
-   for (i = 0; i < 4; ++i)
-      for (j = 0; j < 4; ++j)
-         if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
-            dst[i] = j;
-}
-
-/** Store a texture by per-channel conversions and swizzling.
- *
- * This function attempts to perform a texstore operation by doing simple
- * per-channel conversions and swizzling.  This covers a huge chunk of the
- * texture storage operations that anyone cares about.  If this function is
- * incapable of performing the operation, it bails and returns GL_FALSE.
- */
 static GLboolean
-texstore_swizzle(TEXSTORE_PARAMS)
+texstore_rgba(TEXSTORE_PARAMS)
 {
-   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
-                                                     srcFormat, srcType);
-   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
-                                      srcWidth, srcHeight, srcFormat, srcType);
-   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims,
-        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
-   const int src_components = _mesa_components_in_format(srcFormat);
-
-   GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4];
-   const GLubyte *swap;
-   GLenum dst_type;
-   int dst_components;
-   bool is_array, normalized, need_swap;
-   GLint i, img, row;
-   const GLubyte *src_row;
-   GLubyte *dst_row;
-
-   is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components,
-                                    rgba2dst, &normalized);
-
-   if (!is_array)
-      return GL_FALSE;
-
-   if (srcFormat == GL_COLOR_INDEX)
-      return GL_FALSE;
-
-   if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat))
-      return GL_FALSE;
-
-   switch (srcType) {
-   case GL_FLOAT:
-   case GL_UNSIGNED_BYTE:
-   case GL_BYTE:
-   case GL_UNSIGNED_SHORT:
-   case GL_SHORT:
-   case GL_UNSIGNED_INT:
-   case GL_INT:
-      /* If wa have to swap bytes in a multi-byte datatype, that means
-       * we're not doing an array conversion anymore */
-      if (srcPacking->SwapBytes)
-         return GL_FALSE;
-      need_swap = false;
-      break;
-   case GL_UNSIGNED_INT_8_8_8_8:
-      need_swap = srcPacking->SwapBytes;
-      if (_mesa_little_endian())
-         need_swap = !need_swap;
-      srcType = GL_UNSIGNED_BYTE;
-      break;
-   case GL_UNSIGNED_INT_8_8_8_8_REV:
-      need_swap = srcPacking->SwapBytes;
-      if (!_mesa_little_endian())
-         need_swap = !need_swap;
-      srcType = GL_UNSIGNED_BYTE;
-      break;
-   default:
-      return GL_FALSE;
+   void *tempImage = NULL;
+   int img;
+   GLubyte *src, *dst;
+   uint8_t rebaseSwizzle[4];
+   bool transferOpsDone = false;
+
+   /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
+    * and _mesa_format_convert does not support it. In this case the we only
+    * allow conversions between YCBCR formats and it is mostly a memcpy.
+    */
+   if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) {
+      return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat,
+                                  dstFormat, dstRowStride, dstSlices,
+                                  srcWidth, srcHeight, srcDepth,
+                                  srcFormat, srcType, srcAddr,
+                                  srcPacking);
    }
-   swap = need_swap ? map_3210 : map_identity;
-
-   compute_component_mapping(srcFormat, baseInternalFormat, base2src);
-   compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
-   invert_swizzle(dst2rgba, rgba2dst);
 
-   for (i = 0; i < 4; i++) {
-      if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
-         swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
-      else
-         swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]];
-   }
+   /* We have to deal with GL_COLOR_INDEX manually because
+    * _mesa_format_convert does not handle this format. So what we do here is
+    * convert it to RGBA ubyte first and then convert from that to dst as usual.
+    */
+   if (srcFormat == GL_COLOR_INDEX) {
+      /* Notice that this will already handle byte swapping if necessary */
+      tempImage =
+         _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims,
+                                                srcAddr, srcFormat, srcType,
+                                                srcWidth, srcHeight, srcDepth,
+                                                srcPacking,
+                                                ctx->_ImageTransferState);
+      if (!tempImage)
+         return GL_FALSE;
 
-   /* Is it normalized? */
-   normalized |= !_mesa_is_enum_format_integer(srcFormat);
+      /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops
+       * if needed.
+       */
+      transferOpsDone = true;
 
-   for (img = 0; img < srcDepth; img++) {
-      if (dstRowStride == srcWidth * dst_components &&
-          srcRowStride == srcWidth * src_components) {
-         _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components,
-                                   srcImage, srcType, src_components,
-                                   swizzle, normalized, srcWidth * srcHeight);
-      } else {
-         src_row = srcImage;
-         dst_row = dstSlices[img];
-         for (row = 0; row < srcHeight; row++) {
-            _mesa_swizzle_and_convert(dst_row, dst_type, dst_components,
-                                      src_row, srcType, src_components,
-                                      swizzle, normalized, srcWidth);
-            dst_row += dstRowStride;
-            src_row += srcRowStride;
+      /* Now we only have to adjust our src info for a conversion from
+       * the RGBA ubyte and then we continue as usual.
+       */
+      srcAddr = tempImage;
+      srcFormat = GL_RGBA;
+      srcType = GL_UNSIGNED_BYTE;
+   } else if (srcPacking->SwapBytes) {
+      /* We have to handle byte-swapping scenarios before calling
+       * _mesa_format_convert
+       */
+      GLint swapSize = _mesa_sizeof_packed_type(srcType);
+      if (swapSize == 2 || swapSize == 4) {
+         int imageStride = _mesa_image_image_stride(srcPacking, srcWidth,
+                                                    srcHeight, srcFormat,
+                                                    srcType);
+         int bufferSize = imageStride * srcDepth;
+         int layer;
+         const uint8_t *src;
+         uint8_t *dst;
+
+         tempImage = malloc(bufferSize);
+         if (!tempImage)
+            return GL_FALSE;
+         src = srcAddr;
+         dst = tempImage;
+         for (layer = 0; layer < srcDepth; layer++) {
+            _mesa_swap_bytes_2d_image(srcFormat, srcType,
+                                      srcPacking,
+                                      srcWidth, srcHeight,
+                                      dst, src);
+            src += imageStride;
+            dst += imageStride;
          }
+         srcAddr = tempImage;
       }
-      srcImage += srcImageStride;
    }
 
-   return GL_TRUE;
-}
-
-
-/** Stores a texture by converting float and then to the texture format
- *
- * This function performs a texstore operation by converting to float,
- * applying pixel transfer ops, and then converting to the texture's
- * internal format using pixel store functions.  This function will work
- * for any rgb or srgb textore format.
- */
-static GLboolean
-texstore_via_float(TEXSTORE_PARAMS)
-{
-   GLuint i, img, row;
-   const GLint src_stride =
+   int srcRowStride =
       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-   float *tmp_row;
-   bool need_convert;
-   uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6];
 
-   tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
-   if (!tmp_row)
-      return GL_FALSE;
+   uint32_t srcMesaFormat =
+      _mesa_format_from_format_and_type(srcFormat, srcType);
 
-   /* The GL spec (4.0, compatibility profile) only specifies srgb
-    * conversion as something that is done in the sampler during the
-    * filtering process before the colors are handed to the shader.
-    * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)
-    * does not list RGB <-> sRGB conversions anywhere.  Therefore, we just
-    * treat sRGB formats the same as RGB formats for the purposes of
-    * texture upload and transfer ops.
-    */
    dstFormat = _mesa_get_srgb_format_linear(dstFormat);
 
-   need_convert = false;
-   if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
-      compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
-      compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
-      for (i = 0; i < 4; ++i) {
-         map[i] = base2rgba[rgba2base[i]];
-         if (map[i] != i)
-            need_convert = true;
+   /* If we have transferOps then we need to convert to RGBA float first,
+      then apply transferOps, then do the conversion to dst
+    */
+   void *tempRGBA = NULL;
+   if (!transferOpsDone &&
+       _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
+      /* Allocate RGBA float image */
+      int elementCount = srcWidth * srcHeight * srcDepth;
+      tempRGBA = malloc(4 * elementCount * sizeof(float));
+      if (!tempRGBA) {
+         free(tempImage);
+         return GL_FALSE;
       }
-   }
 
-   for (img = 0; img < srcDepth; img++) {
-      dst_row = dstSlices[img];
-      src_row = _mesa_image_address(dims, srcPacking, srcAddr,
-                                    srcWidth, srcHeight,
-                                    srcFormat, srcType,
-                                    img, 0, 0);
-      for (row = 0; row < srcHeight; row++) {
-        _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row,
-                                       srcFormat, srcType, src_row,
-                                      srcPacking, ctx->_ImageTransferState);
-         if (need_convert)
-            _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4,
-                                      tmp_row, GL_FLOAT, 4,
-                                      map, false, srcWidth);
-         _mesa_pack_float_rgba_row(dstFormat, srcWidth,
-                                   (const GLfloat (*)[4])tmp_row,
-                                   dst_row);
-         dst_row += dstRowStride;
-         src_row += src_stride;
+      /* Convert from src to RGBA float */
+      src = (GLubyte *) srcAddr;
+      dst = (GLubyte *) tempRGBA;
+      for (img = 0; img < srcDepth; img++) {
+         _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float),
+                              src, srcMesaFormat, srcRowStride,
+                              srcWidth, srcHeight, NULL);
+         src += srcHeight * srcRowStride;
+         dst += srcHeight * 4 * srcWidth * sizeof(float);
       }
-   }
-
-   free(tmp_row);
-
-   return GL_TRUE;
-}
 
-/** Stores an integer rgba texture
- *
- * This function performs an integer texture storage operation by unpacking
- * the texture to 32-bit integers, and repacking it into the internal
- * format of the texture.  This will work for any integer rgb texture
- * storage operation.
- */
-static GLboolean
-texstore_rgba_integer(TEXSTORE_PARAMS)
-{
-   GLuint i, img, row, *tmp_row;
-   GLenum dst_type, tmp_type;
-   const GLint src_stride =
-      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
-   int num_dst_components;
-   bool is_array, normalized;
-   uint8_t *src_row, *dst_row;
-   uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4];
+      /* Apply transferOps */
+      _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount,
+                                    (float(*)[4]) tempRGBA);
 
-   tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
-   if (!tmp_row)
-      return GL_FALSE;
-
-   is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components,
-                                    rgba2dst, &normalized);
-
-   assert(is_array && !normalized);
-
-   if (!is_array) {
-      free(tmp_row);
-      return GL_FALSE;
+      /* Now we have to adjust our src info for a conversion from
+       * the RGBA float image and then we continue as usual.
+       */
+      srcAddr = tempRGBA;
+      srcFormat = GL_RGBA;
+      srcType = GL_FLOAT;
+      srcRowStride = srcWidth * 4 * sizeof(float);
+      srcMesaFormat = RGBA32_FLOAT;
+      srcPacking = &ctx->DefaultPacking;
    }
 
-   invert_swizzle(dst2rgba, rgba2dst);
-   compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
-   compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
+   src = (GLubyte *)
+      _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
+                          srcFormat, srcType, 0, 0, 0);
 
-   for (i = 0; i < 4; ++i) {
-      if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
-         swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
-      else
-         swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]];
-   }
-
-   if (_mesa_is_type_unsigned(srcType)) {
-      tmp_type = GL_UNSIGNED_INT;
+   bool needRebase;
+   if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
+      needRebase =
+         _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
+                                                        rebaseSwizzle);
    } else {
-      tmp_type = GL_INT;
+      needRebase = false;
    }
 
    for (img = 0; img < srcDepth; img++) {
-      dst_row = dstSlices[img];
-      src_row = _mesa_image_address(dims, srcPacking, srcAddr,
-                                    srcWidth, srcHeight,
-                                    srcFormat, srcType,
-                                    img, 0, 0);
-      for (row = 0; row < srcHeight; row++) {
-        _mesa_unpack_color_span_uint(ctx, srcWidth, GL_RGBA, tmp_row,
-                                      srcFormat, srcType, src_row, srcPacking);
-         _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components,
-                                   tmp_row, tmp_type, 4,
-                                   swizzle, false, srcWidth);
-         dst_row += dstRowStride;
-         src_row += src_stride;
-      }
+      _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride,
+                           src, srcMesaFormat, srcRowStride,
+                           srcWidth, srcHeight,
+                           needRebase ? rebaseSwizzle : NULL);
+      src += srcHeight * srcRowStride;
    }
 
-   free(tmp_row);
+   free(tempImage);
+   free(tempRGBA);
 
    return GL_TRUE;
 }
 
-static GLboolean
-texstore_rgba(TEXSTORE_PARAMS)
-{
-   static StoreTexImageFunc table[MESA_FORMAT_COUNT];
-   static GLboolean initialized = GL_FALSE;
-
-   if (!initialized) {
-      memset(table, 0, sizeof table);
-
-      table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;
-      table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;
-      table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
-      table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
-
-      table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;
-      table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;
-
-      initialized = GL_TRUE;
-   }
-
-   if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat,
-                                            dstFormat, dstRowStride, dstSlices,
-                                            srcWidth, srcHeight, srcDepth,
-                                            srcFormat, srcType, srcAddr,
-                                            srcPacking)) {
-      return GL_TRUE;
-   }
-
-   if (texstore_swizzle(ctx, dims, baseInternalFormat,
-                        dstFormat,
-                        dstRowStride, dstSlices,
-                        srcWidth, srcHeight, srcDepth,
-                        srcFormat, srcType, srcAddr, srcPacking)) {
-      return GL_TRUE;
-   }
-
-   if (_mesa_is_format_integer(dstFormat)) {
-      return texstore_rgba_integer(ctx, dims, baseInternalFormat,
-                                   dstFormat, dstRowStride, dstSlices,
-                                   srcWidth, srcHeight, srcDepth,
-                                   srcFormat, srcType, srcAddr,
-                                   srcPacking);
-   } else if (_mesa_get_format_max_bits(dstFormat) <= 8 &&
-              !_mesa_is_format_signed(dstFormat)) {
-      return store_ubyte_texture(ctx, dims, baseInternalFormat,
-                                 dstFormat,
-                                 dstRowStride, dstSlices,
-                                 srcWidth, srcHeight, srcDepth,
-                                 srcFormat, srcType, srcAddr, srcPacking);
-   } else {
-      return texstore_via_float(ctx, dims, baseInternalFormat,
-                                dstFormat, dstRowStride, dstSlices,
-                                srcWidth, srcHeight, srcDepth,
-                                srcFormat, srcType, srcAddr,
-                                srcPacking);
-   }
-}
-
 GLboolean
 _mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
                                   GLenum baseInternalFormat,
@@ -1816,7 +868,7 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
 
    /* The Mesa format must match the input format and type. */
    if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
-                                             srcPacking->SwapBytes)) {
+                                             srcPacking->SwapBytes, NULL)) {
       return GL_FALSE;
    }
 
@@ -1846,13 +898,15 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS)
       return GL_FALSE;
    }
 
-   memcpy_texture(ctx, dims,
-                  dstFormat,
-                  dstRowStride, dstSlices,
-                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
-                  srcAddr, srcPacking);
+   _mesa_memcpy_texture(ctx, dims,
+                        dstFormat,
+                        dstRowStride, dstSlices,
+                        srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                        srcAddr, srcPacking);
    return GL_TRUE;
 }
+
+
 /**
  * Store user data into texture memory.
  * Called via glTex[Sub]Image1/2/3D()
@@ -1957,6 +1011,7 @@ store_texsubimage(struct gl_context *ctx,
    /* compute slice info (and do some sanity checks) */
    switch (target) {
    case GL_TEXTURE_2D:
+   case GL_TEXTURE_2D_MULTISAMPLE:
    case GL_TEXTURE_RECTANGLE:
    case GL_TEXTURE_CUBE_MAP:
    case GL_TEXTURE_EXTERNAL_OES:
@@ -1978,6 +1033,7 @@ store_texsubimage(struct gl_context *ctx,
       srcImageStride = _mesa_image_row_stride(packing, width, format, type);
       break;
    case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
       numSlices = depth;
       sliceOffset = zoffset;
       depth = 1;
@@ -1999,7 +1055,8 @@ store_texsubimage(struct gl_context *ctx,
                                                 format, type);
       break;
    default:
-      _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
+      _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()",
+                    target);
       return;
    }
 
@@ -2178,10 +1235,10 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
     * have to worry about the usual image unpacking or image transfer
     * operations.
     */
-   ASSERT(texImage);
-   ASSERT(texImage->Width > 0);
-   ASSERT(texImage->Height > 0);
-   ASSERT(texImage->Depth > 0);
+   assert(texImage);
+   assert(texImage->Width > 0);
+   assert(texImage->Height > 0);
+   assert(texImage->Depth > 0);
 
    /* allocate storage for texture data */
    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
@@ -2189,11 +1246,11 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
       return;
    }
 
-   _mesa_store_compressed_texsubimage(ctx, dims, texImage,
-                                      0, 0, 0,
-                                      texImage->Width, texImage->Height, texImage->Depth,
-                                      texImage->TexFormat,
-                                      imageSize, data);
+   ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
+                                     0, 0, 0,
+                                     texImage->Width, texImage->Height, texImage->Depth,
+                                     texImage->TexFormat,
+                                     imageSize, data);
 }
 
 
@@ -2213,16 +1270,16 @@ _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
                                     const struct gl_pixelstore_attrib *packing,
                                     struct compressed_pixelstore *store)
 {
-   GLuint bw, bh;
+   GLuint bw, bh, bd;
 
-   _mesa_get_format_block_size(texFormat, &bw, &bh);
+   _mesa_get_format_block_size_3d(texFormat, &bw, &bh, &bd);
 
    store->SkipBytes = 0;
    store->TotalBytesPerRow = store->CopyBytesPerRow =
          _mesa_format_row_stride(texFormat, width);
    store->TotalRowsPerSlice = store->CopyRowsPerSlice =
          (height + bh - 1) / bh;
-   store->CopySlices = depth;
+   store->CopySlices = (depth + bd - 1) / bd;
 
    if (packing->CompressedBlockWidth &&
        packing->CompressedBlockSize) {
@@ -2231,10 +1288,11 @@ _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
 
       if (packing->RowLength) {
          store->TotalBytesPerRow = packing->CompressedBlockSize *
-            (packing->RowLength + bw - 1) / bw;
+            ((packing->RowLength + bw - 1) / bw);
       }
 
-      store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
+      store->SkipBytes +=
+         packing->SkipPixels * packing->CompressedBlockSize / bw;
    }
 
    if (dims > 1 && packing->CompressedBlockHeight &&
@@ -2306,16 +1364,24 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
       if (dstMap) {
 
          /* copy rows of blocks */
-         for (i = 0; i < store.CopyRowsPerSlice; i++) {
-            memcpy(dstMap, src, store.CopyBytesPerRow);
-            dstMap += dstRowStride;
-            src += store.TotalBytesPerRow;
+         if (dstRowStride == store.TotalBytesPerRow &&
+             dstRowStride == store.CopyBytesPerRow) {
+            memcpy(dstMap, src, store.CopyBytesPerRow * store.CopyRowsPerSlice);
+            src += store.CopyBytesPerRow * store.CopyRowsPerSlice;
+         }
+         else {
+            for (i = 0; i < store.CopyRowsPerSlice; i++) {
+               memcpy(dstMap, src, store.CopyBytesPerRow);
+               dstMap += dstRowStride;
+               src += store.TotalBytesPerRow;
+            }
          }
 
          ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
 
          /* advance to next slice */
-         src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
+         src += store.TotalBytesPerRow * (store.TotalRowsPerSlice
+                                          - store.CopyRowsPerSlice);
       }
       else {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",