Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.5
      4  *
      5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      6  * Copyright (c) 2008-2009  VMware, Inc.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice shall be included
     16  * in all copies or substantial portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 /*
     27  * Authors:
     28  *   Brian Paul
     29  */
     30 
     31 /**
     32  * The GL texture image functions in teximage.c basically just do
     33  * error checking and data structure allocation.  They in turn call
     34  * device driver functions which actually copy/convert/store the user's
     35  * texture image data.
     36  *
     37  * However, most device drivers will be able to use the fallback functions
     38  * in this file.  That is, most drivers will have the following bit of
     39  * code:
     40  *   ctx->Driver.TexImage = _mesa_store_teximage;
     41  *   ctx->Driver.TexSubImage = _mesa_store_texsubimage;
     42  *   etc...
     43  *
     44  * Texture image processing is actually kind of complicated.  We have to do:
     45  *    Format/type conversions
     46  *    pixel unpacking
     47  *    pixel transfer (scale, bais, lookup, etc)
     48  *
     49  * These functions can handle most everything, including processing full
     50  * images and sub-images.
     51  */
     52 
     53 
     54 #include "glheader.h"
     55 #include "bufferobj.h"
     56 #include "colormac.h"
     57 #include "format_pack.h"
     58 #include "image.h"
     59 #include "macros.h"
     60 #include "mipmap.h"
     61 #include "mfeatures.h"
     62 #include "mtypes.h"
     63 #include "pack.h"
     64 #include "pbo.h"
     65 #include "imports.h"
     66 #include "texcompress.h"
     67 #include "texcompress_fxt1.h"
     68 #include "texcompress_rgtc.h"
     69 #include "texcompress_s3tc.h"
     70 #include "texcompress_etc.h"
     71 #include "teximage.h"
     72 #include "texstore.h"
     73 #include "enums.h"
     74 #include "glformats.h"
     75 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
     76 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
     77 
     78 
     79 enum {
     80    ZERO = 4,
     81    ONE = 5
     82 };
     83 
     84 
     85 /**
     86  * Texture image storage function.
     87  */
     88 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
     89 
     90 
     91 /**
     92  * Return GL_TRUE if the given image format is one that be converted
     93  * to another format by swizzling.
     94  */
     95 static GLboolean
     96 can_swizzle(GLenum logicalBaseFormat)
     97 {
     98    switch (logicalBaseFormat) {
     99    case GL_RGBA:
    100    case GL_RGB:
    101    case GL_LUMINANCE_ALPHA:
    102    case GL_INTENSITY:
    103    case GL_ALPHA:
    104    case GL_LUMINANCE:
    105    case GL_RED:
    106    case GL_GREEN:
    107    case GL_BLUE:
    108    case GL_BGR:
    109    case GL_BGRA:
    110    case GL_ABGR_EXT:
    111    case GL_RG:
    112       return GL_TRUE;
    113    default:
    114       return GL_FALSE;
    115    }
    116 }
    117 
    118 
    119 
    120 enum {
    121    IDX_LUMINANCE = 0,
    122    IDX_ALPHA,
    123    IDX_INTENSITY,
    124    IDX_LUMINANCE_ALPHA,
    125    IDX_RGB,
    126    IDX_RGBA,
    127    IDX_RED,
    128    IDX_GREEN,
    129    IDX_BLUE,
    130    IDX_BGR,
    131    IDX_BGRA,
    132    IDX_ABGR,
    133    IDX_RG,
    134    MAX_IDX
    135 };
    136 
    137 #define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
    138 #define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
    139 #define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
    140 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
    141 
    142 
    143 static const struct {
    144    GLubyte format_idx;
    145    GLubyte to_rgba[6];
    146    GLubyte from_rgba[6];
    147 } mappings[MAX_IDX] =
    148 {
    149    {
    150       IDX_LUMINANCE,
    151       MAP4(0,0,0,ONE),
    152       MAP1(0)
    153    },
    154 
    155    {
    156       IDX_ALPHA,
    157       MAP4(ZERO, ZERO, ZERO, 0),
    158       MAP1(3)
    159    },
    160 
    161    {
    162       IDX_INTENSITY,
    163       MAP4(0, 0, 0, 0),
    164       MAP1(0),
    165    },
    166 
    167    {
    168       IDX_LUMINANCE_ALPHA,
    169       MAP4(0,0,0,1),
    170       MAP2(0,3)
    171    },
    172 
    173    {
    174       IDX_RGB,
    175       MAP4(0,1,2,ONE),
    176       MAP3(0,1,2)
    177    },
    178 
    179    {
    180       IDX_RGBA,
    181       MAP4(0,1,2,3),
    182       MAP4(0,1,2,3),
    183    },
    184 
    185    {
    186       IDX_RED,
    187       MAP4(0, ZERO, ZERO, ONE),
    188       MAP1(0),
    189    },
    190 
    191    {
    192       IDX_GREEN,
    193       MAP4(ZERO, 0, ZERO, ONE),
    194       MAP1(1),
    195    },
    196 
    197    {
    198       IDX_BLUE,
    199       MAP4(ZERO, ZERO, 0, ONE),
    200       MAP1(2),
    201    },
    202 
    203    {
    204       IDX_BGR,
    205       MAP4(2,1,0,ONE),
    206       MAP3(2,1,0)
    207    },
    208 
    209    {
    210       IDX_BGRA,
    211       MAP4(2,1,0,3),
    212       MAP4(2,1,0,3)
    213    },
    214 
    215    {
    216       IDX_ABGR,
    217       MAP4(3,2,1,0),
    218       MAP4(3,2,1,0)
    219    },
    220 
    221    {
    222       IDX_RG,
    223       MAP4(0, 1, ZERO, ONE),
    224       MAP2(0, 1)
    225    },
    226 };
    227 
    228 
    229 
    230 /**
    231  * Convert a GL image format enum to an IDX_* value (see above).
    232  */
    233 static int
    234 get_map_idx(GLenum value)
    235 {
    236    switch (value) {
    237    case GL_LUMINANCE: return IDX_LUMINANCE;
    238    case GL_ALPHA: return IDX_ALPHA;
    239    case GL_INTENSITY: return IDX_INTENSITY;
    240    case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
    241    case GL_RGB: return IDX_RGB;
    242    case GL_RGBA: return IDX_RGBA;
    243    case GL_RED: return IDX_RED;
    244    case GL_GREEN: return IDX_GREEN;
    245    case GL_BLUE: return IDX_BLUE;
    246    case GL_BGR: return IDX_BGR;
    247    case GL_BGRA: return IDX_BGRA;
    248    case GL_ABGR_EXT: return IDX_ABGR;
    249    case GL_RG: return IDX_RG;
    250    default:
    251       _mesa_problem(NULL, "Unexpected inFormat");
    252       return 0;
    253    }
    254 }
    255 
    256 
    257 /**
    258  * When promoting texture formats (see below) we need to compute the
    259  * mapping of dest components back to source components.
    260  * This function does that.
    261  * \param inFormat  the incoming format of the texture
    262  * \param outFormat  the final texture format
    263  * \return map[6]  a full 6-component map
    264  */
    265 static void
    266 compute_component_mapping(GLenum inFormat, GLenum outFormat,
    267 			  GLubyte *map)
    268 {
    269    const int inFmt = get_map_idx(inFormat);
    270    const int outFmt = get_map_idx(outFormat);
    271    const GLubyte *in2rgba = mappings[inFmt].to_rgba;
    272    const GLubyte *rgba2out = mappings[outFmt].from_rgba;
    273    int i;
    274 
    275    for (i = 0; i < 4; i++)
    276       map[i] = in2rgba[rgba2out[i]];
    277 
    278    map[ZERO] = ZERO;
    279    map[ONE] = ONE;
    280 
    281 #if 0
    282    printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
    283 	  inFormat, _mesa_lookup_enum_by_nr(inFormat),
    284 	  outFormat, _mesa_lookup_enum_by_nr(outFormat),
    285 	  map[0],
    286 	  map[1],
    287 	  map[2],
    288 	  map[3],
    289 	  map[4],
    290 	  map[5]);
    291 #endif
    292 }
    293 
    294 
    295 /**
    296  * Make a temporary (color) texture image with GLfloat components.
    297  * Apply all needed pixel unpacking and pixel transfer operations.
    298  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
    299  * Suppose the user specifies GL_LUMINANCE as the internal texture format
    300  * but the graphics hardware doesn't support luminance textures.  So, we might
    301  * use an RGB hardware format instead.
    302  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
    303  *
    304  * \param ctx  the rendering context
    305  * \param dims  image dimensions: 1, 2 or 3
    306  * \param logicalBaseFormat  basic texture derived from the user's
    307  *    internal texture format value
    308  * \param textureBaseFormat  the actual basic format of the texture
    309  * \param srcWidth  source image width
    310  * \param srcHeight  source image height
    311  * \param srcDepth  source image depth
    312  * \param srcFormat  source image format
    313  * \param srcType  source image type
    314  * \param srcAddr  source image address
    315  * \param srcPacking  source image pixel packing
    316  * \return resulting image with format = textureBaseFormat and type = GLfloat.
    317  */
    318 GLfloat *
    319 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
    320 			    GLenum logicalBaseFormat,
    321 			    GLenum textureBaseFormat,
    322 			    GLint srcWidth, GLint srcHeight, GLint srcDepth,
    323 			    GLenum srcFormat, GLenum srcType,
    324 			    const GLvoid *srcAddr,
    325 			    const struct gl_pixelstore_attrib *srcPacking,
    326 			    GLbitfield transferOps)
    327 {
    328    GLfloat *tempImage;
    329    const GLint components = _mesa_components_in_format(logicalBaseFormat);
    330    const GLint srcStride =
    331       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    332    GLfloat *dst;
    333    GLint img, row;
    334 
    335    ASSERT(dims >= 1 && dims <= 3);
    336 
    337    ASSERT(logicalBaseFormat == GL_RGBA ||
    338           logicalBaseFormat == GL_RGB ||
    339           logicalBaseFormat == GL_RG ||
    340           logicalBaseFormat == GL_RED ||
    341           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
    342           logicalBaseFormat == GL_LUMINANCE ||
    343           logicalBaseFormat == GL_ALPHA ||
    344           logicalBaseFormat == GL_INTENSITY ||
    345           logicalBaseFormat == GL_DEPTH_COMPONENT);
    346 
    347    ASSERT(textureBaseFormat == GL_RGBA ||
    348           textureBaseFormat == GL_RGB ||
    349           textureBaseFormat == GL_RG ||
    350           textureBaseFormat == GL_RED ||
    351           textureBaseFormat == GL_LUMINANCE_ALPHA ||
    352           textureBaseFormat == GL_LUMINANCE ||
    353           textureBaseFormat == GL_ALPHA ||
    354           textureBaseFormat == GL_INTENSITY ||
    355           textureBaseFormat == GL_DEPTH_COMPONENT);
    356 
    357    tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
    358 				  * components * sizeof(GLfloat));
    359    if (!tempImage)
    360       return NULL;
    361 
    362    dst = tempImage;
    363    for (img = 0; img < srcDepth; img++) {
    364       const GLubyte *src
    365 	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
    366 						 srcWidth, srcHeight,
    367 						 srcFormat, srcType,
    368 						 img, 0, 0);
    369       for (row = 0; row < srcHeight; row++) {
    370 	 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
    371 				       dst, srcFormat, srcType, src,
    372 				       srcPacking, transferOps);
    373 	 dst += srcWidth * components;
    374 	 src += srcStride;
    375       }
    376    }
    377 
    378    if (logicalBaseFormat != textureBaseFormat) {
    379       /* more work */
    380       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
    381       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
    382       GLfloat *newImage;
    383       GLint i, n;
    384       GLubyte map[6];
    385 
    386       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
    387       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
    388              textureBaseFormat == GL_LUMINANCE_ALPHA);
    389 
    390       /* The actual texture format should have at least as many components
    391        * as the logical texture format.
    392        */
    393       ASSERT(texComponents >= logComponents);
    394 
    395       newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
    396                                           * texComponents * sizeof(GLfloat));
    397       if (!newImage) {
    398          free(tempImage);
    399          return NULL;
    400       }
    401 
    402       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
    403 
    404       n = srcWidth * srcHeight * srcDepth;
    405       for (i = 0; i < n; i++) {
    406          GLint k;
    407          for (k = 0; k < texComponents; k++) {
    408             GLint j = map[k];
    409             if (j == ZERO)
    410                newImage[i * texComponents + k] = 0.0F;
    411             else if (j == ONE)
    412                newImage[i * texComponents + k] = 1.0F;
    413             else
    414                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
    415          }
    416       }
    417 
    418       free(tempImage);
    419       tempImage = newImage;
    420    }
    421 
    422    return tempImage;
    423 }
    424 
    425 
    426 /**
    427  * Make temporary image with uint pixel values.  Used for unsigned
    428  * integer-valued textures.
    429  */
    430 static GLuint *
    431 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
    432                      GLenum logicalBaseFormat,
    433                      GLenum textureBaseFormat,
    434                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
    435                      GLenum srcFormat, GLenum srcType,
    436                      const GLvoid *srcAddr,
    437                      const struct gl_pixelstore_attrib *srcPacking)
    438 {
    439    GLuint *tempImage;
    440    const GLint components = _mesa_components_in_format(logicalBaseFormat);
    441    const GLint srcStride =
    442       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    443    GLuint *dst;
    444    GLint img, row;
    445 
    446    ASSERT(dims >= 1 && dims <= 3);
    447 
    448    ASSERT(logicalBaseFormat == GL_RGBA ||
    449           logicalBaseFormat == GL_RGB ||
    450           logicalBaseFormat == GL_RG ||
    451           logicalBaseFormat == GL_RED ||
    452           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
    453           logicalBaseFormat == GL_LUMINANCE ||
    454           logicalBaseFormat == GL_INTENSITY ||
    455           logicalBaseFormat == GL_ALPHA);
    456 
    457    ASSERT(textureBaseFormat == GL_RGBA ||
    458           textureBaseFormat == GL_RGB ||
    459           textureBaseFormat == GL_RG ||
    460           textureBaseFormat == GL_RED ||
    461           textureBaseFormat == GL_LUMINANCE_ALPHA ||
    462           textureBaseFormat == GL_LUMINANCE ||
    463           textureBaseFormat == GL_INTENSITY ||
    464           textureBaseFormat == GL_ALPHA);
    465 
    466    tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
    467                                  * components * sizeof(GLuint));
    468    if (!tempImage)
    469       return NULL;
    470 
    471    dst = tempImage;
    472    for (img = 0; img < srcDepth; img++) {
    473       const GLubyte *src
    474 	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
    475 						 srcWidth, srcHeight,
    476 						 srcFormat, srcType,
    477 						 img, 0, 0);
    478       for (row = 0; row < srcHeight; row++) {
    479 	 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
    480                                       dst, srcFormat, srcType, src,
    481                                       srcPacking);
    482 	 dst += srcWidth * components;
    483 	 src += srcStride;
    484       }
    485    }
    486 
    487    if (logicalBaseFormat != textureBaseFormat) {
    488       /* more work */
    489       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
    490       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
    491       GLuint *newImage;
    492       GLint i, n;
    493       GLubyte map[6];
    494 
    495       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
    496       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
    497              textureBaseFormat == GL_LUMINANCE_ALPHA);
    498 
    499       /* The actual texture format should have at least as many components
    500        * as the logical texture format.
    501        */
    502       ASSERT(texComponents >= logComponents);
    503 
    504       newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
    505                                    * texComponents * sizeof(GLuint));
    506       if (!newImage) {
    507          free(tempImage);
    508          return NULL;
    509       }
    510 
    511       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
    512 
    513       n = srcWidth * srcHeight * srcDepth;
    514       for (i = 0; i < n; i++) {
    515          GLint k;
    516          for (k = 0; k < texComponents; k++) {
    517             GLint j = map[k];
    518             if (j == ZERO)
    519                newImage[i * texComponents + k] = 0;
    520             else if (j == ONE)
    521                newImage[i * texComponents + k] = 1;
    522             else
    523                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
    524          }
    525       }
    526 
    527       free(tempImage);
    528       tempImage = newImage;
    529    }
    530 
    531    return tempImage;
    532 }
    533 
    534 
    535 
    536 /**
    537  * Make a temporary (color) texture image with GLubyte components.
    538  * Apply all needed pixel unpacking and pixel transfer operations.
    539  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
    540  * Suppose the user specifies GL_LUMINANCE as the internal texture format
    541  * but the graphics hardware doesn't support luminance textures.  So, we might
    542  * use an RGB hardware format instead.
    543  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
    544  *
    545  * \param ctx  the rendering context
    546  * \param dims  image dimensions: 1, 2 or 3
    547  * \param logicalBaseFormat  basic texture derived from the user's
    548  *    internal texture format value
    549  * \param textureBaseFormat  the actual basic format of the texture
    550  * \param srcWidth  source image width
    551  * \param srcHeight  source image height
    552  * \param srcDepth  source image depth
    553  * \param srcFormat  source image format
    554  * \param srcType  source image type
    555  * \param srcAddr  source image address
    556  * \param srcPacking  source image pixel packing
    557  * \return resulting image with format = textureBaseFormat and type = GLubyte.
    558  */
    559 GLubyte *
    560 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
    561                             GLenum logicalBaseFormat,
    562                             GLenum textureBaseFormat,
    563                             GLint srcWidth, GLint srcHeight, GLint srcDepth,
    564                             GLenum srcFormat, GLenum srcType,
    565                             const GLvoid *srcAddr,
    566                             const struct gl_pixelstore_attrib *srcPacking)
    567 {
    568    GLuint transferOps = ctx->_ImageTransferState;
    569    const GLint components = _mesa_components_in_format(logicalBaseFormat);
    570    GLint img, row;
    571    GLubyte *tempImage, *dst;
    572 
    573    ASSERT(dims >= 1 && dims <= 3);
    574 
    575    ASSERT(logicalBaseFormat == GL_RGBA ||
    576           logicalBaseFormat == GL_RGB ||
    577           logicalBaseFormat == GL_RG ||
    578           logicalBaseFormat == GL_RED ||
    579           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
    580           logicalBaseFormat == GL_LUMINANCE ||
    581           logicalBaseFormat == GL_ALPHA ||
    582           logicalBaseFormat == GL_INTENSITY);
    583 
    584    ASSERT(textureBaseFormat == GL_RGBA ||
    585           textureBaseFormat == GL_RGB ||
    586           textureBaseFormat == GL_RG ||
    587           textureBaseFormat == GL_RED ||
    588           textureBaseFormat == GL_LUMINANCE_ALPHA ||
    589           textureBaseFormat == GL_LUMINANCE ||
    590           textureBaseFormat == GL_ALPHA ||
    591           textureBaseFormat == GL_INTENSITY);
    592 
    593    /* unpack and transfer the source image */
    594    tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
    595                                        * components * sizeof(GLubyte));
    596    if (!tempImage) {
    597       return NULL;
    598    }
    599 
    600    dst = tempImage;
    601    for (img = 0; img < srcDepth; img++) {
    602       const GLint srcStride =
    603          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
    604       const GLubyte *src =
    605          (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
    606                                                srcWidth, srcHeight,
    607                                                srcFormat, srcType,
    608                                                img, 0, 0);
    609       for (row = 0; row < srcHeight; row++) {
    610          _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
    611                                        srcFormat, srcType, src, srcPacking,
    612                                        transferOps);
    613          dst += srcWidth * components;
    614          src += srcStride;
    615       }
    616    }
    617 
    618    if (logicalBaseFormat != textureBaseFormat) {
    619       /* one more conversion step */
    620       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
    621       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
    622       GLubyte *newImage;
    623       GLint i, n;
    624       GLubyte map[6];
    625 
    626       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
    627       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
    628              textureBaseFormat == GL_LUMINANCE_ALPHA);
    629 
    630       /* The actual texture format should have at least as many components
    631        * as the logical texture format.
    632        */
    633       ASSERT(texComponents >= logComponents);
    634 
    635       newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
    636                                          * texComponents * sizeof(GLubyte));
    637       if (!newImage) {
    638          free(tempImage);
    639          return NULL;
    640       }
    641 
    642       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
    643 
    644       n = srcWidth * srcHeight * srcDepth;
    645       for (i = 0; i < n; i++) {
    646          GLint k;
    647          for (k = 0; k < texComponents; k++) {
    648             GLint j = map[k];
    649             if (j == ZERO)
    650                newImage[i * texComponents + k] = 0;
    651             else if (j == ONE)
    652                newImage[i * texComponents + k] = 255;
    653             else
    654                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
    655          }
    656       }
    657 
    658       free(tempImage);
    659       tempImage = newImage;
    660    }
    661 
    662    return tempImage;
    663 }
    664 
    665 
    666 /**
    667  * Copy GLubyte pixels from <src> to <dst> with swizzling.
    668  * \param dst  destination pixels
    669  * \param dstComponents  number of color components in destination pixels
    670  * \param src  source pixels
    671  * \param srcComponents  number of color components in source pixels
    672  * \param map  the swizzle mapping.  map[X] says where to find the X component
    673  *             in the source image's pixels.  For example, if the source image
    674  *             is GL_BGRA and X = red, map[0] yields 2.
    675  * \param count  number of pixels to copy/swizzle.
    676  */
    677 static void
    678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
    679              GLuint srcComponents, const GLubyte *map, GLuint count)
    680 {
    681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
    682    do {                                              \
    683       GLuint i;                                      \
    684       for (i = 0; i < count; i++) {                  \
    685          GLuint j;                                   \
    686          if (srcComps == 4) {                        \
    687             COPY_4UBV(tmp, src);                     \
    688          }                                           \
    689          else {                                      \
    690             for (j = 0; j < srcComps; j++) {         \
    691                tmp[j] = src[j];                      \
    692             }                                        \
    693          }                                           \
    694          src += srcComps;                            \
    695          for (j = 0; j < dstComps; j++) {            \
    696             dst[j] = tmp[map[j]];                    \
    697          }                                           \
    698          dst += dstComps;                            \
    699       }                                              \
    700    } while (0)
    701 
    702    GLubyte tmp[6];
    703 
    704    tmp[ZERO] = 0x0;
    705    tmp[ONE] = 0xff;
    706 
    707    ASSERT(srcComponents <= 4);
    708    ASSERT(dstComponents <= 4);
    709 
    710    switch (dstComponents) {
    711    case 4:
    712       switch (srcComponents) {
    713       case 4:
    714          SWZ_CPY(dst, src, count, 4, 4);
    715          break;
    716       case 3:
    717          SWZ_CPY(dst, src, count, 4, 3);
    718          break;
    719       case 2:
    720          SWZ_CPY(dst, src, count, 4, 2);
    721          break;
    722       case 1:
    723          SWZ_CPY(dst, src, count, 4, 1);
    724          break;
    725       default:
    726          ;
    727       }
    728       break;
    729    case 3:
    730       switch (srcComponents) {
    731       case 4:
    732          SWZ_CPY(dst, src, count, 3, 4);
    733          break;
    734       case 3:
    735          SWZ_CPY(dst, src, count, 3, 3);
    736          break;
    737       case 2:
    738          SWZ_CPY(dst, src, count, 3, 2);
    739          break;
    740       case 1:
    741          SWZ_CPY(dst, src, count, 3, 1);
    742          break;
    743       default:
    744          ;
    745       }
    746       break;
    747    case 2:
    748       switch (srcComponents) {
    749       case 4:
    750          SWZ_CPY(dst, src, count, 2, 4);
    751          break;
    752       case 3:
    753          SWZ_CPY(dst, src, count, 2, 3);
    754          break;
    755       case 2:
    756          SWZ_CPY(dst, src, count, 2, 2);
    757          break;
    758       case 1:
    759          SWZ_CPY(dst, src, count, 2, 1);
    760          break;
    761       default:
    762          ;
    763       }
    764       break;
    765    case 1:
    766       switch (srcComponents) {
    767       case 4:
    768          SWZ_CPY(dst, src, count, 1, 4);
    769          break;
    770       case 3:
    771          SWZ_CPY(dst, src, count, 1, 3);
    772          break;
    773       case 2:
    774          SWZ_CPY(dst, src, count, 1, 2);
    775          break;
    776       case 1:
    777          SWZ_CPY(dst, src, count, 1, 1);
    778          break;
    779       default:
    780          ;
    781       }
    782       break;
    783    default:
    784       ;
    785    }
    786 #undef SWZ_CPY
    787 }
    788 
    789 
    790 
    791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
    792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
    793 
    794 
    795 /**
    796  * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
    797  * mapping array depending on endianness.
    798  */
    799 static const GLubyte *
    800 type_mapping( GLenum srcType )
    801 {
    802    switch (srcType) {
    803    case GL_BYTE:
    804    case GL_UNSIGNED_BYTE:
    805       return map_identity;
    806    case GL_UNSIGNED_INT_8_8_8_8:
    807       return _mesa_little_endian() ? map_3210 : map_identity;
    808    case GL_UNSIGNED_INT_8_8_8_8_REV:
    809       return _mesa_little_endian() ? map_identity : map_3210;
    810    default:
    811       return NULL;
    812    }
    813 }
    814 
    815 
    816 /**
    817  * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
    818  * mapping array depending on pixelstore byte swapping state.
    819  */
    820 static const GLubyte *
    821 byteswap_mapping( GLboolean swapBytes,
    822 		  GLenum srcType )
    823 {
    824    if (!swapBytes)
    825       return map_identity;
    826 
    827    switch (srcType) {
    828    case GL_BYTE:
    829    case GL_UNSIGNED_BYTE:
    830       return map_identity;
    831    case GL_UNSIGNED_INT_8_8_8_8:
    832    case GL_UNSIGNED_INT_8_8_8_8_REV:
    833       return map_3210;
    834    default:
    835       return NULL;
    836    }
    837 }
    838 
    839 
    840 
    841 /**
    842  * Transfer a GLubyte texture image with component swizzling.
    843  */
    844 static void
    845 _mesa_swizzle_ubyte_image(struct gl_context *ctx,
    846 			  GLuint dimensions,
    847 			  GLenum srcFormat,
    848 			  GLenum srcType,
    849 
    850 			  GLenum baseInternalFormat,
    851 
    852 			  const GLubyte *rgba2dst,
    853 			  GLuint dstComponents,
    854 
    855 			  GLint dstRowStride,
    856                           GLubyte **dstSlices,
    857 
    858 			  GLint srcWidth, GLint srcHeight, GLint srcDepth,
    859 			  const GLvoid *srcAddr,
    860 			  const struct gl_pixelstore_attrib *srcPacking )
    861 {
    862    GLint srcComponents = _mesa_components_in_format(srcFormat);
    863    const GLubyte *srctype2ubyte, *swap;
    864    GLubyte map[4], src2base[6], base2rgba[6];
    865    GLint i;
    866    const GLint srcRowStride =
    867       _mesa_image_row_stride(srcPacking, srcWidth,
    868                              srcFormat, GL_UNSIGNED_BYTE);
    869    const GLint srcImageStride
    870       = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
    871                                  GL_UNSIGNED_BYTE);
    872    const GLubyte *srcImage
    873       = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
    874                                               srcWidth, srcHeight, srcFormat,
    875                                               GL_UNSIGNED_BYTE, 0, 0, 0);
    876 
    877    (void) ctx;
    878 
    879    /* Translate from src->baseInternal->GL_RGBA->dst.  This will
    880     * correctly deal with RGBA->RGB->RGBA conversions where the final
    881     * A value must be 0xff regardless of the incoming alpha values.
    882     */
    883    compute_component_mapping(srcFormat, baseInternalFormat, src2base);
    884    compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
    885    swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
    886    srctype2ubyte = type_mapping(srcType);
    887 
    888 
    889    for (i = 0; i < 4; i++)
    890       map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
    891 
    892 /*    printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
    893 
    894    if (srcComponents == dstComponents &&
    895        srcRowStride == dstRowStride &&
    896        srcRowStride == srcWidth * srcComponents &&
    897        dimensions < 3) {
    898       /* 1 and 2D images only */
    899       GLubyte *dstImage = dstSlices[0];
    900       swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
    901 		   srcWidth * srcHeight);
    902    }
    903    else {
    904       GLint img, row;
    905       for (img = 0; img < srcDepth; img++) {
    906          const GLubyte *srcRow = srcImage;
    907          GLubyte *dstRow = dstSlices[img];
    908          for (row = 0; row < srcHeight; row++) {
    909 	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
    910             dstRow += dstRowStride;
    911             srcRow += srcRowStride;
    912          }
    913          srcImage += srcImageStride;
    914       }
    915    }
    916 }
    917 
    918 
    919 /**
    920  * Teximage storage routine for when a simple memcpy will do.
    921  * No pixel transfer operations or special texel encodings allowed.
    922  * 1D, 2D and 3D images supported.
    923  */
    924 static void
    925 memcpy_texture(struct gl_context *ctx,
    926 	       GLuint dimensions,
    927                gl_format dstFormat,
    928                GLint dstRowStride,
    929                GLubyte **dstSlices,
    930                GLint srcWidth, GLint srcHeight, GLint srcDepth,
    931                GLenum srcFormat, GLenum srcType,
    932                const GLvoid *srcAddr,
    933                const struct gl_pixelstore_attrib *srcPacking)
    934 {
    935    const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
    936                                                      srcFormat, srcType);
    937    const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
    938                                       srcWidth, srcHeight, srcFormat, srcType);
    939    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
    940         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
    941    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
    942    const GLint bytesPerRow = srcWidth * texelBytes;
    943 
    944    if (dstRowStride == srcRowStride &&
    945        dstRowStride == bytesPerRow) {
    946       /* memcpy image by image */
    947       GLint img;
    948       for (img = 0; img < srcDepth; img++) {
    949          GLubyte *dstImage = dstSlices[img];
    950          memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
    951          srcImage += srcImageStride;
    952       }
    953    }
    954    else {
    955       /* memcpy row by row */
    956       GLint img, row;
    957       for (img = 0; img < srcDepth; img++) {
    958          const GLubyte *srcRow = srcImage;
    959          GLubyte *dstRow = dstSlices[img];
    960          for (row = 0; row < srcHeight; row++) {
    961             memcpy(dstRow, srcRow, bytesPerRow);
    962             dstRow += dstRowStride;
    963             srcRow += srcRowStride;
    964          }
    965          srcImage += srcImageStride;
    966       }
    967    }
    968 }
    969 
    970 
    971 /**
    972  * General-case function for storing a color texture images with
    973  * components that can be represented with ubytes.  Example destination
    974  * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
    975  */
    976 static GLboolean
    977 store_ubyte_texture(TEXSTORE_PARAMS)
    978 {
    979    const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
    980    GLubyte *tempImage, *src;
    981    GLint img;
    982 
    983    tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
    984                                            baseInternalFormat,
    985                                            GL_RGBA,
    986                                            srcWidth, srcHeight, srcDepth,
    987                                            srcFormat, srcType, srcAddr,
    988                                            srcPacking);
    989    if (!tempImage)
    990       return GL_FALSE;
    991 
    992    src = tempImage;
    993    for (img = 0; img < srcDepth; img++) {
    994       _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
    995                                  src, srcRowStride,
    996                                  dstSlices[img], dstRowStride);
    997       src += srcHeight * srcRowStride;
    998    }
    999    free(tempImage);
   1000 
   1001    return GL_TRUE;
   1002 }
   1003 
   1004 
   1005 
   1006 
   1007 /**
   1008  * Store a 32-bit integer or float depth component texture image.
   1009  */
   1010 static GLboolean
   1011 _mesa_texstore_z32(TEXSTORE_PARAMS)
   1012 {
   1013    const GLuint depthScale = 0xffffffff;
   1014    GLenum dstType;
   1015    (void) dims;
   1016    ASSERT(dstFormat == MESA_FORMAT_Z32 ||
   1017           dstFormat == MESA_FORMAT_Z32_FLOAT);
   1018    ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
   1019 
   1020    if (dstFormat == MESA_FORMAT_Z32)
   1021       dstType = GL_UNSIGNED_INT;
   1022    else
   1023       dstType = GL_FLOAT;
   1024 
   1025    if (ctx->Pixel.DepthScale == 1.0f &&
   1026        ctx->Pixel.DepthBias == 0.0f &&
   1027        !srcPacking->SwapBytes &&
   1028        baseInternalFormat == GL_DEPTH_COMPONENT &&
   1029        srcFormat == GL_DEPTH_COMPONENT &&
   1030        srcType == dstType) {
   1031       /* simple memcpy path */
   1032       memcpy_texture(ctx, dims,
   1033                      dstFormat,
   1034                      dstRowStride, dstSlices,
   1035                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1036                      srcAddr, srcPacking);
   1037    }
   1038    else {
   1039       /* general path */
   1040       GLint img, row;
   1041       for (img = 0; img < srcDepth; img++) {
   1042          GLubyte *dstRow = dstSlices[img];
   1043          for (row = 0; row < srcHeight; row++) {
   1044             const GLvoid *src = _mesa_image_address(dims, srcPacking,
   1045                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
   1046             _mesa_unpack_depth_span(ctx, srcWidth,
   1047                                     dstType, dstRow,
   1048                                     depthScale, srcType, src, srcPacking);
   1049             dstRow += dstRowStride;
   1050          }
   1051       }
   1052    }
   1053    return GL_TRUE;
   1054 }
   1055 
   1056 
   1057 /**
   1058  * Store a 24-bit integer depth component texture image.
   1059  */
   1060 static GLboolean
   1061 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
   1062 {
   1063    const GLuint depthScale = 0xffffff;
   1064 
   1065    (void) dims;
   1066    ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
   1067 
   1068    {
   1069       /* general path */
   1070       GLint img, row;
   1071       for (img = 0; img < srcDepth; img++) {
   1072          GLubyte *dstRow = dstSlices[img];
   1073          for (row = 0; row < srcHeight; row++) {
   1074             const GLvoid *src = _mesa_image_address(dims, srcPacking,
   1075                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
   1076             _mesa_unpack_depth_span(ctx, srcWidth,
   1077                                     GL_UNSIGNED_INT, (GLuint *) dstRow,
   1078                                     depthScale, srcType, src, srcPacking);
   1079             dstRow += dstRowStride;
   1080          }
   1081       }
   1082    }
   1083    return GL_TRUE;
   1084 }
   1085 
   1086 
   1087 /**
   1088  * Store a 24-bit integer depth component texture image.
   1089  */
   1090 static GLboolean
   1091 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
   1092 {
   1093    const GLuint depthScale = 0xffffff;
   1094 
   1095    (void) dims;
   1096    ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
   1097 
   1098    {
   1099       /* general path */
   1100       GLint img, row;
   1101       for (img = 0; img < srcDepth; img++) {
   1102          GLubyte *dstRow = dstSlices[img];
   1103          for (row = 0; row < srcHeight; row++) {
   1104             const GLvoid *src = _mesa_image_address(dims, srcPacking,
   1105                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
   1106             GLuint *dst = (GLuint *) dstRow;
   1107             GLint i;
   1108             _mesa_unpack_depth_span(ctx, srcWidth,
   1109                                     GL_UNSIGNED_INT, dst,
   1110                                     depthScale, srcType, src, srcPacking);
   1111             for (i = 0; i < srcWidth; i++)
   1112                dst[i] <<= 8;
   1113             dstRow += dstRowStride;
   1114          }
   1115       }
   1116    }
   1117    return GL_TRUE;
   1118 }
   1119 
   1120 
   1121 /**
   1122  * Store a 16-bit integer depth component texture image.
   1123  */
   1124 static GLboolean
   1125 _mesa_texstore_z16(TEXSTORE_PARAMS)
   1126 {
   1127    const GLuint depthScale = 0xffff;
   1128    (void) dims;
   1129    ASSERT(dstFormat == MESA_FORMAT_Z16);
   1130    ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
   1131 
   1132    if (ctx->Pixel.DepthScale == 1.0f &&
   1133        ctx->Pixel.DepthBias == 0.0f &&
   1134        !srcPacking->SwapBytes &&
   1135        baseInternalFormat == GL_DEPTH_COMPONENT &&
   1136        srcFormat == GL_DEPTH_COMPONENT &&
   1137        srcType == GL_UNSIGNED_SHORT) {
   1138       /* simple memcpy path */
   1139       memcpy_texture(ctx, dims,
   1140                      dstFormat,
   1141                      dstRowStride, dstSlices,
   1142                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1143                      srcAddr, srcPacking);
   1144    }
   1145    else {
   1146       /* general path */
   1147       GLint img, row;
   1148       for (img = 0; img < srcDepth; img++) {
   1149          GLubyte *dstRow = dstSlices[img];
   1150          for (row = 0; row < srcHeight; row++) {
   1151             const GLvoid *src = _mesa_image_address(dims, srcPacking,
   1152                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
   1153             GLushort *dst16 = (GLushort *) dstRow;
   1154             _mesa_unpack_depth_span(ctx, srcWidth,
   1155                                     GL_UNSIGNED_SHORT, dst16, depthScale,
   1156                                     srcType, src, srcPacking);
   1157             dstRow += dstRowStride;
   1158          }
   1159       }
   1160    }
   1161    return GL_TRUE;
   1162 }
   1163 
   1164 
   1165 /**
   1166  * Store an rgb565 or rgb565_rev texture image.
   1167  */
   1168 static GLboolean
   1169 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
   1170 {
   1171    ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
   1172           dstFormat == MESA_FORMAT_RGB565_REV);
   1173    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   1174 
   1175    if (!ctx->_ImageTransferState &&
   1176        baseInternalFormat == GL_RGB &&
   1177        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1178                                             srcPacking->SwapBytes)) {
   1179       /* simple memcpy path */
   1180       memcpy_texture(ctx, dims,
   1181                      dstFormat,
   1182                      dstRowStride, dstSlices,
   1183                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1184                      srcAddr, srcPacking);
   1185    }
   1186    else if (!ctx->_ImageTransferState &&
   1187             !srcPacking->SwapBytes &&
   1188             baseInternalFormat == GL_RGB &&
   1189             srcFormat == GL_RGB &&
   1190             srcType == GL_UNSIGNED_BYTE &&
   1191             dims == 2) {
   1192       /* do optimized tex store */
   1193       const GLint srcRowStride =
   1194          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1195       const GLubyte *src = (const GLubyte *)
   1196          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
   1197                              srcFormat, srcType, 0, 0, 0);
   1198       GLubyte *dst = dstSlices[0];
   1199       GLint row, col;
   1200       for (row = 0; row < srcHeight; row++) {
   1201          const GLubyte *srcUB = (const GLubyte *) src;
   1202          GLushort *dstUS = (GLushort *) dst;
   1203          /* check for byteswapped format */
   1204          if (dstFormat == MESA_FORMAT_RGB565) {
   1205             for (col = 0; col < srcWidth; col++) {
   1206                dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
   1207                srcUB += 3;
   1208             }
   1209          }
   1210          else {
   1211             for (col = 0; col < srcWidth; col++) {
   1212                dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
   1213                srcUB += 3;
   1214             }
   1215          }
   1216          dst += dstRowStride;
   1217          src += srcRowStride;
   1218       }
   1219    }
   1220    else {
   1221       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1222                                  dstFormat, dstRowStride, dstSlices,
   1223                                  srcWidth, srcHeight, srcDepth,
   1224                                  srcFormat, srcType, srcAddr, srcPacking);
   1225    }
   1226    return GL_TRUE;
   1227 }
   1228 
   1229 
   1230 /**
   1231  * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
   1232  */
   1233 static GLboolean
   1234 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
   1235 {
   1236    const GLboolean littleEndian = _mesa_little_endian();
   1237 
   1238    ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
   1239           dstFormat == MESA_FORMAT_RGBA8888_REV ||
   1240           dstFormat == MESA_FORMAT_RGBX8888 ||
   1241           dstFormat == MESA_FORMAT_RGBX8888_REV);
   1242    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   1243 
   1244    if (!ctx->_ImageTransferState &&
   1245        baseInternalFormat == GL_RGBA &&
   1246        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1247                                             srcPacking->SwapBytes)) {
   1248       /* simple memcpy path */
   1249       memcpy_texture(ctx, dims,
   1250                      dstFormat,
   1251                      dstRowStride, dstSlices,
   1252                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1253                      srcAddr, srcPacking);
   1254    }
   1255    else if (!ctx->_ImageTransferState &&
   1256 	    (srcType == GL_UNSIGNED_BYTE ||
   1257 	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
   1258 	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
   1259 	    can_swizzle(baseInternalFormat) &&
   1260 	    can_swizzle(srcFormat)) {
   1261 
   1262       GLubyte dstmap[4];
   1263 
   1264       /* dstmap - how to swizzle from RGBA to dst format:
   1265        */
   1266       if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
   1267                             dstFormat == MESA_FORMAT_RGBX8888)) ||
   1268 	  (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
   1269 	                     dstFormat == MESA_FORMAT_RGBX8888_REV))) {
   1270 	 dstmap[3] = 0;
   1271 	 dstmap[2] = 1;
   1272 	 dstmap[1] = 2;
   1273 	 dstmap[0] = 3;
   1274       }
   1275       else {
   1276 	 dstmap[3] = 3;
   1277 	 dstmap[2] = 2;
   1278 	 dstmap[1] = 1;
   1279 	 dstmap[0] = 0;
   1280       }
   1281 
   1282       _mesa_swizzle_ubyte_image(ctx, dims,
   1283 				srcFormat,
   1284 				srcType,
   1285 				baseInternalFormat,
   1286 				dstmap, 4,
   1287 				dstRowStride, dstSlices,
   1288 				srcWidth, srcHeight, srcDepth, srcAddr,
   1289 				srcPacking);
   1290    }
   1291    else {
   1292       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1293                                  dstFormat, dstRowStride, dstSlices,
   1294                                  srcWidth, srcHeight, srcDepth,
   1295                                  srcFormat, srcType, srcAddr, srcPacking);
   1296    }
   1297    return GL_TRUE;
   1298 }
   1299 
   1300 
   1301 static GLboolean
   1302 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
   1303 {
   1304    const GLboolean littleEndian = _mesa_little_endian();
   1305 
   1306    ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
   1307           dstFormat == MESA_FORMAT_ARGB8888_REV ||
   1308           dstFormat == MESA_FORMAT_XRGB8888 ||
   1309           dstFormat == MESA_FORMAT_XRGB8888_REV );
   1310    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   1311 
   1312    if (!ctx->_ImageTransferState &&
   1313        baseInternalFormat == GL_RGBA &&
   1314        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1315                                             srcPacking->SwapBytes)) {
   1316       /* simple memcpy path (big endian) */
   1317       memcpy_texture(ctx, dims,
   1318                      dstFormat,
   1319                      dstRowStride, dstSlices,
   1320                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1321                      srcAddr, srcPacking);
   1322    }
   1323    else if (!ctx->_ImageTransferState &&
   1324             !srcPacking->SwapBytes &&
   1325 	    (dstFormat == MESA_FORMAT_ARGB8888 ||
   1326              dstFormat == MESA_FORMAT_XRGB8888) &&
   1327             srcFormat == GL_RGB &&
   1328 	    (baseInternalFormat == GL_RGBA ||
   1329 	     baseInternalFormat == GL_RGB) &&
   1330             srcType == GL_UNSIGNED_BYTE) {
   1331       int img, row, col;
   1332       for (img = 0; img < srcDepth; img++) {
   1333          const GLint srcRowStride =
   1334             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1335          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
   1336                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
   1337          GLubyte *dstRow = dstSlices[img];
   1338          for (row = 0; row < srcHeight; row++) {
   1339             GLuint *d4 = (GLuint *) dstRow;
   1340             for (col = 0; col < srcWidth; col++) {
   1341                d4[col] = PACK_COLOR_8888(0xff,
   1342                                          srcRow[col * 3 + RCOMP],
   1343                                          srcRow[col * 3 + GCOMP],
   1344                                          srcRow[col * 3 + BCOMP]);
   1345             }
   1346             dstRow += dstRowStride;
   1347             srcRow += srcRowStride;
   1348          }
   1349       }
   1350    }
   1351    else if (!ctx->_ImageTransferState &&
   1352             !srcPacking->SwapBytes &&
   1353             dstFormat == MESA_FORMAT_ARGB8888 &&
   1354             srcFormat == GL_LUMINANCE_ALPHA &&
   1355             baseInternalFormat == GL_RGBA &&
   1356             srcType == GL_UNSIGNED_BYTE) {
   1357       /* special case of storing LA -> ARGB8888 */
   1358       int img, row, col;
   1359       const GLint srcRowStride =
   1360          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1361       for (img = 0; img < srcDepth; img++) {
   1362          const GLubyte *srcRow = (const GLubyte *)
   1363             _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
   1364                                 srcHeight, srcFormat, srcType, img, 0, 0);
   1365          GLubyte *dstRow = dstSlices[img];
   1366          for (row = 0; row < srcHeight; row++) {
   1367             GLuint *d4 = (GLuint *) dstRow;
   1368             for (col = 0; col < srcWidth; col++) {
   1369                GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
   1370                d4[col] = PACK_COLOR_8888(a, l, l, l);
   1371             }
   1372             dstRow += dstRowStride;
   1373             srcRow += srcRowStride;
   1374          }
   1375       }
   1376    }
   1377    else if (!ctx->_ImageTransferState &&
   1378             !srcPacking->SwapBytes &&
   1379 	    dstFormat == MESA_FORMAT_ARGB8888 &&
   1380             srcFormat == GL_RGBA &&
   1381 	    baseInternalFormat == GL_RGBA &&
   1382             srcType == GL_UNSIGNED_BYTE) {
   1383       /* same as above case, but src data has alpha too */
   1384       GLint img, row, col;
   1385       /* For some reason, streaming copies to write-combined regions
   1386        * are extremely sensitive to the characteristics of how the
   1387        * source data is retrieved.  By reordering the source reads to
   1388        * be in-order, the speed of this operation increases by half.
   1389        * Strangely the same isn't required for the RGB path, above.
   1390        */
   1391       for (img = 0; img < srcDepth; img++) {
   1392          const GLint srcRowStride =
   1393             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1394          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
   1395                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
   1396          GLubyte *dstRow = dstSlices[img];
   1397          for (row = 0; row < srcHeight; row++) {
   1398             GLuint *d4 = (GLuint *) dstRow;
   1399             for (col = 0; col < srcWidth; col++) {
   1400                d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
   1401                                          srcRow[col * 4 + RCOMP],
   1402                                          srcRow[col * 4 + GCOMP],
   1403                                          srcRow[col * 4 + BCOMP]);
   1404             }
   1405             dstRow += dstRowStride;
   1406             srcRow += srcRowStride;
   1407          }
   1408       }
   1409    }
   1410    else if (!ctx->_ImageTransferState &&
   1411 	    (srcType == GL_UNSIGNED_BYTE ||
   1412 	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
   1413 	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
   1414 	    can_swizzle(baseInternalFormat) &&
   1415 	    can_swizzle(srcFormat)) {
   1416 
   1417       GLubyte dstmap[4];
   1418 
   1419       /* dstmap - how to swizzle from RGBA to dst format:
   1420        */
   1421       if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
   1422           (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
   1423 	  (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
   1424 	  (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
   1425 	 dstmap[3] = 3;		/* alpha */
   1426 	 dstmap[2] = 0;		/* red */
   1427 	 dstmap[1] = 1;		/* green */
   1428 	 dstmap[0] = 2;		/* blue */
   1429       }
   1430       else {
   1431 	 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
   1432 		(!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
   1433 		(littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
   1434 		(!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
   1435 	 dstmap[3] = 2;
   1436 	 dstmap[2] = 1;
   1437 	 dstmap[1] = 0;
   1438 	 dstmap[0] = 3;
   1439       }
   1440 
   1441       _mesa_swizzle_ubyte_image(ctx, dims,
   1442 				srcFormat,
   1443 				srcType,
   1444 				baseInternalFormat,
   1445 				dstmap, 4,
   1446 				dstRowStride,
   1447                                 dstSlices,
   1448 				srcWidth, srcHeight, srcDepth, srcAddr,
   1449 				srcPacking);
   1450    }
   1451    else {
   1452       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1453                                  dstFormat, dstRowStride, dstSlices,
   1454                                  srcWidth, srcHeight, srcDepth,
   1455                                  srcFormat, srcType, srcAddr, srcPacking);
   1456    }
   1457    return GL_TRUE;
   1458 }
   1459 
   1460 
   1461 static GLboolean
   1462 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
   1463 {
   1464    ASSERT(dstFormat == MESA_FORMAT_RGB888);
   1465    ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
   1466 
   1467    if (!ctx->_ImageTransferState &&
   1468        baseInternalFormat == GL_RGB &&
   1469        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1470                                             srcPacking->SwapBytes)) {
   1471       /* simple memcpy path */
   1472       memcpy_texture(ctx, dims,
   1473                      dstFormat,
   1474                      dstRowStride, dstSlices,
   1475                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1476                      srcAddr, srcPacking);
   1477    }
   1478    else if (!ctx->_ImageTransferState &&
   1479             !srcPacking->SwapBytes &&
   1480             srcFormat == GL_RGBA &&
   1481             srcType == GL_UNSIGNED_BYTE) {
   1482       /* extract RGB from RGBA */
   1483       GLint img, row, col;
   1484       for (img = 0; img < srcDepth; img++) {
   1485          const GLint srcRowStride =
   1486             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1487          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
   1488                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
   1489          GLubyte *dstRow = dstSlices[img];
   1490          for (row = 0; row < srcHeight; row++) {
   1491             for (col = 0; col < srcWidth; col++) {
   1492                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
   1493                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
   1494                dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
   1495             }
   1496             dstRow += dstRowStride;
   1497             srcRow += srcRowStride;
   1498          }
   1499       }
   1500    }
   1501    else if (!ctx->_ImageTransferState &&
   1502 	    srcType == GL_UNSIGNED_BYTE &&
   1503 	    can_swizzle(baseInternalFormat) &&
   1504 	    can_swizzle(srcFormat)) {
   1505 
   1506       GLubyte dstmap[4];
   1507 
   1508       /* dstmap - how to swizzle from RGBA to dst format:
   1509        */
   1510       dstmap[0] = 2;
   1511       dstmap[1] = 1;
   1512       dstmap[2] = 0;
   1513       dstmap[3] = ONE;		/* ? */
   1514 
   1515       _mesa_swizzle_ubyte_image(ctx, dims,
   1516 				srcFormat,
   1517 				srcType,
   1518 				baseInternalFormat,
   1519 				dstmap, 3,
   1520 				dstRowStride, dstSlices,
   1521 				srcWidth, srcHeight, srcDepth, srcAddr,
   1522 				srcPacking);
   1523    }
   1524    else {
   1525       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1526                                  dstFormat, dstRowStride, dstSlices,
   1527                                  srcWidth, srcHeight, srcDepth,
   1528                                  srcFormat, srcType, srcAddr, srcPacking);
   1529    }
   1530    return GL_TRUE;
   1531 }
   1532 
   1533 
   1534 static GLboolean
   1535 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
   1536 {
   1537    ASSERT(dstFormat == MESA_FORMAT_BGR888);
   1538    ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
   1539 
   1540    if (!ctx->_ImageTransferState &&
   1541        baseInternalFormat == GL_RGB &&
   1542        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1543                                             srcPacking->SwapBytes)) {
   1544       /* simple memcpy path */
   1545       memcpy_texture(ctx, dims,
   1546                      dstFormat,
   1547                      dstRowStride, dstSlices,
   1548                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1549                      srcAddr, srcPacking);
   1550    }
   1551    else if (!ctx->_ImageTransferState &&
   1552             !srcPacking->SwapBytes &&
   1553             srcFormat == GL_RGBA &&
   1554             srcType == GL_UNSIGNED_BYTE) {
   1555       /* extract BGR from RGBA */
   1556       int img, row, col;
   1557       for (img = 0; img < srcDepth; img++) {
   1558          const GLint srcRowStride =
   1559             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   1560          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
   1561                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
   1562          GLubyte *dstRow = dstSlices[img];
   1563          for (row = 0; row < srcHeight; row++) {
   1564             for (col = 0; col < srcWidth; col++) {
   1565                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
   1566                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
   1567                dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
   1568             }
   1569             dstRow += dstRowStride;
   1570             srcRow += srcRowStride;
   1571          }
   1572       }
   1573    }
   1574    else if (!ctx->_ImageTransferState &&
   1575 	    srcType == GL_UNSIGNED_BYTE &&
   1576 	    can_swizzle(baseInternalFormat) &&
   1577 	    can_swizzle(srcFormat)) {
   1578 
   1579       GLubyte dstmap[4];
   1580 
   1581       /* dstmap - how to swizzle from RGBA to dst format:
   1582        */
   1583       dstmap[0] = 0;
   1584       dstmap[1] = 1;
   1585       dstmap[2] = 2;
   1586       dstmap[3] = ONE;		/* ? */
   1587 
   1588       _mesa_swizzle_ubyte_image(ctx, dims,
   1589 				srcFormat,
   1590 				srcType,
   1591 				baseInternalFormat,
   1592 				dstmap, 3,
   1593 				dstRowStride, dstSlices,
   1594 				srcWidth, srcHeight, srcDepth, srcAddr,
   1595 				srcPacking);
   1596    }
   1597    else {
   1598       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1599                                  dstFormat, dstRowStride, dstSlices,
   1600                                  srcWidth, srcHeight, srcDepth,
   1601                                  srcFormat, srcType, srcAddr, srcPacking);
   1602    }
   1603    return GL_TRUE;
   1604 }
   1605 
   1606 
   1607 static GLboolean
   1608 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
   1609 {
   1610    ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
   1611           dstFormat == MESA_FORMAT_ARGB4444_REV);
   1612    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   1613 
   1614    if (!ctx->_ImageTransferState &&
   1615        baseInternalFormat == GL_RGBA &&
   1616        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1617                                             srcPacking->SwapBytes)) {
   1618       /* simple memcpy path */
   1619       memcpy_texture(ctx, dims,
   1620                      dstFormat,
   1621                      dstRowStride, dstSlices,
   1622                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1623                      srcAddr, srcPacking);
   1624    }
   1625    else {
   1626       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1627                                  dstFormat, dstRowStride, dstSlices,
   1628                                  srcWidth, srcHeight, srcDepth,
   1629                                  srcFormat, srcType, srcAddr, srcPacking);
   1630    }
   1631    return GL_TRUE;
   1632 }
   1633 
   1634 static GLboolean
   1635 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
   1636 {
   1637    ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
   1638    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   1639 
   1640    if (!ctx->_ImageTransferState &&
   1641        baseInternalFormat == GL_RGBA &&
   1642        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1643                                             srcPacking->SwapBytes)) {
   1644       /* simple memcpy path */
   1645       memcpy_texture(ctx, dims,
   1646                      dstFormat,
   1647                      dstRowStride, dstSlices,
   1648                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1649                      srcAddr, srcPacking);
   1650    }
   1651    else {
   1652       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1653                                  dstFormat, dstRowStride, dstSlices,
   1654                                  srcWidth, srcHeight, srcDepth,
   1655                                  srcFormat, srcType, srcAddr, srcPacking);
   1656    }
   1657    return GL_TRUE;
   1658 }
   1659 
   1660 static GLboolean
   1661 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
   1662 {
   1663    ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
   1664           dstFormat == MESA_FORMAT_ARGB1555_REV);
   1665    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   1666 
   1667    if (!ctx->_ImageTransferState &&
   1668        baseInternalFormat == GL_RGBA &&
   1669        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1670                                             srcPacking->SwapBytes)) {
   1671       /* simple memcpy path */
   1672       memcpy_texture(ctx, dims,
   1673                      dstFormat,
   1674                      dstRowStride, dstSlices,
   1675                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1676                      srcAddr, srcPacking);
   1677    }
   1678    else {
   1679       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   1680                                  dstFormat, dstRowStride, dstSlices,
   1681                                  srcWidth, srcHeight, srcDepth,
   1682                                  srcFormat, srcType, srcAddr, srcPacking);
   1683    }
   1684    return GL_TRUE;
   1685 }
   1686 
   1687 
   1688 static GLboolean
   1689 _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
   1690 {
   1691    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   1692 
   1693    ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
   1694    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   1695 
   1696    if (!ctx->_ImageTransferState &&
   1697        baseInternalFormat == GL_RGBA &&
   1698        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   1699                                             srcPacking->SwapBytes)) {
   1700       /* simple memcpy path */
   1701       memcpy_texture(ctx, dims,
   1702                      dstFormat,
   1703                      dstRowStride, dstSlices,
   1704                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1705                      srcAddr, srcPacking);
   1706    }
   1707    else {
   1708       /* general path */
   1709       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   1710                                                  baseInternalFormat,
   1711                                                  baseFormat,
   1712                                                  srcWidth, srcHeight, srcDepth,
   1713                                                  srcFormat, srcType, srcAddr,
   1714                                                  srcPacking,
   1715                                                  ctx->_ImageTransferState);
   1716       const GLfloat *src = tempImage;
   1717       GLint img, row, col;
   1718       if (!tempImage)
   1719          return GL_FALSE;
   1720       for (img = 0; img < srcDepth; img++) {
   1721          GLubyte *dstRow = dstSlices[img];
   1722          if (baseInternalFormat == GL_RGBA) {
   1723             for (row = 0; row < srcHeight; row++) {
   1724                GLuint *dstUI = (GLuint *) dstRow;
   1725                for (col = 0; col < srcWidth; col++) {
   1726                   GLushort a,r,g,b;
   1727 
   1728                   UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
   1729                   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
   1730                   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
   1731                   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
   1732                   dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
   1733                   src += 4;
   1734                }
   1735                dstRow += dstRowStride;
   1736             }
   1737          } else if (baseInternalFormat == GL_RGB) {
   1738             for (row = 0; row < srcHeight; row++) {
   1739                GLuint *dstUI = (GLuint *) dstRow;
   1740                for (col = 0; col < srcWidth; col++) {
   1741                   GLushort r,g,b;
   1742 
   1743                   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
   1744                   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
   1745                   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
   1746                   dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
   1747                   src += 4;
   1748                }
   1749                dstRow += dstRowStride;
   1750             }
   1751          } else {
   1752             ASSERT(0);
   1753          }
   1754       }
   1755       free((void *) tempImage);
   1756    }
   1757    return GL_TRUE;
   1758 }
   1759 
   1760 
   1761 /**
   1762  * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
   1763  */
   1764 static GLboolean
   1765 _mesa_texstore_unorm44(TEXSTORE_PARAMS)
   1766 {
   1767    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   1768 
   1769    ASSERT(dstFormat == MESA_FORMAT_AL44);
   1770    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
   1771 
   1772    {
   1773       /* general path */
   1774       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
   1775                                                  baseInternalFormat,
   1776                                                  baseFormat,
   1777                                                  srcWidth, srcHeight, srcDepth,
   1778                                                  srcFormat, srcType, srcAddr,
   1779                                                  srcPacking);
   1780       const GLubyte *src = tempImage;
   1781       GLint img, row, col;
   1782       if (!tempImage)
   1783          return GL_FALSE;
   1784       for (img = 0; img < srcDepth; img++) {
   1785          GLubyte *dstRow = dstSlices[img];
   1786          for (row = 0; row < srcHeight; row++) {
   1787             GLubyte *dstUS = (GLubyte *) dstRow;
   1788             for (col = 0; col < srcWidth; col++) {
   1789                /* src[0] is luminance, src[1] is alpha */
   1790                dstUS[col] = PACK_COLOR_44( src[1],
   1791                                            src[0] );
   1792                src += 2;
   1793             }
   1794             dstRow += dstRowStride;
   1795          }
   1796       }
   1797       free((void *) tempImage);
   1798    }
   1799    return GL_TRUE;
   1800 }
   1801 
   1802 
   1803 /**
   1804  * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
   1805  */
   1806 static GLboolean
   1807 _mesa_texstore_unorm88(TEXSTORE_PARAMS)
   1808 {
   1809    const GLboolean littleEndian = _mesa_little_endian();
   1810    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   1811 
   1812    ASSERT(dstFormat == MESA_FORMAT_AL88 ||
   1813           dstFormat == MESA_FORMAT_AL88_REV ||
   1814           dstFormat == MESA_FORMAT_GR88 ||
   1815           dstFormat == MESA_FORMAT_RG88);
   1816    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   1817 
   1818    if (!ctx->_ImageTransferState &&
   1819        !srcPacking->SwapBytes &&
   1820        ((dstFormat == MESA_FORMAT_AL88 &&
   1821          baseInternalFormat == GL_LUMINANCE_ALPHA &&
   1822          srcFormat == GL_LUMINANCE_ALPHA) ||
   1823         (dstFormat == MESA_FORMAT_GR88 &&
   1824          baseInternalFormat == srcFormat)) &&
   1825        srcType == GL_UNSIGNED_BYTE &&
   1826        littleEndian) {
   1827       /* simple memcpy path */
   1828       memcpy_texture(ctx, dims,
   1829                      dstFormat,
   1830                      dstRowStride, dstSlices,
   1831                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1832                      srcAddr, srcPacking);
   1833    }
   1834    else if (!ctx->_ImageTransferState &&
   1835 	    littleEndian &&
   1836 	    srcType == GL_UNSIGNED_BYTE &&
   1837 	    can_swizzle(baseInternalFormat) &&
   1838 	    can_swizzle(srcFormat)) {
   1839       GLubyte dstmap[4];
   1840 
   1841       /* dstmap - how to swizzle from RGBA to dst format:
   1842        */
   1843       if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
   1844 	 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
   1845 	     (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
   1846 	    dstmap[0] = 0;
   1847 	    dstmap[1] = 3;
   1848 	 }
   1849 	 else {
   1850 	    dstmap[0] = 3;
   1851 	    dstmap[1] = 0;
   1852 	 }
   1853       }
   1854       else {
   1855 	 if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
   1856 	     (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
   1857 	    dstmap[0] = 0;
   1858 	    dstmap[1] = 1;
   1859 	 }
   1860 	 else {
   1861 	    dstmap[0] = 1;
   1862 	    dstmap[1] = 0;
   1863 	 }
   1864       }
   1865       dstmap[2] = ZERO;		/* ? */
   1866       dstmap[3] = ONE;		/* ? */
   1867 
   1868       _mesa_swizzle_ubyte_image(ctx, dims,
   1869 				srcFormat,
   1870 				srcType,
   1871 				baseInternalFormat,
   1872 				dstmap, 2,
   1873 				dstRowStride, dstSlices,
   1874 				srcWidth, srcHeight, srcDepth, srcAddr,
   1875 				srcPacking);
   1876    }
   1877    else {
   1878       /* general path */
   1879       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
   1880                                                  baseInternalFormat,
   1881                                                  baseFormat,
   1882                                                  srcWidth, srcHeight, srcDepth,
   1883                                                  srcFormat, srcType, srcAddr,
   1884                                                  srcPacking);
   1885       const GLubyte *src = tempImage;
   1886       GLint img, row, col;
   1887       if (!tempImage)
   1888          return GL_FALSE;
   1889       for (img = 0; img < srcDepth; img++) {
   1890          GLubyte *dstRow = dstSlices[img];
   1891          for (row = 0; row < srcHeight; row++) {
   1892             GLushort *dstUS = (GLushort *) dstRow;
   1893             if (dstFormat == MESA_FORMAT_AL88 ||
   1894 		dstFormat == MESA_FORMAT_GR88) {
   1895                for (col = 0; col < srcWidth; col++) {
   1896                   /* src[0] is luminance (or R), src[1] is alpha (or G) */
   1897                  dstUS[col] = PACK_COLOR_88( src[1],
   1898                                              src[0] );
   1899                  src += 2;
   1900                }
   1901             }
   1902             else {
   1903                for (col = 0; col < srcWidth; col++) {
   1904                   /* src[0] is luminance (or R), src[1] is alpha (or G) */
   1905                  dstUS[col] = PACK_COLOR_88_REV( src[1],
   1906                                                  src[0] );
   1907                  src += 2;
   1908                }
   1909             }
   1910             dstRow += dstRowStride;
   1911          }
   1912       }
   1913       free((void *) tempImage);
   1914    }
   1915    return GL_TRUE;
   1916 }
   1917 
   1918 
   1919 /**
   1920  * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
   1921  */
   1922 static GLboolean
   1923 _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
   1924 {
   1925    const GLboolean littleEndian = _mesa_little_endian();
   1926    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   1927 
   1928    ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
   1929           dstFormat == MESA_FORMAT_AL1616_REV ||
   1930 	  dstFormat == MESA_FORMAT_RG1616 ||
   1931           dstFormat == MESA_FORMAT_RG1616_REV);
   1932    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   1933 
   1934    if (!ctx->_ImageTransferState &&
   1935        !srcPacking->SwapBytes &&
   1936        ((dstFormat == MESA_FORMAT_AL1616 &&
   1937          baseInternalFormat == GL_LUMINANCE_ALPHA &&
   1938          srcFormat == GL_LUMINANCE_ALPHA) ||
   1939         (dstFormat == MESA_FORMAT_RG1616 &&
   1940          baseInternalFormat == srcFormat)) &&
   1941        srcType == GL_UNSIGNED_SHORT &&
   1942        littleEndian) {
   1943       /* simple memcpy path */
   1944       memcpy_texture(ctx, dims,
   1945                      dstFormat,
   1946                      dstRowStride, dstSlices,
   1947                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   1948                      srcAddr, srcPacking);
   1949    }
   1950    else {
   1951       /* general path */
   1952       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   1953                                                  baseInternalFormat,
   1954                                                  baseFormat,
   1955                                                  srcWidth, srcHeight, srcDepth,
   1956                                                  srcFormat, srcType, srcAddr,
   1957                                                  srcPacking,
   1958                                                  ctx->_ImageTransferState);
   1959       const GLfloat *src = tempImage;
   1960       GLint img, row, col;
   1961       if (!tempImage)
   1962          return GL_FALSE;
   1963       for (img = 0; img < srcDepth; img++) {
   1964          GLubyte *dstRow = dstSlices[img];
   1965          for (row = 0; row < srcHeight; row++) {
   1966             GLuint *dstUI = (GLuint *) dstRow;
   1967             if (dstFormat == MESA_FORMAT_AL1616 ||
   1968 		dstFormat == MESA_FORMAT_RG1616) {
   1969                for (col = 0; col < srcWidth; col++) {
   1970 		  GLushort l, a;
   1971 
   1972 		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
   1973 		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
   1974 		  dstUI[col] = PACK_COLOR_1616(a, l);
   1975 		  src += 2;
   1976                }
   1977             }
   1978             else {
   1979                for (col = 0; col < srcWidth; col++) {
   1980 		  GLushort l, a;
   1981 
   1982 		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
   1983 		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
   1984 		  dstUI[col] = PACK_COLOR_1616_REV(a, l);
   1985 		  src += 2;
   1986                }
   1987             }
   1988             dstRow += dstRowStride;
   1989          }
   1990       }
   1991       free((void *) tempImage);
   1992    }
   1993    return GL_TRUE;
   1994 }
   1995 
   1996 
   1997 /* Texstore for R16, A16, L16, I16. */
   1998 static GLboolean
   1999 _mesa_texstore_unorm16(TEXSTORE_PARAMS)
   2000 {
   2001    const GLboolean littleEndian = _mesa_little_endian();
   2002    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2003 
   2004    ASSERT(dstFormat == MESA_FORMAT_R16 ||
   2005           dstFormat == MESA_FORMAT_A16 ||
   2006           dstFormat == MESA_FORMAT_L16 ||
   2007           dstFormat == MESA_FORMAT_I16);
   2008    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   2009 
   2010    if (!ctx->_ImageTransferState &&
   2011        !srcPacking->SwapBytes &&
   2012        baseInternalFormat == srcFormat &&
   2013        srcType == GL_UNSIGNED_SHORT &&
   2014        littleEndian) {
   2015       /* simple memcpy path */
   2016       memcpy_texture(ctx, dims,
   2017                      dstFormat,
   2018                      dstRowStride, dstSlices,
   2019                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2020                      srcAddr, srcPacking);
   2021    }
   2022    else {
   2023       /* general path */
   2024       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2025                                                  baseInternalFormat,
   2026                                                  baseFormat,
   2027                                                  srcWidth, srcHeight, srcDepth,
   2028                                                  srcFormat, srcType, srcAddr,
   2029                                                  srcPacking,
   2030                                                  ctx->_ImageTransferState);
   2031       const GLfloat *src = tempImage;
   2032       GLint img, row, col;
   2033       if (!tempImage)
   2034          return GL_FALSE;
   2035       for (img = 0; img < srcDepth; img++) {
   2036          GLubyte *dstRow = dstSlices[img];
   2037          for (row = 0; row < srcHeight; row++) {
   2038             GLushort *dstUS = (GLushort *) dstRow;
   2039 	    for (col = 0; col < srcWidth; col++) {
   2040 	       GLushort r;
   2041 
   2042 	       UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
   2043 	       dstUS[col] = r;
   2044 	       src += 1;
   2045 	    }
   2046             dstRow += dstRowStride;
   2047          }
   2048       }
   2049       free((void *) tempImage);
   2050    }
   2051    return GL_TRUE;
   2052 }
   2053 
   2054 
   2055 static GLboolean
   2056 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
   2057 {
   2058    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2059 
   2060    ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
   2061    ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
   2062 
   2063    if (!ctx->_ImageTransferState &&
   2064        !srcPacking->SwapBytes &&
   2065        baseInternalFormat == GL_RGBA &&
   2066        srcFormat == GL_RGBA &&
   2067        srcType == GL_UNSIGNED_SHORT) {
   2068       /* simple memcpy path */
   2069       memcpy_texture(ctx, dims,
   2070                      dstFormat,
   2071                      dstRowStride, dstSlices,
   2072                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2073                      srcAddr, srcPacking);
   2074    }
   2075    else {
   2076       /* general path */
   2077       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2078                                                  baseInternalFormat,
   2079                                                  baseFormat,
   2080                                                  srcWidth, srcHeight, srcDepth,
   2081                                                  srcFormat, srcType, srcAddr,
   2082                                                  srcPacking,
   2083                                                  ctx->_ImageTransferState);
   2084       const GLfloat *src = tempImage;
   2085       GLint img, row, col;
   2086       if (!tempImage)
   2087          return GL_FALSE;
   2088       for (img = 0; img < srcDepth; img++) {
   2089          GLubyte *dstRow = dstSlices[img];
   2090          for (row = 0; row < srcHeight; row++) {
   2091             GLushort *dstUS = (GLushort *) dstRow;
   2092             for (col = 0; col < srcWidth; col++) {
   2093                GLushort r, g, b, a;
   2094 
   2095                UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
   2096                UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
   2097                UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
   2098                UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
   2099                dstUS[col*4+0] = r;
   2100                dstUS[col*4+1] = g;
   2101                dstUS[col*4+2] = b;
   2102                dstUS[col*4+3] = a;
   2103                src += 4;
   2104             }
   2105             dstRow += dstRowStride;
   2106          }
   2107       }
   2108       free((void *) tempImage);
   2109    }
   2110    return GL_TRUE;
   2111 }
   2112 
   2113 
   2114 static GLboolean
   2115 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
   2116 {
   2117    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2118 
   2119    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
   2120           dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
   2121 
   2122    if (!ctx->_ImageTransferState &&
   2123        !srcPacking->SwapBytes &&
   2124        baseInternalFormat == GL_RGBA &&
   2125        dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
   2126        srcFormat == GL_RGBA &&
   2127        srcType == GL_SHORT) {
   2128       /* simple memcpy path */
   2129       memcpy_texture(ctx, dims,
   2130                      dstFormat,
   2131                      dstRowStride, dstSlices,
   2132                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2133                      srcAddr, srcPacking);
   2134    }
   2135    else {
   2136       /* general path */
   2137       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2138                                                  baseInternalFormat,
   2139                                                  baseFormat,
   2140                                                  srcWidth, srcHeight, srcDepth,
   2141                                                  srcFormat, srcType, srcAddr,
   2142                                                  srcPacking,
   2143                                                  ctx->_ImageTransferState);
   2144       const GLfloat *src = tempImage;
   2145       const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
   2146       GLint img, row, col;
   2147 
   2148       if (!tempImage)
   2149          return GL_FALSE;
   2150 
   2151       /* Note: tempImage is always float[4] / RGBA.  We convert to 1, 2,
   2152        * 3 or 4 components/pixel here.
   2153        */
   2154       for (img = 0; img < srcDepth; img++) {
   2155          GLubyte *dstRow = dstSlices[img];
   2156          for (row = 0; row < srcHeight; row++) {
   2157             GLshort *dstRowS = (GLshort *) dstRow;
   2158             if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) {
   2159                for (col = 0; col < srcWidth; col++) {
   2160                   GLuint c;
   2161                   for (c = 0; c < comps; c++) {
   2162                      GLshort p;
   2163                      UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
   2164                      dstRowS[col * comps + c] = p;
   2165                   }
   2166                }
   2167                dstRow += dstRowStride;
   2168                src += 4 * srcWidth;
   2169             } else {
   2170                for (col = 0; col < srcWidth; col++) {
   2171                   GLuint c;
   2172                   for (c = 0; c < comps; c++) {
   2173                      GLshort p;
   2174                      UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
   2175                      dstRowS[col * comps + c] = p;
   2176                   }
   2177                }
   2178                dstRow += dstRowStride;
   2179                src += 3 * srcWidth;
   2180             }
   2181          }
   2182       }
   2183       free((void *) tempImage);
   2184    }
   2185    return GL_TRUE;
   2186 }
   2187 
   2188 
   2189 static GLboolean
   2190 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
   2191 {
   2192    ASSERT(dstFormat == MESA_FORMAT_RGB332);
   2193    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
   2194 
   2195    if (!ctx->_ImageTransferState &&
   2196        baseInternalFormat == GL_RGB &&
   2197        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   2198                                             srcPacking->SwapBytes)) {
   2199       /* simple memcpy path */
   2200       memcpy_texture(ctx, dims,
   2201                      dstFormat,
   2202                      dstRowStride, dstSlices,
   2203                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2204                      srcAddr, srcPacking);
   2205    }
   2206    else {
   2207       return store_ubyte_texture(ctx, dims, baseInternalFormat,
   2208                                  dstFormat, dstRowStride, dstSlices,
   2209                                  srcWidth, srcHeight, srcDepth,
   2210                                  srcFormat, srcType, srcAddr, srcPacking);
   2211    }
   2212    return GL_TRUE;
   2213 }
   2214 
   2215 
   2216 /**
   2217  * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
   2218  */
   2219 static GLboolean
   2220 _mesa_texstore_unorm8(TEXSTORE_PARAMS)
   2221 {
   2222    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2223 
   2224    ASSERT(dstFormat == MESA_FORMAT_A8 ||
   2225           dstFormat == MESA_FORMAT_L8 ||
   2226           dstFormat == MESA_FORMAT_I8 ||
   2227           dstFormat == MESA_FORMAT_R8);
   2228    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
   2229 
   2230    if (!ctx->_ImageTransferState &&
   2231        !srcPacking->SwapBytes &&
   2232        baseInternalFormat == srcFormat &&
   2233        srcType == GL_UNSIGNED_BYTE) {
   2234       /* simple memcpy path */
   2235       memcpy_texture(ctx, dims,
   2236                      dstFormat,
   2237                      dstRowStride, dstSlices,
   2238                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2239                      srcAddr, srcPacking);
   2240    }
   2241    else if (!ctx->_ImageTransferState &&
   2242 	    srcType == GL_UNSIGNED_BYTE &&
   2243 	    can_swizzle(baseInternalFormat) &&
   2244 	    can_swizzle(srcFormat)) {
   2245       GLubyte dstmap[4];
   2246 
   2247       /* dstmap - how to swizzle from RGBA to dst format:
   2248        */
   2249       if (dstFormat == MESA_FORMAT_A8) {
   2250 	 dstmap[0] = 3;
   2251       }
   2252       else {
   2253 	 dstmap[0] = 0;
   2254       }
   2255       dstmap[1] = ZERO;		/* ? */
   2256       dstmap[2] = ZERO;		/* ? */
   2257       dstmap[3] = ONE;		/* ? */
   2258 
   2259       _mesa_swizzle_ubyte_image(ctx, dims,
   2260 				srcFormat,
   2261 				srcType,
   2262 				baseInternalFormat,
   2263 				dstmap, 1,
   2264 				dstRowStride, dstSlices,
   2265 				srcWidth, srcHeight, srcDepth, srcAddr,
   2266 				srcPacking);
   2267    }
   2268    else {
   2269       /* general path */
   2270       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
   2271                                                  baseInternalFormat,
   2272                                                  baseFormat,
   2273                                                  srcWidth, srcHeight, srcDepth,
   2274                                                  srcFormat, srcType, srcAddr,
   2275                                                  srcPacking);
   2276       const GLubyte *src = tempImage;
   2277       GLint img, row, col;
   2278       if (!tempImage)
   2279          return GL_FALSE;
   2280       for (img = 0; img < srcDepth; img++) {
   2281          GLubyte *dstRow = dstSlices[img];
   2282          for (row = 0; row < srcHeight; row++) {
   2283             for (col = 0; col < srcWidth; col++) {
   2284                dstRow[col] = src[col];
   2285             }
   2286             dstRow += dstRowStride;
   2287             src += srcWidth;
   2288          }
   2289       }
   2290       free((void *) tempImage);
   2291    }
   2292    return GL_TRUE;
   2293 }
   2294 
   2295 
   2296 
   2297 /**
   2298  * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
   2299  */
   2300 static GLboolean
   2301 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
   2302 {
   2303    const GLboolean littleEndian = _mesa_little_endian();
   2304 
   2305    (void) ctx; (void) dims; (void) baseInternalFormat;
   2306 
   2307    ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
   2308           (dstFormat == MESA_FORMAT_YCBCR_REV));
   2309    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   2310    ASSERT(ctx->Extensions.MESA_ycbcr_texture);
   2311    ASSERT(srcFormat == GL_YCBCR_MESA);
   2312    ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
   2313           (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
   2314    ASSERT(baseInternalFormat == GL_YCBCR_MESA);
   2315 
   2316    /* always just memcpy since no pixel transfer ops apply */
   2317    memcpy_texture(ctx, dims,
   2318                   dstFormat,
   2319                   dstRowStride, dstSlices,
   2320                   srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2321                   srcAddr, srcPacking);
   2322 
   2323    /* Check if we need byte swapping */
   2324    /* XXX the logic here _might_ be wrong */
   2325    if (srcPacking->SwapBytes ^
   2326        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
   2327        (dstFormat == MESA_FORMAT_YCBCR_REV) ^
   2328        !littleEndian) {
   2329       GLint img, row;
   2330       for (img = 0; img < srcDepth; img++) {
   2331          GLubyte *dstRow = dstSlices[img];
   2332          for (row = 0; row < srcHeight; row++) {
   2333             _mesa_swap2((GLushort *) dstRow, srcWidth);
   2334             dstRow += dstRowStride;
   2335          }
   2336       }
   2337    }
   2338    return GL_TRUE;
   2339 }
   2340 
   2341 static GLboolean
   2342 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
   2343 {
   2344    const GLboolean littleEndian = _mesa_little_endian();
   2345    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
   2346 
   2347    ASSERT(dstFormat == MESA_FORMAT_DUDV8);
   2348    ASSERT(texelBytes == 2);
   2349    ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
   2350    ASSERT((srcFormat == GL_DU8DV8_ATI) ||
   2351 	  (srcFormat == GL_DUDV_ATI));
   2352    ASSERT(baseInternalFormat == GL_DUDV_ATI);
   2353 
   2354    if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
   2355        littleEndian) {
   2356       /* simple memcpy path */
   2357       memcpy_texture(ctx, dims,
   2358                      dstFormat,
   2359                      dstRowStride, dstSlices,
   2360                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2361                      srcAddr, srcPacking);
   2362    }
   2363    else if (srcType == GL_BYTE) {
   2364       GLubyte dstmap[4];
   2365 
   2366       /* dstmap - how to swizzle from RGBA to dst format:
   2367        */
   2368       if (littleEndian) {
   2369 	 dstmap[0] = 0;
   2370 	 dstmap[1] = 3;
   2371       }
   2372       else {
   2373 	 dstmap[0] = 3;
   2374 	 dstmap[1] = 0;
   2375       }
   2376       dstmap[2] = ZERO;		/* ? */
   2377       dstmap[3] = ONE;		/* ? */
   2378 
   2379       _mesa_swizzle_ubyte_image(ctx, dims,
   2380 				GL_LUMINANCE_ALPHA, /* hack */
   2381 				GL_UNSIGNED_BYTE, /* hack */
   2382 				GL_LUMINANCE_ALPHA, /* hack */
   2383 				dstmap, 2,
   2384 				dstRowStride, dstSlices,
   2385 				srcWidth, srcHeight, srcDepth, srcAddr,
   2386 				srcPacking);
   2387    }
   2388    else {
   2389       /* general path - note this is defined for 2d textures only */
   2390       const GLint components = _mesa_components_in_format(baseInternalFormat);
   2391       const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
   2392                                                      srcFormat, srcType);
   2393       GLbyte *tempImage, *dst, *src;
   2394       GLint row;
   2395 
   2396       tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
   2397                                           * components * sizeof(GLbyte));
   2398       if (!tempImage)
   2399          return GL_FALSE;
   2400 
   2401       src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
   2402                                            srcWidth, srcHeight,
   2403                                            srcFormat, srcType,
   2404                                            0, 0, 0);
   2405 
   2406       dst = tempImage;
   2407       for (row = 0; row < srcHeight; row++) {
   2408          _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
   2409                                      dst, srcFormat, srcType, src,
   2410                                      srcPacking, 0);
   2411          dst += srcWidth * components;
   2412          src += srcStride;
   2413       }
   2414 
   2415       src = tempImage;
   2416       dst = (GLbyte *) dstSlices[0];
   2417       for (row = 0; row < srcHeight; row++) {
   2418          memcpy(dst, src, srcWidth * texelBytes);
   2419          dst += dstRowStride;
   2420          src += srcWidth * texelBytes;
   2421       }
   2422       free((void *) tempImage);
   2423    }
   2424    return GL_TRUE;
   2425 }
   2426 
   2427 
   2428 /**
   2429  * Store a texture in a signed normalized 8-bit format.
   2430  */
   2431 static GLboolean
   2432 _mesa_texstore_snorm8(TEXSTORE_PARAMS)
   2433 {
   2434    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2435 
   2436    ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 ||
   2437           dstFormat == MESA_FORMAT_SIGNED_L8 ||
   2438           dstFormat == MESA_FORMAT_SIGNED_I8 ||
   2439           dstFormat == MESA_FORMAT_SIGNED_R8);
   2440    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
   2441 
   2442    if (!ctx->_ImageTransferState &&
   2443        !srcPacking->SwapBytes &&
   2444        baseInternalFormat == srcFormat &&
   2445        srcType == GL_BYTE) {
   2446       /* simple memcpy path */
   2447       memcpy_texture(ctx, dims,
   2448                      dstFormat,
   2449                      dstRowStride, dstSlices,
   2450                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2451                      srcAddr, srcPacking);
   2452    }
   2453    else {
   2454       /* general path */
   2455       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2456                                                  baseInternalFormat,
   2457                                                  baseFormat,
   2458                                                  srcWidth, srcHeight, srcDepth,
   2459                                                  srcFormat, srcType, srcAddr,
   2460                                                  srcPacking,
   2461                                                  ctx->_ImageTransferState);
   2462       const GLfloat *src = tempImage;
   2463       GLint img, row, col;
   2464       if (!tempImage)
   2465          return GL_FALSE;
   2466       for (img = 0; img < srcDepth; img++) {
   2467          GLbyte *dstRow = (GLbyte *) dstSlices[img];
   2468          for (row = 0; row < srcHeight; row++) {
   2469             for (col = 0; col < srcWidth; col++) {
   2470                dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
   2471             }
   2472             dstRow += dstRowStride;
   2473             src += srcWidth;
   2474          }
   2475       }
   2476       free((void *) tempImage);
   2477    }
   2478    return GL_TRUE;
   2479 }
   2480 
   2481 
   2482 /**
   2483  * Store a texture in a signed normalized two-channel 16-bit format.
   2484  */
   2485 static GLboolean
   2486 _mesa_texstore_snorm88(TEXSTORE_PARAMS)
   2487 {
   2488    const GLboolean littleEndian = _mesa_little_endian();
   2489    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2490 
   2491    ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
   2492           dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
   2493    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   2494 
   2495    if (!ctx->_ImageTransferState &&
   2496        !srcPacking->SwapBytes &&
   2497        baseInternalFormat == srcFormat &&
   2498        srcType == GL_BYTE &&
   2499        littleEndian) {
   2500       /* simple memcpy path */
   2501       memcpy_texture(ctx, dims,
   2502                      dstFormat,
   2503                      dstRowStride, dstSlices,
   2504                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2505                      srcAddr, srcPacking);
   2506    }
   2507    else {
   2508       /* general path */
   2509       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2510                                                  baseInternalFormat,
   2511                                                  baseFormat,
   2512                                                  srcWidth, srcHeight, srcDepth,
   2513                                                  srcFormat, srcType, srcAddr,
   2514                                                  srcPacking,
   2515                                                  ctx->_ImageTransferState);
   2516       const GLfloat *src = tempImage;
   2517       GLint img, row, col;
   2518       if (!tempImage)
   2519          return GL_FALSE;
   2520       for (img = 0; img < srcDepth; img++) {
   2521          GLbyte *dstRow = (GLbyte *) dstSlices[img];
   2522          for (row = 0; row < srcHeight; row++) {
   2523             GLbyte *dst = dstRow;
   2524             for (col = 0; col < srcWidth; col++) {
   2525                dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
   2526                dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
   2527                src += 2;
   2528                dst += 2;
   2529             }
   2530             dstRow += dstRowStride;
   2531          }
   2532       }
   2533       free((void *) tempImage);
   2534    }
   2535    return GL_TRUE;
   2536 }
   2537 
   2538 /* Texstore for signed R16, A16, L16, I16. */
   2539 static GLboolean
   2540 _mesa_texstore_snorm16(TEXSTORE_PARAMS)
   2541 {
   2542    const GLboolean littleEndian = _mesa_little_endian();
   2543    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2544 
   2545    ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 ||
   2546           dstFormat == MESA_FORMAT_SIGNED_A16 ||
   2547           dstFormat == MESA_FORMAT_SIGNED_L16 ||
   2548           dstFormat == MESA_FORMAT_SIGNED_I16);
   2549    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
   2550 
   2551    if (!ctx->_ImageTransferState &&
   2552        !srcPacking->SwapBytes &&
   2553        baseInternalFormat == srcFormat &&
   2554        srcType == GL_SHORT &&
   2555        littleEndian) {
   2556       /* simple memcpy path */
   2557       memcpy_texture(ctx, dims,
   2558                      dstFormat,
   2559                      dstRowStride, dstSlices,
   2560                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2561                      srcAddr, srcPacking);
   2562    }
   2563    else {
   2564       /* general path */
   2565       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2566                                                  baseInternalFormat,
   2567                                                  baseFormat,
   2568                                                  srcWidth, srcHeight, srcDepth,
   2569                                                  srcFormat, srcType, srcAddr,
   2570                                                  srcPacking,
   2571                                                  ctx->_ImageTransferState);
   2572       const GLfloat *src = tempImage;
   2573       GLint img, row, col;
   2574       if (!tempImage)
   2575          return GL_FALSE;
   2576       for (img = 0; img < srcDepth; img++) {
   2577          GLubyte *dstRow = dstSlices[img];
   2578          for (row = 0; row < srcHeight; row++) {
   2579             GLshort *dstUS = (GLshort *) dstRow;
   2580 	    for (col = 0; col < srcWidth; col++) {
   2581 	       GLushort r;
   2582 
   2583 	       UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
   2584 	       dstUS[col] = r;
   2585 	       src += 1;
   2586 	    }
   2587             dstRow += dstRowStride;
   2588          }
   2589       }
   2590       free((void *) tempImage);
   2591    }
   2592    return GL_TRUE;
   2593 }
   2594 
   2595 /**
   2596  * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
   2597  */
   2598 static GLboolean
   2599 _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
   2600 {
   2601    const GLboolean littleEndian = _mesa_little_endian();
   2602    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2603 
   2604    ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
   2605           dstFormat == MESA_FORMAT_SIGNED_GR1616);
   2606    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   2607 
   2608    if (!ctx->_ImageTransferState &&
   2609        !srcPacking->SwapBytes &&
   2610        baseInternalFormat == srcFormat &&
   2611        srcType == GL_SHORT &&
   2612        littleEndian) {
   2613       /* simple memcpy path */
   2614       memcpy_texture(ctx, dims,
   2615                      dstFormat,
   2616                      dstRowStride, dstSlices,
   2617                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2618                      srcAddr, srcPacking);
   2619    }
   2620    else {
   2621       /* general path */
   2622       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2623                                                  baseInternalFormat,
   2624                                                  baseFormat,
   2625                                                  srcWidth, srcHeight, srcDepth,
   2626                                                  srcFormat, srcType, srcAddr,
   2627                                                  srcPacking,
   2628                                                  ctx->_ImageTransferState);
   2629       const GLfloat *src = tempImage;
   2630       GLint img, row, col;
   2631       if (!tempImage)
   2632          return GL_FALSE;
   2633       for (img = 0; img < srcDepth; img++) {
   2634          GLubyte *dstRow = dstSlices[img];
   2635          for (row = 0; row < srcHeight; row++) {
   2636             GLshort *dst = (GLshort *) dstRow;
   2637             for (col = 0; col < srcWidth; col++) {
   2638                GLushort l, a;
   2639 
   2640                UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
   2641                UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
   2642                dst[0] = l;
   2643                dst[1] = a;
   2644                src += 2;
   2645                dst += 2;
   2646             }
   2647             dstRow += dstRowStride;
   2648          }
   2649       }
   2650       free((void *) tempImage);
   2651    }
   2652    return GL_TRUE;
   2653 }
   2654 
   2655 /**
   2656  * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
   2657  */
   2658 static GLboolean
   2659 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
   2660 {
   2661    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2662 
   2663    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
   2664    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   2665 
   2666    {
   2667       /* general path */
   2668       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2669                                                  baseInternalFormat,
   2670                                                  baseFormat,
   2671                                                  srcWidth, srcHeight, srcDepth,
   2672                                                  srcFormat, srcType, srcAddr,
   2673                                                  srcPacking,
   2674                                                  ctx->_ImageTransferState);
   2675       const GLfloat *srcRow = tempImage;
   2676       GLint img, row, col;
   2677       if (!tempImage)
   2678          return GL_FALSE;
   2679       for (img = 0; img < srcDepth; img++) {
   2680          GLbyte *dstRow = (GLbyte *) dstSlices[img];
   2681          for (row = 0; row < srcHeight; row++) {
   2682             GLbyte *dst = dstRow;
   2683             for (col = 0; col < srcWidth; col++) {
   2684                dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
   2685                dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
   2686                dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
   2687                dst[0] = 127;
   2688                srcRow += 3;
   2689                dst += 4;
   2690             }
   2691             dstRow += dstRowStride;
   2692          }
   2693       }
   2694       free((void *) tempImage);
   2695    }
   2696    return GL_TRUE;
   2697 }
   2698 
   2699 
   2700 
   2701 /**
   2702  * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
   2703  * MESA_FORMAT_SIGNED_RGBA8888_REV
   2704  */
   2705 static GLboolean
   2706 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
   2707 {
   2708    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   2709 
   2710    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
   2711           dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
   2712    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   2713 
   2714    if (!ctx->_ImageTransferState &&
   2715        baseInternalFormat == GL_RGBA &&
   2716        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   2717                                             srcPacking->SwapBytes)) {
   2718        /* simple memcpy path */
   2719       memcpy_texture(ctx, dims,
   2720                      dstFormat,
   2721                      dstRowStride, dstSlices,
   2722                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2723                      srcAddr, srcPacking);
   2724    }
   2725    else {
   2726       /* general path */
   2727       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   2728                                                  baseInternalFormat,
   2729                                                  baseFormat,
   2730                                                  srcWidth, srcHeight, srcDepth,
   2731                                                  srcFormat, srcType, srcAddr,
   2732                                                  srcPacking,
   2733                                                  ctx->_ImageTransferState);
   2734       const GLfloat *srcRow = tempImage;
   2735       GLint img, row, col;
   2736       if (!tempImage)
   2737          return GL_FALSE;
   2738       for (img = 0; img < srcDepth; img++) {
   2739          GLbyte *dstRow = (GLbyte *) dstSlices[img];
   2740          for (row = 0; row < srcHeight; row++) {
   2741             GLbyte *dst = dstRow;
   2742             if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
   2743                for (col = 0; col < srcWidth; col++) {
   2744                   dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
   2745                   dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
   2746                   dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
   2747                   dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
   2748                   srcRow += 4;
   2749                   dst += 4;
   2750                }
   2751             }
   2752             else {
   2753                for (col = 0; col < srcWidth; col++) {
   2754                   dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
   2755                   dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
   2756                   dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
   2757                   dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
   2758                   srcRow += 4;
   2759                   dst += 4;
   2760                }
   2761             }
   2762             dstRow += dstRowStride;
   2763          }
   2764       }
   2765       free((void *) tempImage);
   2766    }
   2767    return GL_TRUE;
   2768 }
   2769 
   2770 
   2771 /**
   2772  * Store a combined depth/stencil texture image.
   2773  */
   2774 static GLboolean
   2775 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
   2776 {
   2777    const GLuint depthScale = 0xffffff;
   2778    const GLint srcRowStride
   2779       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   2780    GLint img, row;
   2781 
   2782    ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
   2783    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
   2784           srcFormat == GL_DEPTH_COMPONENT ||
   2785           srcFormat == GL_STENCIL_INDEX);
   2786    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
   2787 
   2788    if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
   2789        ctx->Pixel.DepthBias == 0.0f &&
   2790        !srcPacking->SwapBytes) {
   2791       /* simple path */
   2792       memcpy_texture(ctx, dims,
   2793                      dstFormat,
   2794                      dstRowStride, dstSlices,
   2795                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2796                      srcAddr, srcPacking);
   2797    }
   2798    else if (srcFormat == GL_DEPTH_COMPONENT ||
   2799             srcFormat == GL_STENCIL_INDEX) {
   2800       GLuint *depth = (GLuint *) malloc(srcWidth * sizeof(GLuint));
   2801       GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
   2802 
   2803       if (!depth || !stencil) {
   2804          free(depth);
   2805          free(stencil);
   2806          return GL_FALSE;
   2807       }
   2808 
   2809       /* In case we only upload depth we need to preserve the stencil */
   2810       for (img = 0; img < srcDepth; img++) {
   2811 	 GLuint *dstRow = (GLuint *) dstSlices[img];
   2812          const GLubyte *src
   2813             = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
   2814                   srcWidth, srcHeight,
   2815                   srcFormat, srcType,
   2816                   img, 0, 0);
   2817          for (row = 0; row < srcHeight; row++) {
   2818             GLint i;
   2819 	    GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
   2820 
   2821 	    if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
   2822 	       keepstencil = GL_TRUE;
   2823 	    }
   2824             else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
   2825 	       keepdepth = GL_TRUE;
   2826 	    }
   2827 
   2828 	    if (keepdepth == GL_FALSE)
   2829 	       /* the 24 depth bits will be in the low position: */
   2830 	       _mesa_unpack_depth_span(ctx, srcWidth,
   2831 				       GL_UNSIGNED_INT, /* dst type */
   2832 				       keepstencil ? depth : dstRow, /* dst addr */
   2833 				       depthScale,
   2834 				       srcType, src, srcPacking);
   2835 
   2836 	    if (keepstencil == GL_FALSE)
   2837 	       /* get the 8-bit stencil values */
   2838 	       _mesa_unpack_stencil_span(ctx, srcWidth,
   2839 					 GL_UNSIGNED_BYTE, /* dst type */
   2840 					 stencil, /* dst addr */
   2841 					 srcType, src, srcPacking,
   2842 					 ctx->_ImageTransferState);
   2843 
   2844 	    for (i = 0; i < srcWidth; i++) {
   2845 	       if (keepstencil)
   2846 		  dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
   2847 	       else
   2848 		  dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
   2849 	    }
   2850 
   2851             src += srcRowStride;
   2852             dstRow += dstRowStride / sizeof(GLuint);
   2853          }
   2854       }
   2855 
   2856       free(depth);
   2857       free(stencil);
   2858    }
   2859    return GL_TRUE;
   2860 }
   2861 
   2862 
   2863 /**
   2864  * Store a combined depth/stencil texture image.
   2865  */
   2866 static GLboolean
   2867 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
   2868 {
   2869    const GLuint depthScale = 0xffffff;
   2870    const GLint srcRowStride
   2871       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   2872    GLint img, row;
   2873    GLuint *depth;
   2874    GLubyte *stencil;
   2875 
   2876    ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
   2877    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
   2878           srcFormat == GL_DEPTH_COMPONENT ||
   2879           srcFormat == GL_STENCIL_INDEX);
   2880    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
   2881           srcType == GL_UNSIGNED_INT_24_8_EXT);
   2882 
   2883    depth = (GLuint *) malloc(srcWidth * sizeof(GLuint));
   2884    stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
   2885 
   2886    if (!depth || !stencil) {
   2887       free(depth);
   2888       free(stencil);
   2889       return GL_FALSE;
   2890    }
   2891 
   2892    for (img = 0; img < srcDepth; img++) {
   2893       GLuint *dstRow = (GLuint *) dstSlices[img];
   2894       const GLubyte *src
   2895 	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
   2896 						srcWidth, srcHeight,
   2897 						srcFormat, srcType,
   2898 						img, 0, 0);
   2899       for (row = 0; row < srcHeight; row++) {
   2900 	 GLint i;
   2901 	 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
   2902 
   2903 	 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
   2904 	    keepstencil = GL_TRUE;
   2905 	 }
   2906          else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
   2907 	    keepdepth = GL_TRUE;
   2908 	 }
   2909 
   2910 	 if (keepdepth == GL_FALSE)
   2911 	    /* the 24 depth bits will be in the low position: */
   2912 	    _mesa_unpack_depth_span(ctx, srcWidth,
   2913 				    GL_UNSIGNED_INT, /* dst type */
   2914 				    keepstencil ? depth : dstRow, /* dst addr */
   2915 				    depthScale,
   2916 				    srcType, src, srcPacking);
   2917 
   2918 	 if (keepstencil == GL_FALSE)
   2919 	    /* get the 8-bit stencil values */
   2920 	    _mesa_unpack_stencil_span(ctx, srcWidth,
   2921 				      GL_UNSIGNED_BYTE, /* dst type */
   2922 				      stencil, /* dst addr */
   2923 				      srcType, src, srcPacking,
   2924 				      ctx->_ImageTransferState);
   2925 
   2926 	 /* merge stencil values into depth values */
   2927 	 for (i = 0; i < srcWidth; i++) {
   2928 	    if (keepstencil)
   2929 	       dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
   2930 	    else
   2931 	       dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
   2932 
   2933 	 }
   2934 	 src += srcRowStride;
   2935 	 dstRow += dstRowStride / sizeof(GLuint);
   2936       }
   2937    }
   2938 
   2939    free(depth);
   2940    free(stencil);
   2941 
   2942    return GL_TRUE;
   2943 }
   2944 
   2945 
   2946 /**
   2947  * Store simple 8-bit/value stencil texture data.
   2948  */
   2949 static GLboolean
   2950 _mesa_texstore_s8(TEXSTORE_PARAMS)
   2951 {
   2952    ASSERT(dstFormat == MESA_FORMAT_S8);
   2953    ASSERT(srcFormat == GL_STENCIL_INDEX);
   2954 
   2955    if (!ctx->_ImageTransferState &&
   2956        !srcPacking->SwapBytes &&
   2957        baseInternalFormat == srcFormat &&
   2958        srcType == GL_UNSIGNED_BYTE) {
   2959       /* simple memcpy path */
   2960       memcpy_texture(ctx, dims,
   2961                      dstFormat,
   2962                      dstRowStride, dstSlices,
   2963                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   2964                      srcAddr, srcPacking);
   2965    }
   2966    else {
   2967       const GLint srcRowStride
   2968 	 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
   2969       GLint img, row;
   2970       GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
   2971 
   2972       if (!stencil)
   2973          return GL_FALSE;
   2974 
   2975       for (img = 0; img < srcDepth; img++) {
   2976          GLubyte *dstRow = dstSlices[img];
   2977          const GLubyte *src
   2978             = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
   2979                                                    srcWidth, srcHeight,
   2980                                                    srcFormat, srcType,
   2981                                                    img, 0, 0);
   2982          for (row = 0; row < srcHeight; row++) {
   2983             GLint i;
   2984 
   2985             /* get the 8-bit stencil values */
   2986             _mesa_unpack_stencil_span(ctx, srcWidth,
   2987                                       GL_UNSIGNED_BYTE, /* dst type */
   2988                                       stencil, /* dst addr */
   2989                                       srcType, src, srcPacking,
   2990                                       ctx->_ImageTransferState);
   2991             /* merge stencil values into depth values */
   2992             for (i = 0; i < srcWidth; i++)
   2993                dstRow[i] = stencil[i];
   2994 
   2995             src += srcRowStride;
   2996             dstRow += dstRowStride / sizeof(GLubyte);
   2997          }
   2998       }
   2999 
   3000       free(stencil);
   3001    }
   3002 
   3003    return GL_TRUE;
   3004 }
   3005 
   3006 
   3007 /**
   3008  * Store an image in any of the formats:
   3009  *   _mesa_texformat_rgba_float32
   3010  *   _mesa_texformat_rgb_float32
   3011  *   _mesa_texformat_alpha_float32
   3012  *   _mesa_texformat_luminance_float32
   3013  *   _mesa_texformat_luminance_alpha_float32
   3014  *   _mesa_texformat_intensity_float32
   3015  */
   3016 static GLboolean
   3017 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
   3018 {
   3019    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3020    const GLint components = _mesa_components_in_format(baseFormat);
   3021 
   3022    ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
   3023           dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
   3024           dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
   3025           dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
   3026           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
   3027           dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 ||
   3028           dstFormat == MESA_FORMAT_R_FLOAT32 ||
   3029           dstFormat == MESA_FORMAT_RG_FLOAT32);
   3030    ASSERT(baseInternalFormat == GL_RGBA ||
   3031           baseInternalFormat == GL_RGB ||
   3032           baseInternalFormat == GL_ALPHA ||
   3033           baseInternalFormat == GL_LUMINANCE ||
   3034           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3035           baseInternalFormat == GL_INTENSITY ||
   3036           baseInternalFormat == GL_RED ||
   3037           baseInternalFormat == GL_RG);
   3038    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat));
   3039 
   3040    if (!ctx->_ImageTransferState &&
   3041        !srcPacking->SwapBytes &&
   3042        baseInternalFormat == srcFormat &&
   3043        baseInternalFormat == baseFormat &&
   3044        srcType == GL_FLOAT) {
   3045       /* simple memcpy path */
   3046       memcpy_texture(ctx, dims,
   3047                      dstFormat,
   3048                      dstRowStride, dstSlices,
   3049                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3050                      srcAddr, srcPacking);
   3051    }
   3052    else {
   3053       /* general path */
   3054       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   3055                                                  baseInternalFormat,
   3056                                                  baseFormat,
   3057                                                  srcWidth, srcHeight, srcDepth,
   3058                                                  srcFormat, srcType, srcAddr,
   3059                                                  srcPacking,
   3060                                                  ctx->_ImageTransferState);
   3061       const GLfloat *srcRow = tempImage;
   3062       GLint bytesPerRow;
   3063       GLint img, row;
   3064       if (!tempImage)
   3065          return GL_FALSE;
   3066       bytesPerRow = srcWidth * components * sizeof(GLfloat);
   3067       for (img = 0; img < srcDepth; img++) {
   3068          GLubyte *dstRow = dstSlices[img];
   3069          for (row = 0; row < srcHeight; row++) {
   3070             memcpy(dstRow, srcRow, bytesPerRow);
   3071             dstRow += dstRowStride;
   3072             srcRow += srcWidth * components;
   3073          }
   3074       }
   3075 
   3076       free((void *) tempImage);
   3077    }
   3078    return GL_TRUE;
   3079 }
   3080 
   3081 
   3082 
   3083 /**
   3084  * As above, but store 16-bit floats.
   3085  */
   3086 static GLboolean
   3087 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
   3088 {
   3089    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3090    const GLint components = _mesa_components_in_format(baseFormat);
   3091 
   3092    ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
   3093           dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
   3094           dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
   3095           dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
   3096           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
   3097           dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 ||
   3098           dstFormat == MESA_FORMAT_R_FLOAT16 ||
   3099           dstFormat == MESA_FORMAT_RG_FLOAT16);
   3100    ASSERT(baseInternalFormat == GL_RGBA ||
   3101           baseInternalFormat == GL_RGB ||
   3102           baseInternalFormat == GL_ALPHA ||
   3103           baseInternalFormat == GL_LUMINANCE ||
   3104           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3105           baseInternalFormat == GL_INTENSITY ||
   3106           baseInternalFormat == GL_RED ||
   3107           baseInternalFormat == GL_RG);
   3108    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB));
   3109 
   3110    if (!ctx->_ImageTransferState &&
   3111        !srcPacking->SwapBytes &&
   3112        baseInternalFormat == srcFormat &&
   3113        baseInternalFormat == baseFormat &&
   3114        srcType == GL_HALF_FLOAT_ARB) {
   3115       /* simple memcpy path */
   3116       memcpy_texture(ctx, dims,
   3117                      dstFormat,
   3118                      dstRowStride, dstSlices,
   3119                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3120                      srcAddr, srcPacking);
   3121    }
   3122    else {
   3123       /* general path */
   3124       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   3125                                                  baseInternalFormat,
   3126                                                  baseFormat,
   3127                                                  srcWidth, srcHeight, srcDepth,
   3128                                                  srcFormat, srcType, srcAddr,
   3129                                                  srcPacking,
   3130                                                  ctx->_ImageTransferState);
   3131       const GLfloat *src = tempImage;
   3132       GLint img, row;
   3133       if (!tempImage)
   3134          return GL_FALSE;
   3135       for (img = 0; img < srcDepth; img++) {
   3136          GLubyte *dstRow = dstSlices[img];
   3137          for (row = 0; row < srcHeight; row++) {
   3138             GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
   3139             GLint i;
   3140             for (i = 0; i < srcWidth * components; i++) {
   3141                dstTexel[i] = _mesa_float_to_half(src[i]);
   3142             }
   3143             dstRow += dstRowStride;
   3144             src += srcWidth * components;
   3145          }
   3146       }
   3147 
   3148       free((void *) tempImage);
   3149    }
   3150    return GL_TRUE;
   3151 }
   3152 
   3153 
   3154 /* non-normalized, signed int8 */
   3155 static GLboolean
   3156 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
   3157 {
   3158    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3159    const GLint components = _mesa_components_in_format(baseFormat);
   3160 
   3161    ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
   3162           dstFormat == MESA_FORMAT_RG_INT8 ||
   3163           dstFormat == MESA_FORMAT_RGB_INT8 ||
   3164           dstFormat == MESA_FORMAT_RGBA_INT8 ||
   3165           dstFormat == MESA_FORMAT_ALPHA_INT8 ||
   3166           dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
   3167           dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
   3168           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
   3169    ASSERT(baseInternalFormat == GL_RGBA ||
   3170           baseInternalFormat == GL_RGB ||
   3171           baseInternalFormat == GL_RG ||
   3172           baseInternalFormat == GL_RED ||
   3173           baseInternalFormat == GL_ALPHA ||
   3174           baseInternalFormat == GL_LUMINANCE ||
   3175           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3176           baseInternalFormat == GL_INTENSITY);
   3177    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte));
   3178 
   3179    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3180     * to integer formats.
   3181     */
   3182    if (!srcPacking->SwapBytes &&
   3183        baseInternalFormat == srcFormat &&
   3184        srcType == GL_BYTE) {
   3185       /* simple memcpy path */
   3186       memcpy_texture(ctx, dims,
   3187                      dstFormat,
   3188                      dstRowStride, dstSlices,
   3189                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3190                      srcAddr, srcPacking);
   3191    }
   3192    else {
   3193       /* general path */
   3194       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
   3195 						     baseInternalFormat,
   3196 						     baseFormat,
   3197 						     srcWidth, srcHeight, srcDepth,
   3198 						     srcFormat, srcType,
   3199 						     srcAddr,
   3200 						     srcPacking);
   3201       const GLuint *src = tempImage;
   3202       GLint img, row;
   3203       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3204       if (!tempImage)
   3205          return GL_FALSE;
   3206       for (img = 0; img < srcDepth; img++) {
   3207          GLubyte *dstRow = dstSlices[img];
   3208          for (row = 0; row < srcHeight; row++) {
   3209             GLbyte *dstTexel = (GLbyte *) dstRow;
   3210             GLint i;
   3211             if (is_unsigned) {
   3212                for (i = 0; i < srcWidth * components; i++) {
   3213                   dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
   3214                }
   3215             } else {
   3216                for (i = 0; i < srcWidth * components; i++) {
   3217                   dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
   3218                }
   3219             }
   3220             dstRow += dstRowStride;
   3221             src += srcWidth * components;
   3222          }
   3223       }
   3224 
   3225       free((void *) tempImage);
   3226    }
   3227    return GL_TRUE;
   3228 }
   3229 
   3230 
   3231 /* non-normalized, signed int16 */
   3232 static GLboolean
   3233 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
   3234 {
   3235    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3236    const GLint components = _mesa_components_in_format(baseFormat);
   3237 
   3238    ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
   3239           dstFormat == MESA_FORMAT_RG_INT16 ||
   3240           dstFormat == MESA_FORMAT_RGB_INT16 ||
   3241           dstFormat == MESA_FORMAT_RGBA_INT16 ||
   3242           dstFormat == MESA_FORMAT_ALPHA_INT16 ||
   3243           dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
   3244           dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
   3245           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
   3246    ASSERT(baseInternalFormat == GL_RGBA ||
   3247           baseInternalFormat == GL_RGB ||
   3248           baseInternalFormat == GL_RG ||
   3249           baseInternalFormat == GL_RED ||
   3250           baseInternalFormat == GL_ALPHA ||
   3251           baseInternalFormat == GL_LUMINANCE ||
   3252           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3253           baseInternalFormat == GL_INTENSITY);
   3254    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort));
   3255 
   3256    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3257     * to integer formats.
   3258     */
   3259    if (!srcPacking->SwapBytes &&
   3260        baseInternalFormat == srcFormat &&
   3261        srcType == GL_SHORT) {
   3262       /* simple memcpy path */
   3263       memcpy_texture(ctx, dims,
   3264                      dstFormat,
   3265                      dstRowStride, dstSlices,
   3266                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3267                      srcAddr, srcPacking);
   3268    }
   3269    else {
   3270       /* general path */
   3271       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
   3272 						     baseInternalFormat,
   3273 						     baseFormat,
   3274 						     srcWidth, srcHeight, srcDepth,
   3275 						     srcFormat, srcType,
   3276 						     srcAddr,
   3277 						     srcPacking);
   3278       const GLuint *src = tempImage;
   3279       GLint img, row;
   3280       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3281       if (!tempImage)
   3282          return GL_FALSE;
   3283       for (img = 0; img < srcDepth; img++) {
   3284          GLubyte *dstRow = dstSlices[img];
   3285          for (row = 0; row < srcHeight; row++) {
   3286             GLshort *dstTexel = (GLshort *) dstRow;
   3287             GLint i;
   3288             if (is_unsigned) {
   3289                for (i = 0; i < srcWidth * components; i++) {
   3290                   dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
   3291                }
   3292             } else {
   3293                for (i = 0; i < srcWidth * components; i++) {
   3294                   dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
   3295                }
   3296             }
   3297             dstRow += dstRowStride;
   3298             src += srcWidth * components;
   3299          }
   3300       }
   3301 
   3302       free((void *) tempImage);
   3303    }
   3304    return GL_TRUE;
   3305 }
   3306 
   3307 
   3308 /* non-normalized, signed int32 */
   3309 static GLboolean
   3310 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
   3311 {
   3312    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3313    const GLint components = _mesa_components_in_format(baseFormat);
   3314 
   3315    ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
   3316           dstFormat == MESA_FORMAT_RG_INT32 ||
   3317           dstFormat == MESA_FORMAT_RGB_INT32 ||
   3318           dstFormat == MESA_FORMAT_RGBA_INT32 ||
   3319           dstFormat == MESA_FORMAT_ALPHA_INT32 ||
   3320           dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
   3321           dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
   3322           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
   3323    ASSERT(baseInternalFormat == GL_RGBA ||
   3324           baseInternalFormat == GL_RGB ||
   3325           baseInternalFormat == GL_RG ||
   3326           baseInternalFormat == GL_RED ||
   3327           baseInternalFormat == GL_ALPHA ||
   3328           baseInternalFormat == GL_LUMINANCE ||
   3329           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3330           baseInternalFormat == GL_INTENSITY);
   3331    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint));
   3332 
   3333    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3334     * to integer formats.
   3335     */
   3336    if (!srcPacking->SwapBytes &&
   3337        baseInternalFormat == srcFormat &&
   3338        srcType == GL_INT) {
   3339       /* simple memcpy path */
   3340       memcpy_texture(ctx, dims,
   3341                      dstFormat,
   3342                      dstRowStride, dstSlices,
   3343                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3344                      srcAddr, srcPacking);
   3345    }
   3346    else {
   3347       /* general path */
   3348       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
   3349 						     baseInternalFormat,
   3350 						     baseFormat,
   3351 						     srcWidth, srcHeight, srcDepth,
   3352 						     srcFormat, srcType,
   3353 						     srcAddr,
   3354 						     srcPacking);
   3355       const GLuint *src = tempImage;
   3356       GLint img, row;
   3357       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3358       if (!tempImage)
   3359          return GL_FALSE;
   3360       for (img = 0; img < srcDepth; img++) {
   3361          GLubyte *dstRow = dstSlices[img];
   3362          for (row = 0; row < srcHeight; row++) {
   3363             GLint *dstTexel = (GLint *) dstRow;
   3364             GLint i;
   3365             if (is_unsigned) {
   3366                for (i = 0; i < srcWidth * components; i++) {
   3367                   dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
   3368                }
   3369             } else {
   3370                for (i = 0; i < srcWidth * components; i++) {
   3371                   dstTexel[i] = (GLint) src[i];
   3372                }
   3373             }
   3374             dstRow += dstRowStride;
   3375             src += srcWidth * components;
   3376          }
   3377       }
   3378 
   3379       free((void *) tempImage);
   3380    }
   3381    return GL_TRUE;
   3382 }
   3383 
   3384 
   3385 /* non-normalized, unsigned int8 */
   3386 static GLboolean
   3387 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
   3388 {
   3389    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3390    const GLint components = _mesa_components_in_format(baseFormat);
   3391 
   3392    ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
   3393           dstFormat == MESA_FORMAT_RG_UINT8 ||
   3394           dstFormat == MESA_FORMAT_RGB_UINT8 ||
   3395           dstFormat == MESA_FORMAT_RGBA_UINT8 ||
   3396           dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
   3397           dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
   3398           dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
   3399           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
   3400    ASSERT(baseInternalFormat == GL_RGBA ||
   3401           baseInternalFormat == GL_RGB ||
   3402           baseInternalFormat == GL_RG ||
   3403           baseInternalFormat == GL_RED ||
   3404           baseInternalFormat == GL_ALPHA ||
   3405           baseInternalFormat == GL_LUMINANCE ||
   3406           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3407           baseInternalFormat == GL_INTENSITY);
   3408    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte));
   3409 
   3410    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3411     * to integer formats.
   3412     */
   3413    if (!srcPacking->SwapBytes &&
   3414        baseInternalFormat == srcFormat &&
   3415        srcType == GL_UNSIGNED_BYTE) {
   3416       /* simple memcpy path */
   3417       memcpy_texture(ctx, dims,
   3418                      dstFormat,
   3419                      dstRowStride, dstSlices,
   3420                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3421                      srcAddr, srcPacking);
   3422    }
   3423    else {
   3424       /* general path */
   3425       const GLuint *tempImage =
   3426          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
   3427                               srcWidth, srcHeight, srcDepth,
   3428                               srcFormat, srcType, srcAddr, srcPacking);
   3429       const GLuint *src = tempImage;
   3430       GLint img, row;
   3431       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3432       if (!tempImage)
   3433          return GL_FALSE;
   3434       for (img = 0; img < srcDepth; img++) {
   3435          GLubyte *dstRow = dstSlices[img];
   3436          for (row = 0; row < srcHeight; row++) {
   3437             GLubyte *dstTexel = (GLubyte *) dstRow;
   3438             GLint i;
   3439             if (is_unsigned) {
   3440                for (i = 0; i < srcWidth * components; i++) {
   3441                   dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
   3442                }
   3443             } else {
   3444                for (i = 0; i < srcWidth * components; i++) {
   3445                   dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
   3446                }
   3447             }
   3448             dstRow += dstRowStride;
   3449             src += srcWidth * components;
   3450          }
   3451       }
   3452 
   3453       free((void *) tempImage);
   3454    }
   3455    return GL_TRUE;
   3456 }
   3457 
   3458 
   3459 /* non-normalized, unsigned int16 */
   3460 static GLboolean
   3461 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
   3462 {
   3463    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3464    const GLint components = _mesa_components_in_format(baseFormat);
   3465 
   3466    ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
   3467           dstFormat == MESA_FORMAT_RG_UINT16 ||
   3468           dstFormat == MESA_FORMAT_RGB_UINT16 ||
   3469           dstFormat == MESA_FORMAT_RGBA_UINT16 ||
   3470           dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
   3471           dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
   3472           dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
   3473           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
   3474    ASSERT(baseInternalFormat == GL_RGBA ||
   3475           baseInternalFormat == GL_RGB ||
   3476           baseInternalFormat == GL_RG ||
   3477           baseInternalFormat == GL_RED ||
   3478           baseInternalFormat == GL_ALPHA ||
   3479           baseInternalFormat == GL_LUMINANCE ||
   3480           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3481           baseInternalFormat == GL_INTENSITY);
   3482    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort));
   3483 
   3484    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3485     * to integer formats.
   3486     */
   3487    if (!srcPacking->SwapBytes &&
   3488        baseInternalFormat == srcFormat &&
   3489        srcType == GL_UNSIGNED_SHORT) {
   3490       /* simple memcpy path */
   3491       memcpy_texture(ctx, dims,
   3492                      dstFormat,
   3493                      dstRowStride, dstSlices,
   3494                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3495                      srcAddr, srcPacking);
   3496    }
   3497    else {
   3498       /* general path */
   3499       const GLuint *tempImage =
   3500          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
   3501                               srcWidth, srcHeight, srcDepth,
   3502                               srcFormat, srcType, srcAddr, srcPacking);
   3503       const GLuint *src = tempImage;
   3504       GLint img, row;
   3505       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3506       if (!tempImage)
   3507          return GL_FALSE;
   3508       for (img = 0; img < srcDepth; img++) {
   3509          GLubyte *dstRow = dstSlices[img];
   3510          for (row = 0; row < srcHeight; row++) {
   3511             GLushort *dstTexel = (GLushort *) dstRow;
   3512             GLint i;
   3513             if (is_unsigned) {
   3514                for (i = 0; i < srcWidth * components; i++) {
   3515                   dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
   3516               }
   3517             } else {
   3518                for (i = 0; i < srcWidth * components; i++) {
   3519                   dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
   3520                }
   3521             }
   3522             dstRow += dstRowStride;
   3523             src += srcWidth * components;
   3524          }
   3525       }
   3526 
   3527       free((void *) tempImage);
   3528    }
   3529    return GL_TRUE;
   3530 }
   3531 
   3532 
   3533 /* non-normalized, unsigned int32 */
   3534 static GLboolean
   3535 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
   3536 {
   3537    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3538    const GLint components = _mesa_components_in_format(baseFormat);
   3539 
   3540    ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
   3541           dstFormat == MESA_FORMAT_RG_UINT32 ||
   3542           dstFormat == MESA_FORMAT_RGB_UINT32 ||
   3543           dstFormat == MESA_FORMAT_RGBA_UINT32 ||
   3544           dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
   3545           dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
   3546           dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
   3547           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
   3548    ASSERT(baseInternalFormat == GL_RGBA ||
   3549           baseInternalFormat == GL_RGB ||
   3550           baseInternalFormat == GL_RG ||
   3551           baseInternalFormat == GL_RED ||
   3552           baseInternalFormat == GL_ALPHA ||
   3553           baseInternalFormat == GL_LUMINANCE ||
   3554           baseInternalFormat == GL_LUMINANCE_ALPHA ||
   3555           baseInternalFormat == GL_INTENSITY);
   3556    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint));
   3557 
   3558    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
   3559     * to integer formats.
   3560     */
   3561    if (!srcPacking->SwapBytes &&
   3562        baseInternalFormat == srcFormat &&
   3563        srcType == GL_UNSIGNED_INT) {
   3564       /* simple memcpy path */
   3565       memcpy_texture(ctx, dims,
   3566                      dstFormat,
   3567                      dstRowStride, dstSlices,
   3568                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3569                      srcAddr, srcPacking);
   3570    }
   3571    else {
   3572       /* general path */
   3573       const GLuint *tempImage =
   3574          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
   3575                               srcWidth, srcHeight, srcDepth,
   3576                               srcFormat, srcType, srcAddr, srcPacking);
   3577       const GLuint *src = tempImage;
   3578       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3579       GLint img, row;
   3580       if (!tempImage)
   3581          return GL_FALSE;
   3582       for (img = 0; img < srcDepth; img++) {
   3583          GLubyte *dstRow = dstSlices[img];
   3584          for (row = 0; row < srcHeight; row++) {
   3585             GLuint *dstTexel = (GLuint *) dstRow;
   3586             GLint i;
   3587             if (is_unsigned) {
   3588                for (i = 0; i < srcWidth * components; i++) {
   3589                   dstTexel[i] = src[i];
   3590                }
   3591             } else {
   3592                for (i = 0; i < srcWidth * components; i++) {
   3593                   dstTexel[i] = MAX2((GLint) src[i], 0);
   3594                }
   3595             }
   3596             dstRow += dstRowStride;
   3597             src += srcWidth * components;
   3598          }
   3599       }
   3600 
   3601       free((void *) tempImage);
   3602    }
   3603    return GL_TRUE;
   3604 }
   3605 
   3606 
   3607 
   3608 
   3609 #if FEATURE_EXT_texture_sRGB
   3610 static GLboolean
   3611 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
   3612 {
   3613    gl_format newDstFormat;
   3614    GLboolean k;
   3615 
   3616    ASSERT(dstFormat == MESA_FORMAT_SRGB8);
   3617 
   3618    /* reuse normal rgb texstore code */
   3619    newDstFormat = MESA_FORMAT_RGB888;
   3620 
   3621    k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
   3622                              newDstFormat,
   3623                              dstRowStride, dstSlices,
   3624                              srcWidth, srcHeight, srcDepth,
   3625                              srcFormat, srcType,
   3626                              srcAddr, srcPacking);
   3627    return k;
   3628 }
   3629 
   3630 
   3631 static GLboolean
   3632 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
   3633 {
   3634    gl_format newDstFormat;
   3635    GLboolean k;
   3636 
   3637    ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
   3638 
   3639    /* reuse normal rgba texstore code */
   3640    newDstFormat = MESA_FORMAT_RGBA8888;
   3641    k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
   3642                                newDstFormat,
   3643                                dstRowStride, dstSlices,
   3644                                srcWidth, srcHeight, srcDepth,
   3645                                srcFormat, srcType,
   3646                                srcAddr, srcPacking);
   3647    return k;
   3648 }
   3649 
   3650 
   3651 static GLboolean
   3652 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
   3653 {
   3654    gl_format newDstFormat;
   3655    GLboolean k;
   3656 
   3657    ASSERT(dstFormat == MESA_FORMAT_SARGB8);
   3658 
   3659    /* reuse normal rgba texstore code */
   3660    newDstFormat = MESA_FORMAT_ARGB8888;
   3661 
   3662    k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
   3663                                newDstFormat,
   3664                                dstRowStride, dstSlices,
   3665                                srcWidth, srcHeight, srcDepth,
   3666                                srcFormat, srcType,
   3667                                srcAddr, srcPacking);
   3668    return k;
   3669 }
   3670 
   3671 
   3672 static GLboolean
   3673 _mesa_texstore_sl8(TEXSTORE_PARAMS)
   3674 {
   3675    gl_format newDstFormat;
   3676    GLboolean k;
   3677 
   3678    ASSERT(dstFormat == MESA_FORMAT_SL8);
   3679 
   3680    newDstFormat = MESA_FORMAT_L8;
   3681 
   3682    /* _mesa_textore_a8 handles luminance8 too */
   3683    k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
   3684                              newDstFormat,
   3685                              dstRowStride, dstSlices,
   3686                              srcWidth, srcHeight, srcDepth,
   3687                              srcFormat, srcType,
   3688                              srcAddr, srcPacking);
   3689    return k;
   3690 }
   3691 
   3692 
   3693 static GLboolean
   3694 _mesa_texstore_sla8(TEXSTORE_PARAMS)
   3695 {
   3696    gl_format newDstFormat;
   3697    GLboolean k;
   3698 
   3699    ASSERT(dstFormat == MESA_FORMAT_SLA8);
   3700 
   3701    /* reuse normal luminance/alpha texstore code */
   3702    newDstFormat = MESA_FORMAT_AL88;
   3703 
   3704    k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
   3705 			      newDstFormat,
   3706 			      dstRowStride, dstSlices,
   3707 			      srcWidth, srcHeight, srcDepth,
   3708 			      srcFormat, srcType,
   3709 			      srcAddr, srcPacking);
   3710    return k;
   3711 }
   3712 
   3713 #else
   3714 
   3715 /* these are used only in texstore_funcs[] below */
   3716 #define _mesa_texstore_srgb8 NULL
   3717 #define _mesa_texstore_srgba8 NULL
   3718 #define _mesa_texstore_sargb8 NULL
   3719 #define _mesa_texstore_sl8 NULL
   3720 #define _mesa_texstore_sla8 NULL
   3721 
   3722 #endif /* FEATURE_EXT_texture_sRGB */
   3723 
   3724 static GLboolean
   3725 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
   3726 {
   3727    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3728 
   3729    ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
   3730    ASSERT(baseInternalFormat == GL_RGB);
   3731 
   3732    if (!ctx->_ImageTransferState &&
   3733        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   3734                                             srcPacking->SwapBytes)) {
   3735       /* simple memcpy path */
   3736       memcpy_texture(ctx, dims,
   3737                      dstFormat,
   3738                      dstRowStride, dstSlices,
   3739                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3740                      srcAddr, srcPacking);
   3741    }
   3742    else {
   3743       /* general path */
   3744       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   3745                                                  baseInternalFormat,
   3746                                                  baseFormat,
   3747                                                  srcWidth, srcHeight, srcDepth,
   3748                                                  srcFormat, srcType, srcAddr,
   3749                                                  srcPacking,
   3750                                                  ctx->_ImageTransferState);
   3751       const GLfloat *srcRow = tempImage;
   3752       GLint img, row, col;
   3753       if (!tempImage)
   3754          return GL_FALSE;
   3755       for (img = 0; img < srcDepth; img++) {
   3756          GLubyte *dstRow = dstSlices[img];
   3757          for (row = 0; row < srcHeight; row++) {
   3758             GLuint *dstUI = (GLuint*)dstRow;
   3759             for (col = 0; col < srcWidth; col++) {
   3760                dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
   3761             }
   3762             dstRow += dstRowStride;
   3763             srcRow += srcWidth * 3;
   3764          }
   3765       }
   3766 
   3767       free((void *) tempImage);
   3768    }
   3769    return GL_TRUE;
   3770 }
   3771 
   3772 static GLboolean
   3773 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
   3774 {
   3775    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3776 
   3777    ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
   3778    ASSERT(baseInternalFormat == GL_RGB);
   3779 
   3780    if (!ctx->_ImageTransferState &&
   3781        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   3782                                             srcPacking->SwapBytes)) {
   3783       /* simple memcpy path */
   3784       memcpy_texture(ctx, dims,
   3785                      dstFormat,
   3786                      dstRowStride, dstSlices,
   3787                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3788                      srcAddr, srcPacking);
   3789    }
   3790    else {
   3791       /* general path */
   3792       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
   3793                                                  baseInternalFormat,
   3794                                                  baseFormat,
   3795                                                  srcWidth, srcHeight, srcDepth,
   3796                                                  srcFormat, srcType, srcAddr,
   3797                                                  srcPacking,
   3798                                                  ctx->_ImageTransferState);
   3799       const GLfloat *srcRow = tempImage;
   3800       GLint img, row, col;
   3801       if (!tempImage)
   3802          return GL_FALSE;
   3803       for (img = 0; img < srcDepth; img++) {
   3804          GLubyte *dstRow = dstSlices[img];
   3805          for (row = 0; row < srcHeight; row++) {
   3806             GLuint *dstUI = (GLuint*)dstRow;
   3807             for (col = 0; col < srcWidth; col++) {
   3808                dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
   3809             }
   3810             dstRow += dstRowStride;
   3811             srcRow += srcWidth * 3;
   3812          }
   3813       }
   3814 
   3815       free((void *) tempImage);
   3816    }
   3817    return GL_TRUE;
   3818 }
   3819 
   3820 
   3821 static GLboolean
   3822 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
   3823 {
   3824    ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
   3825    ASSERT(srcFormat == GL_DEPTH_STENCIL ||
   3826           srcFormat == GL_DEPTH_COMPONENT ||
   3827           srcFormat == GL_STENCIL_INDEX);
   3828    ASSERT(srcFormat != GL_DEPTH_STENCIL ||
   3829           srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
   3830 
   3831    if (srcFormat == GL_DEPTH_STENCIL &&
   3832        ctx->Pixel.DepthScale == 1.0f &&
   3833        ctx->Pixel.DepthBias == 0.0f &&
   3834        !srcPacking->SwapBytes) {
   3835       /* simple path */
   3836       memcpy_texture(ctx, dims,
   3837                      dstFormat,
   3838                      dstRowStride, dstSlices,
   3839                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3840                      srcAddr, srcPacking);
   3841    }
   3842    else if (srcFormat == GL_DEPTH_COMPONENT ||
   3843             srcFormat == GL_STENCIL_INDEX) {
   3844       GLint img, row;
   3845       const GLint srcRowStride
   3846          = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
   3847          / sizeof(uint64_t);
   3848 
   3849       /* In case we only upload depth we need to preserve the stencil */
   3850       for (img = 0; img < srcDepth; img++) {
   3851          uint64_t *dstRow = (uint64_t *) dstSlices[img];
   3852          const uint64_t *src
   3853             = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
   3854                   srcWidth, srcHeight,
   3855                   srcFormat, srcType,
   3856                   img, 0, 0);
   3857          for (row = 0; row < srcHeight; row++) {
   3858             /* The unpack functions with:
   3859              *    dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
   3860              * only write their own dword, so the other dword (stencil
   3861              * or depth) is preserved. */
   3862             if (srcFormat != GL_STENCIL_INDEX)
   3863                _mesa_unpack_depth_span(ctx, srcWidth,
   3864                                        GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
   3865                                        dstRow, /* dst addr */
   3866                                        ~0U, srcType, src, srcPacking);
   3867 
   3868             if (srcFormat != GL_DEPTH_COMPONENT)
   3869                _mesa_unpack_stencil_span(ctx, srcWidth,
   3870                                          GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
   3871                                          dstRow, /* dst addr */
   3872                                          srcType, src, srcPacking,
   3873                                          ctx->_ImageTransferState);
   3874 
   3875             src += srcRowStride;
   3876             dstRow += dstRowStride / sizeof(uint64_t);
   3877          }
   3878       }
   3879    }
   3880    return GL_TRUE;
   3881 }
   3882 
   3883 static GLboolean
   3884 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
   3885 {
   3886    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3887 
   3888    ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
   3889    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   3890 
   3891    if (baseInternalFormat == GL_RGBA &&
   3892        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   3893                                             srcPacking->SwapBytes)) {
   3894       /* simple memcpy path */
   3895       memcpy_texture(ctx, dims,
   3896                      dstFormat,
   3897                      dstRowStride, dstSlices,
   3898                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3899                      srcAddr, srcPacking);
   3900    }
   3901    else {
   3902       /* general path */
   3903       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
   3904                                                      baseInternalFormat,
   3905                                                      baseFormat,
   3906                                                      srcWidth, srcHeight,
   3907                                                      srcDepth, srcFormat,
   3908                                                      srcType, srcAddr,
   3909                                                      srcPacking);
   3910       const GLuint *src = tempImage;
   3911       GLint img, row, col;
   3912       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3913       if (!tempImage)
   3914          return GL_FALSE;
   3915       for (img = 0; img < srcDepth; img++) {
   3916          GLubyte *dstRow = dstSlices[img];
   3917 
   3918          for (row = 0; row < srcHeight; row++) {
   3919             GLuint *dstUI = (GLuint *) dstRow;
   3920             if (is_unsigned) {
   3921                for (col = 0; col < srcWidth; col++) {
   3922                   GLushort a,r,g,b;
   3923                   r = MIN2(src[RCOMP], 0x3ff);
   3924                   g = MIN2(src[GCOMP], 0x3ff);
   3925                   b = MIN2(src[BCOMP], 0x3ff);
   3926                   a = MIN2(src[ACOMP], 0x003);
   3927                   dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
   3928                   src += 4;
   3929                }
   3930             } else {
   3931                for (col = 0; col < srcWidth; col++) {
   3932                   GLushort a,r,g,b;
   3933                   r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
   3934                   g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
   3935                   b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
   3936                   a = CLAMP((GLint) src[ACOMP], 0, 0x003);
   3937                   dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
   3938                   src += 4;
   3939                }
   3940             }
   3941             dstRow += dstRowStride;
   3942          }
   3943       }
   3944       free((void *) tempImage);
   3945    }
   3946    return GL_TRUE;
   3947 }
   3948 
   3949 static GLboolean
   3950 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
   3951 {
   3952    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
   3953 
   3954    ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
   3955    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
   3956 
   3957    if (baseInternalFormat == GL_RGBA &&
   3958        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
   3959                                             srcPacking->SwapBytes)) {
   3960       /* simple memcpy path */
   3961       memcpy_texture(ctx, dims,
   3962                      dstFormat,
   3963                      dstRowStride, dstSlices,
   3964                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
   3965                      srcAddr, srcPacking);
   3966    }
   3967    else {
   3968       /* general path */
   3969       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
   3970                                                      baseInternalFormat,
   3971                                                      baseFormat,
   3972                                                      srcWidth, srcHeight,
   3973                                                      srcDepth, srcFormat,
   3974                                                      srcType, srcAddr,
   3975                                                      srcPacking);
   3976       const GLuint *src = tempImage;
   3977       GLint img, row, col;
   3978       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
   3979       if (!tempImage)
   3980          return GL_FALSE;
   3981       for (img = 0; img < srcDepth; img++) {
   3982          GLubyte *dstRow = dstSlices[img];
   3983 
   3984          for (row = 0; row < srcHeight; row++) {
   3985             GLuint *dstUI = (GLuint *) dstRow;
   3986             if (is_unsigned) {
   3987                for (col = 0; col < srcWidth; col++) {
   3988                   GLushort a,r,g,b;
   3989                   r = MIN2(src[RCOMP], 0x3ff);
   3990                   g = MIN2(src[GCOMP], 0x3ff);
   3991                   b = MIN2(src[BCOMP], 0x3ff);
   3992                   a = MIN2(src[ACOMP], 0x003);
   3993                   dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
   3994                   src += 4;
   3995                }
   3996             } else {
   3997                for (col = 0; col < srcWidth; col++) {
   3998                   GLushort a,r,g,b;
   3999                   r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
   4000                   g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
   4001                   b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
   4002                   a = CLAMP((GLint) src[ACOMP], 0, 0x003);
   4003                   dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
   4004                   src += 4;
   4005                }
   4006             }
   4007             dstRow += dstRowStride;
   4008          }
   4009       }
   4010       free((void *) tempImage);
   4011    }
   4012    return GL_TRUE;
   4013 }
   4014 
   4015 static GLboolean
   4016 _mesa_texstore_null(TEXSTORE_PARAMS)
   4017 {
   4018    (void) ctx; (void) dims;
   4019    (void) baseInternalFormat;
   4020    (void) dstFormat;
   4021    (void) dstRowStride; (void) dstSlices,
   4022    (void) srcWidth; (void) srcHeight; (void) srcDepth;
   4023    (void) srcFormat; (void) srcType;
   4024    (void) srcAddr;
   4025    (void) srcPacking;
   4026 
   4027    /* should never happen */
   4028    _mesa_problem(NULL, "_mesa_texstore_null() is called");
   4029    return GL_FALSE;
   4030 }
   4031 
   4032 
   4033 /**
   4034  * Return the StoreTexImageFunc pointer to store an image in the given format.
   4035  */
   4036 static StoreTexImageFunc
   4037 _mesa_get_texstore_func(gl_format format)
   4038 {
   4039    static StoreTexImageFunc table[MESA_FORMAT_COUNT];
   4040    static GLboolean initialized = GL_FALSE;
   4041 
   4042    if (!initialized) {
   4043       table[MESA_FORMAT_NONE] = _mesa_texstore_null;
   4044 
   4045       table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
   4046       table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
   4047       table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
   4048       table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
   4049       table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
   4050       table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
   4051       table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
   4052       table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
   4053       table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
   4054       table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
   4055       table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
   4056       table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
   4057       table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
   4058       table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
   4059       table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
   4060       table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
   4061       table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
   4062       table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
   4063       table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
   4064       table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
   4065       table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
   4066       table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
   4067       table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
   4068       table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
   4069       table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
   4070       table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
   4071       table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
   4072       table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
   4073       table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
   4074       table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
   4075       table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
   4076       table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
   4077       table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
   4078       table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
   4079       table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
   4080       table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
   4081       table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
   4082       table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
   4083       table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
   4084       table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
   4085       table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
   4086       table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
   4087       table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
   4088       table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
   4089       table[MESA_FORMAT_S8] = _mesa_texstore_s8;
   4090       table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
   4091       table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
   4092       table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
   4093       table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
   4094       table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
   4095       table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
   4096       table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
   4097       table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
   4098       table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
   4099       table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
   4100       table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
   4101       table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
   4102       table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
   4103       table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
   4104       table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
   4105       table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
   4106       table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
   4107       table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
   4108       table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
   4109       table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
   4110       table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
   4111       table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
   4112       table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
   4113       table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
   4114       table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
   4115       table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
   4116       table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
   4117       table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
   4118       table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
   4119       table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
   4120       table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
   4121       table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
   4122       table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
   4123       table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
   4124       table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
   4125       table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
   4126       table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
   4127       table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
   4128       table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
   4129       table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
   4130       table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
   4131       table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
   4132       table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
   4133       table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
   4134       table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
   4135       table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
   4136       table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
   4137       table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
   4138       table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
   4139       table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
   4140       table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
   4141       table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
   4142       table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
   4143       table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
   4144       table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
   4145       table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
   4146       table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
   4147       table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
   4148       table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
   4149       table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
   4150       table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
   4151       table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
   4152       table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
   4153 
   4154       table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
   4155       table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
   4156       table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
   4157       table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
   4158       table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
   4159       table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
   4160 
   4161       table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
   4162       table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
   4163       table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
   4164       table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
   4165       table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
   4166       table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
   4167 
   4168       table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
   4169       table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
   4170       table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
   4171       table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
   4172       table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
   4173       table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
   4174 
   4175       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
   4176       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
   4177       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
   4178       table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
   4179       table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
   4180       table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
   4181 
   4182       table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
   4183       table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
   4184       table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
   4185       table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
   4186       table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
   4187       table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
   4188       table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
   4189       table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
   4190       table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
   4191       table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
   4192       table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
   4193       table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
   4194 
   4195       table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
   4196       table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
   4197       table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
   4198       table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
   4199       table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
   4200       table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
   4201       table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
   4202       table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
   4203       table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
   4204       table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
   4205       table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
   4206       table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
   4207 
   4208       table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
   4209       table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
   4210       initialized = GL_TRUE;
   4211    }
   4212 
   4213    ASSERT(table[format]);
   4214    return table[format];
   4215 }
   4216 
   4217 
   4218 /**
   4219  * Store user data into texture memory.
   4220  * Called via glTex[Sub]Image1/2/3D()
   4221  */
   4222 GLboolean
   4223 _mesa_texstore(TEXSTORE_PARAMS)
   4224 {
   4225    StoreTexImageFunc storeImage;
   4226    GLboolean success;
   4227 
   4228    storeImage = _mesa_get_texstore_func(dstFormat);
   4229 
   4230    success = storeImage(ctx, dims, baseInternalFormat,
   4231                         dstFormat,
   4232                         dstRowStride, dstSlices,
   4233                         srcWidth, srcHeight, srcDepth,
   4234                         srcFormat, srcType, srcAddr, srcPacking);
   4235    return success;
   4236 }
   4237 
   4238 
   4239 /**
   4240  * Normally, we'll only _write_ texel data to a texture when we map it.
   4241  * But if the user is providing depth or stencil values and the texture
   4242  * image is a combined depth/stencil format, we'll actually read from
   4243  * the texture buffer too (in order to insert the depth or stencil values.
   4244  * \param userFormat  the user-provided image format
   4245  * \param texFormat  the destination texture format
   4246  */
   4247 static GLbitfield
   4248 get_read_write_mode(GLenum userFormat, gl_format texFormat)
   4249 {
   4250    if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
   4251        && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
   4252       return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
   4253    else
   4254       return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
   4255 }
   4256 
   4257 
   4258 /**
   4259  * Helper function for storing 1D, 2D, 3D whole and subimages into texture
   4260  * memory.
   4261  * The source of the image data may be user memory or a PBO.  In the later
   4262  * case, we'll map the PBO, copy from it, then unmap it.
   4263  */
   4264 static void
   4265 store_texsubimage(struct gl_context *ctx,
   4266                   struct gl_texture_image *texImage,
   4267                   GLint xoffset, GLint yoffset, GLint zoffset,
   4268                   GLint width, GLint height, GLint depth,
   4269                   GLenum format, GLenum type, const GLvoid *pixels,
   4270                   const struct gl_pixelstore_attrib *packing,
   4271                   const char *caller)
   4272 
   4273 {
   4274    const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
   4275    const GLenum target = texImage->TexObject->Target;
   4276    GLboolean success = GL_FALSE;
   4277    GLuint dims, slice, numSlices = 1, sliceOffset = 0;
   4278    GLint srcImageStride = 0;
   4279    const GLubyte *src;
   4280 
   4281    assert(xoffset + width <= texImage->Width);
   4282    assert(yoffset + height <= texImage->Height);
   4283    assert(zoffset + depth <= texImage->Depth);
   4284 
   4285    switch (target) {
   4286    case GL_TEXTURE_1D:
   4287       dims = 1;
   4288       break;
   4289    case GL_TEXTURE_2D_ARRAY:
   4290    case GL_TEXTURE_3D:
   4291       dims = 3;
   4292       break;
   4293    default:
   4294       dims = 2;
   4295    }
   4296 
   4297    /* get pointer to src pixels (may be in a pbo which we'll map here) */
   4298    src = (const GLubyte *)
   4299       _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
   4300                                   format, type, pixels, packing, caller);
   4301    if (!src)
   4302       return;
   4303 
   4304    /* compute slice info (and do some sanity checks) */
   4305    switch (target) {
   4306    case GL_TEXTURE_2D:
   4307    case GL_TEXTURE_RECTANGLE:
   4308    case GL_TEXTURE_CUBE_MAP:
   4309       /* one image slice, nothing special needs to be done */
   4310       break;
   4311    case GL_TEXTURE_1D:
   4312       assert(height == 1);
   4313       assert(depth == 1);
   4314       assert(yoffset == 0);
   4315       assert(zoffset == 0);
   4316       break;
   4317    case GL_TEXTURE_1D_ARRAY:
   4318       assert(depth == 1);
   4319       assert(zoffset == 0);
   4320       numSlices = height;
   4321       sliceOffset = yoffset;
   4322       height = 1;
   4323       yoffset = 0;
   4324       srcImageStride = _mesa_image_row_stride(packing, width, format, type);
   4325       break;
   4326    case GL_TEXTURE_2D_ARRAY:
   4327       numSlices = depth;
   4328       sliceOffset = zoffset;
   4329       depth = 1;
   4330       zoffset = 0;
   4331       srcImageStride = _mesa_image_image_stride(packing, width, height,
   4332                                                 format, type);
   4333       break;
   4334    case GL_TEXTURE_3D:
   4335       /* we'll store 3D images as a series of slices */
   4336       numSlices = depth;
   4337       sliceOffset = zoffset;
   4338       srcImageStride = _mesa_image_image_stride(packing, width, height,
   4339                                                 format, type);
   4340       break;
   4341    default:
   4342       _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
   4343       return;
   4344    }
   4345 
   4346    assert(numSlices == 1 || srcImageStride != 0);
   4347 
   4348    for (slice = 0; slice < numSlices; slice++) {
   4349       GLubyte *dstMap;
   4350       GLint dstRowStride;
   4351 
   4352       ctx->Driver.MapTextureImage(ctx, texImage,
   4353                                   slice + sliceOffset,
   4354                                   xoffset, yoffset, width, height,
   4355                                   mapMode, &dstMap, &dstRowStride);
   4356       if (dstMap) {
   4357          /* Note: we're only storing a 2D (or 1D) slice at a time but we need
   4358           * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
   4359           * used for 3D images.
   4360           */
   4361          success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
   4362                                   texImage->TexFormat,
   4363                                   dstRowStride,
   4364                                   &dstMap,
   4365                                   width, height, 1,  /* w, h, d */
   4366                                   format, type, src, packing);
   4367 
   4368          ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
   4369       }
   4370 
   4371       src += srcImageStride;
   4372 
   4373       if (!success)
   4374          break;
   4375    }
   4376 
   4377    if (!success)
   4378       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
   4379 
   4380    _mesa_unmap_teximage_pbo(ctx, packing);
   4381 }
   4382 
   4383 
   4384 
   4385 /**
   4386  * Fallback code for ctx->Driver.TexImage().
   4387  * Basically, allocate storage for the texture image, then copy the
   4388  * user's image into it.
   4389  */
   4390 void
   4391 _mesa_store_teximage(struct gl_context *ctx,
   4392                      GLuint dims,
   4393                      struct gl_texture_image *texImage,
   4394                      GLenum format, GLenum type, const GLvoid *pixels,
   4395                      const struct gl_pixelstore_attrib *packing)
   4396 {
   4397    assert(dims == 1 || dims == 2 || dims == 3);
   4398 
   4399    if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
   4400       return;
   4401 
   4402    /* allocate storage for texture data */
   4403    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
   4404       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
   4405       return;
   4406    }
   4407 
   4408    store_texsubimage(ctx, texImage,
   4409                      0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
   4410                      format, type, pixels, packing, "glTexImage");
   4411 }
   4412 
   4413 
   4414 /*
   4415  * Fallback for Driver.TexSubImage().
   4416  */
   4417 void
   4418 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
   4419                         struct gl_texture_image *texImage,
   4420                         GLint xoffset, GLint yoffset, GLint zoffset,
   4421                         GLint width, GLint height, GLint depth,
   4422                         GLenum format, GLenum type, const void *pixels,
   4423                         const struct gl_pixelstore_attrib *packing)
   4424 {
   4425    store_texsubimage(ctx, texImage,
   4426                      xoffset, yoffset, zoffset, width, height, depth,
   4427                      format, type, pixels, packing, "glTexSubImage");
   4428 }
   4429 
   4430 
   4431 /**
   4432  * Fallback for Driver.CompressedTexImage()
   4433  */
   4434 void
   4435 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
   4436                                 struct gl_texture_image *texImage,
   4437                                 GLsizei imageSize, const GLvoid *data)
   4438 {
   4439    /* only 2D compressed images are supported at this time */
   4440    if (dims != 2) {
   4441       _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
   4442       return;
   4443    }
   4444 
   4445    /* This is pretty simple, because unlike the general texstore path we don't
   4446     * have to worry about the usual image unpacking or image transfer
   4447     * operations.
   4448     */
   4449    ASSERT(texImage);
   4450    ASSERT(texImage->Width > 0);
   4451    ASSERT(texImage->Height > 0);
   4452    ASSERT(texImage->Depth == 1);
   4453 
   4454    /* allocate storage for texture data */
   4455    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
   4456       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
   4457       return;
   4458    }
   4459 
   4460    _mesa_store_compressed_texsubimage(ctx, dims, texImage,
   4461                                       0, 0, 0,
   4462                                       texImage->Width, texImage->Height, texImage->Depth,
   4463                                       texImage->TexFormat,
   4464                                       imageSize, data);
   4465 }
   4466 
   4467 
   4468 /**
   4469  * Fallback for Driver.CompressedTexSubImage()
   4470  */
   4471 void
   4472 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
   4473                                    struct gl_texture_image *texImage,
   4474                                    GLint xoffset, GLint yoffset, GLint zoffset,
   4475                                    GLsizei width, GLsizei height, GLsizei depth,
   4476                                    GLenum format,
   4477                                    GLsizei imageSize, const GLvoid *data)
   4478 {
   4479    GLint bytesPerRow, dstRowStride, srcRowStride;
   4480    GLint i, rows;
   4481    GLubyte *dstMap;
   4482    const GLubyte *src;
   4483    const gl_format texFormat = texImage->TexFormat;
   4484    GLuint bw, bh;
   4485 
   4486    if (dims != 2) {
   4487       _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
   4488       return;
   4489    }
   4490 
   4491    _mesa_get_format_block_size(texFormat, &bw, &bh);
   4492 
   4493    /* get pointer to src pixels (may be in a pbo which we'll map here) */
   4494    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
   4495                                                  &ctx->Unpack,
   4496                                                  "glCompressedTexSubImage2D");
   4497    if (!data)
   4498       return;
   4499 
   4500    srcRowStride = _mesa_format_row_stride(texFormat, width);
   4501    src = (const GLubyte *) data;
   4502 
   4503    /* Map dest texture buffer */
   4504    ctx->Driver.MapTextureImage(ctx, texImage, 0,
   4505                                xoffset, yoffset, width, height,
   4506                                GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
   4507                                &dstMap, &dstRowStride);
   4508 
   4509    if (dstMap) {
   4510       bytesPerRow = srcRowStride;  /* bytes per row of blocks */
   4511       rows = (height + bh - 1) / bh;  /* rows in blocks */
   4512 
   4513       /* copy rows of blocks */
   4514       for (i = 0; i < rows; i++) {
   4515          memcpy(dstMap, src, bytesPerRow);
   4516          dstMap += dstRowStride;
   4517          src += srcRowStride;
   4518       }
   4519 
   4520       ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
   4521    }
   4522    else {
   4523       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
   4524    }
   4525 
   4526    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
   4527 }
   4528