Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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