Subversion Repositories Kolibri OS

Rev

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

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