mesa/get: Add TYPE_UINT for casting through a GLuint.
[mesa.git] / src / mesa / main / texstore.c
index 42088bbb59ab790bf12b6869bd2e7edaa9577212..615ba63362efe3012adc9a9fb58fc553652d4c20 100644 (file)
@@ -53,7 +53,6 @@
 
 #include "glheader.h"
 #include "bufferobj.h"
-#include "colormac.h"
 #include "format_pack.h"
 #include "format_utils.h"
 #include "image.h"
@@ -73,8 +72,9 @@
 #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 {
@@ -89,287 +89,21 @@ enum {
 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
 
 
-/**
- * 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;
-      }
-
-      _mesa_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 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;
-      }
-
-      _mesa_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)
+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)
 {
    const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
                                                      srcFormat, srcType);
@@ -416,9 +150,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;
@@ -453,7 +187,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 */
@@ -483,7 +217,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 */
@@ -516,8 +250,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 */
@@ -549,21 +283,21 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
 
    (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 */
@@ -597,11 +331,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);
 
@@ -676,11 +410,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);
 
@@ -753,8 +487,8 @@ _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
@@ -805,11 +539,11 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
       / sizeof(uint64_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);
 
@@ -868,7 +602,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,
@@ -928,7 +662,7 @@ 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,
@@ -938,12 +672,13 @@ texstore_compressed(TEXSTORE_PARAMS)
 static GLboolean
 texstore_rgba(TEXSTORE_PARAMS)
 {
-   void *tempImage = NULL;
+   void *tempImage = NULL, *tempRGBA = NULL;
    int srcRowStride, img;
-   GLubyte *src;
+   GLubyte *src, *dst;
    uint32_t srcMesaFormat;
    uint8_t rebaseSwizzle[4];
    bool needRebase;
+   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
@@ -963,15 +698,20 @@ texstore_rgba(TEXSTORE_PARAMS)
     */
    if (srcFormat == GL_COLOR_INDEX) {
       /* Notice that this will already handle byte swapping if necessary */
-      tempImage  = _mesa_make_temp_ubyte_image(ctx, dims,
-                                               baseInternalFormat,
-                                               GL_RGBA,
-                                               srcWidth, srcHeight, srcDepth,
-                                               srcFormat, srcType, srcAddr,
-                                               srcPacking);
+      tempImage =
+         _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims,
+                                                srcAddr, srcFormat, srcType,
+                                                srcWidth, srcHeight, srcDepth,
+                                                srcPacking,
+                                                ctx->_ImageTransferState);
       if (!tempImage)
          return GL_FALSE;
 
+      /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops
+       * if needed.
+       */
+      transferOpsDone = true;
+
       /* Now we only have to adjust our src info for a conversion from
        * the RGBA ubyte and then we continue as usual.
        */
@@ -984,15 +724,25 @@ texstore_rgba(TEXSTORE_PARAMS)
        */
       GLint swapSize = _mesa_sizeof_packed_type(srcType);
       if (swapSize == 2 || swapSize == 4) {
-         int components = _mesa_components_in_format(srcFormat);
-         int elementCount = srcWidth * srcHeight * components;
-         tempImage = malloc(elementCount * swapSize);
+         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;
-         if (swapSize == 2)
-            _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);
-         else
-            _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);
+         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;
       }
    }
@@ -1000,13 +750,53 @@ texstore_rgba(TEXSTORE_PARAMS)
    srcRowStride =
       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
 
+   srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
+   dstFormat = _mesa_get_srgb_format_linear(dstFormat);
+
+   /* If we have transferOps then we need to convert to RGBA float first,
+      then apply transferOps, then do the conversion to dst
+    */
+   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);
+         free(tempRGBA);
+         return GL_FALSE;
+      }
+
+      /* 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);
+      }
+
+      /* Apply transferOps */
+      _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount,
+                                    (float(*)[4]) tempRGBA);
+
+      /* 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;
+   }
+
    src = (GLubyte *)
       _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
                           srcFormat, srcType, 0, 0, 0);
 
-   srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
-   dstFormat = _mesa_get_srgb_format_linear(dstFormat);
-
    if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
       needRebase =
          _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
@@ -1024,6 +814,7 @@ texstore_rgba(TEXSTORE_PARAMS)
    }
 
    free(tempImage);
+   free(tempRGBA);
 
    return GL_TRUE;
 }
@@ -1075,7 +866,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;
    }
 
@@ -1105,13 +896,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()
@@ -1216,6 +1009,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:
@@ -1237,6 +1031,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;
@@ -1437,10 +1232,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)) {
@@ -1448,11 +1243,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);
 }
 
 
@@ -1472,16 +1267,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) {