texstore.c revision 07d6a983595b7ee52c8448fc579d952ce36472b8
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
34f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Version:  6.1
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
55e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
603c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
6189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h"
62371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul#include "texutil.h"
668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Given an internal texture format enum or 1, 2, 3, 4 return the
708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * number of components for the format.  Return -1 if invalid enum.
738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulstatic GLint
758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulcomponents_in_intformat( GLint format )
768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   switch (format) {
788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA:
798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA4:
808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA8:
818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA12:
828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA16:
838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 1:
858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE:
868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE4:
878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE8:
888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12:
898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE16:
908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 2:
928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE_ALPHA:
938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE4_ALPHA4:
948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE6_ALPHA2:
958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE8_ALPHA8:
968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12_ALPHA4:
978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12_ALPHA12:
988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE16_ALPHA16:
998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 2;
1008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY:
1018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY4:
1028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY8:
1038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY12:
1048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY16:
1058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
1068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 3:
1078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB:
1088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_R3_G3_B2:
1098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB4:
1108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB5:
1118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB8:
1128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB10:
1138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB12:
1148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB16:
1158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 3;
1168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 4:
1178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA:
1188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA2:
1198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA4:
1208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB5_A1:
1218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA8:
1228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB10_A2:
1238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA12:
1248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA16:
1258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 4;
1268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX:
1278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX1_EXT:
1288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX2_EXT:
1298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX4_EXT:
1308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX8_EXT:
1318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX12_EXT:
1328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX16_EXT:
1338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
134f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT:
135f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT16_SGIX:
136f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT24_SGIX:
137f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT32_SGIX:
138f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         return 1;
139c5b995066020191982b2315fc45d05e068eee761Brian Paul      case GL_YCBCR_MESA:
140c5b995066020191982b2315fc45d05e068eee761Brian Paul         return 2; /* Y + (Cb or Cr) */
1418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      default:
1428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return -1;  /* error */
1438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
1448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
1458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
1488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This function is used to transfer the user's image data into a texture
1498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * image buffer.  We handle both full texture images and subtexture images.
1508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * We also take care of all image transfer operations here, including
1518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convolution, scale/bias, colortables, etc.
1528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
15389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The destination texel type is always GLchan.
15489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The destination texel format is one of the 6 basic types.
1558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
1568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * A hardware driver may use this as a helper routine to unpack and
1578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * apply pixel transfer ops into a temporary image buffer.  Then,
1588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convert the temporary image into the special hardware format.
1598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
1606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param
1618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   dimensions - 1, 2, or 3
16289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   texDestFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
16389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *                   GL_RGB or GL_RGBA (the destination format)
16456671022f97cfbc199a47b3338125431e42030eeBrian Paul *   texDestAddr - destination image address
1658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
1668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   dstXoffset, dstYoffset, dstZoffset - position to store the image within
1678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *      the destination 3D texture
16856671022f97cfbc199a47b3338125431e42030eeBrian Paul *   dstRowStride, dstImageStride - dest image strides in bytes
1698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
1708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
1718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcPacking - describes packing of incoming image.
1721c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   transferOps - mask of pixel transfer operations
1738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
1747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulstatic void
1757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paultransfer_teximage(GLcontext *ctx, GLuint dimensions,
1767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLenum texDestFormat, GLvoid *texDestAddr,
1777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint srcWidth, GLint srcHeight, GLint srcDepth,
1787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
1797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint dstRowStride, GLint dstImageStride,
1807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLenum srcFormat, GLenum srcType,
1817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  const GLvoid *srcAddr,
1821c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                  const struct gl_pixelstore_attrib *srcPacking,
1831c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                  GLuint transferOps)
1848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
1858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint texComponents;
1868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(ctx);
1888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dimensions >= 1 && dimensions <= 3);
18989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texDestFormat == GL_LUMINANCE ||
19089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          texDestFormat == GL_INTENSITY ||
19189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          texDestFormat == GL_LUMINANCE_ALPHA ||
19289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          texDestFormat == GL_ALPHA ||
19389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          texDestFormat == GL_RGB ||
1942a7243481a40dee437d4a95ac39b84e550aa98f6Brian Paul          texDestFormat == GL_RGBA ||
195c8e28650c9cdec9611348cf077d3a3bda4305f59Brian Paul          texDestFormat == GL_COLOR_INDEX ||
1962a7243481a40dee437d4a95ac39b84e550aa98f6Brian Paul          texDestFormat == GL_DEPTH_COMPONENT);
19756671022f97cfbc199a47b3338125431e42030eeBrian Paul   ASSERT(texDestAddr);
198973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   ASSERT(srcWidth >= 0);
199973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   ASSERT(srcHeight >= 0);
200973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   ASSERT(srcDepth >= 0);
2018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstXoffset >= 0);
2028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstYoffset >= 0);
2038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstZoffset >= 0);
2048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstRowStride >= 0);
2058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstImageStride >= 0);
2068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcAddr);
2078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcPacking);
2088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2090299ad753224372c7a6147f598fdad33f576a714Brian Paul   texComponents = components_in_intformat(texDestFormat);
2108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* try common 2D texture cases first */
2121c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) {
2138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2140299ad753224372c7a6147f598fdad33f576a714Brian Paul      if (srcFormat == texDestFormat) {
2158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
2168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * GL_LUMINANCE_ALPHA, etc. texture formats.  Use memcpy().
2178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
2188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLchan *src = (const GLchan *) _mesa_image_address(
2198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcPacking, srcAddr, srcWidth, srcHeight,
2208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcFormat, srcType, 0, 0, 0);
2218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
2228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                               srcWidth, srcFormat, srcType);
2238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
224a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul         GLchan *dst = (GLchan *) texDestAddr
225a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstYoffset * (dstRowStride / sizeof(GLchan))
226a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstXoffset * texComponents;
2278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
2288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            MEMCPY(dst, src, srcHeight * widthInBytes);
2298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         else {
2318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLint i;
2328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (i = 0; i < srcHeight; i++) {
2338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               MEMCPY(dst, src, widthInBytes);
234a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               src += (srcRowStride / sizeof(GLchan));
235a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               dst += (dstRowStride / sizeof(GLchan));
2368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
2378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2400299ad753224372c7a6147f598fdad33f576a714Brian Paul      else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) {
2418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /* commonly used by Quake */
2428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLchan *src = (const GLchan *) _mesa_image_address(
2438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcPacking, srcAddr, srcWidth, srcHeight,
2448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcFormat, srcType, 0, 0, 0);
2458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
2468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                               srcWidth, srcFormat, srcType);
247a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul         GLchan *dst = (GLchan *) texDestAddr
248a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstYoffset * (dstRowStride / sizeof(GLchan))
249a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstXoffset * texComponents;
2508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint i, j;
2518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (i = 0; i < srcHeight; i++) {
2528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLchan *s = src;
2538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *d = dst;
2548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (j = 0; j < srcWidth; j++) {
2558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*red*/
2568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*green*/
2578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*blue*/
2588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               s++;          /*alpha*/
2598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
260a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            src += (srcRowStride / sizeof(GLchan));
261a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            dst += (dstRowStride / sizeof(GLchan));
2628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
2668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /*
2688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * General case solutions
2698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
2700299ad753224372c7a6147f598fdad33f576a714Brian Paul   if (texDestFormat == GL_COLOR_INDEX) {
2718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* color index texture */
2721ceda0f84fdfe07951071fdf4fa643d07f09a4d7Brian Paul      const GLenum texType = CHAN_TYPE;
2738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      GLint img, row;
27442f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul      GLchan *dest = (GLchan *) texDestAddr
27542f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul                   + dstZoffset * (dstImageStride / sizeof(GLchan))
276a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                   + dstYoffset * (dstRowStride / sizeof(GLchan))
277a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                   + dstXoffset * texComponents;
2788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      for (img = 0; img < srcDepth; img++) {
2798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLchan *destRow = dest;
2808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (row = 0; row < srcHeight; row++) {
2818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
2828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
2841c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                    srcType, src, srcPacking, transferOps);
285a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            destRow += (dstRowStride / sizeof(GLchan));
2868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         dest += dstImageStride;
2888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
290c5b995066020191982b2315fc45d05e068eee761Brian Paul   else if (texDestFormat == GL_YCBCR_MESA) {
291c5b995066020191982b2315fc45d05e068eee761Brian Paul      /* YCbCr texture */
292c5b995066020191982b2315fc45d05e068eee761Brian Paul      GLint img, row;
293c5b995066020191982b2315fc45d05e068eee761Brian Paul      GLushort *dest = (GLushort *) texDestAddr
294c5b995066020191982b2315fc45d05e068eee761Brian Paul                     + dstZoffset * (dstImageStride / sizeof(GLushort))
295c5b995066020191982b2315fc45d05e068eee761Brian Paul                     + dstYoffset * (dstRowStride / sizeof(GLushort))
296c5b995066020191982b2315fc45d05e068eee761Brian Paul                     + dstXoffset * texComponents;
297c5b995066020191982b2315fc45d05e068eee761Brian Paul      ASSERT(ctx->Extensions.MESA_ycbcr_texture);
298c5b995066020191982b2315fc45d05e068eee761Brian Paul      for (img = 0; img < srcDepth; img++) {
299c5b995066020191982b2315fc45d05e068eee761Brian Paul         GLushort *destRow = dest;
300c5b995066020191982b2315fc45d05e068eee761Brian Paul         for (row = 0; row < srcHeight; row++) {
301c5b995066020191982b2315fc45d05e068eee761Brian Paul            const GLvoid *srcRow = _mesa_image_address(srcPacking,
302c5b995066020191982b2315fc45d05e068eee761Brian Paul                                          srcAddr, srcWidth, srcHeight,
303c5b995066020191982b2315fc45d05e068eee761Brian Paul                                          srcFormat, srcType, img, row, 0);
304c5b995066020191982b2315fc45d05e068eee761Brian Paul            MEMCPY(destRow, srcRow, srcWidth * sizeof(GLushort));
305c5b995066020191982b2315fc45d05e068eee761Brian Paul            destRow += (dstRowStride / sizeof(GLushort));
306c5b995066020191982b2315fc45d05e068eee761Brian Paul         }
307c5b995066020191982b2315fc45d05e068eee761Brian Paul         dest += dstImageStride / sizeof(GLushort);
308c5b995066020191982b2315fc45d05e068eee761Brian Paul      }
309c5b995066020191982b2315fc45d05e068eee761Brian Paul   }
3100299ad753224372c7a6147f598fdad33f576a714Brian Paul   else if (texDestFormat == GL_DEPTH_COMPONENT) {
311f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      /* Depth texture (shadow maps) */
312f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      GLint img, row;
31356671022f97cfbc199a47b3338125431e42030eeBrian Paul      GLubyte *dest = (GLubyte *) texDestAddr
31456671022f97cfbc199a47b3338125431e42030eeBrian Paul                    + dstZoffset * dstImageStride
315a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                    + dstYoffset * (dstRowStride / sizeof(GLchan))
316f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                    + dstXoffset * texComponents;
317f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      for (img = 0; img < srcDepth; img++) {
31856671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLubyte *destRow = dest;
319f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         for (row = 0; row < srcHeight; row++) {
320f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
321f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
32256671022f97cfbc199a47b3338125431e42030eeBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow,
323e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul                                    srcType, src, srcPacking);
324a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            destRow += (dstRowStride / sizeof(GLchan));
325f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         }
326f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         dest += dstImageStride;
327f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      }
328f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul   }
3298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   else {
3308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* regular, color texture */
3318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
3328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
3338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
3348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
3358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * Fill texture image with convolution
3368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
3378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
3388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint convWidth = srcWidth, convHeight = srcHeight;
3398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLfloat *tmpImage, *convImage;
3408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
3418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!tmpImage) {
34208836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
3438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
3448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
3468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!convImage) {
34708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
3488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            FREE(tmpImage);
3498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
3508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
3538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLfloat *srcf;
3548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLfloat *dstf = tmpImage;
3558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *dest;
3568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* unpack and do transfer ops up to convolution */
3588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
3598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *src = _mesa_image_address(srcPacking,
3608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
3618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
3628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
3638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         srcFormat, srcType, src, srcPacking,
3641c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                         transferOps & IMAGE_PRE_CONVOLUTION_BITS,
3658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         GL_TRUE);
3668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               dstf += srcWidth * 4;
3678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* convolve */
3708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            if (dimensions == 1) {
3718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
3728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
3738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            else {
3758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
3768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
3778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          tmpImage, convImage);
3788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               else {
3808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
3818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
3828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                           tmpImage, convImage);
3838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* packing and transfer ops after convolution */
3878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            srcf = convImage;
38842f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul            dest = (GLchan *) texDestAddr
38942f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul                 + (dstZoffset + img) * (dstImageStride / sizeof(GLchan))
390a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                 + dstYoffset * (dstRowStride / sizeof(GLchan));
3918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < convHeight; row++) {
3928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_pack_float_rgba_span(ctx, convWidth,
3938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          (const GLfloat (*)[4]) srcf,
3940299ad753224372c7a6147f598fdad33f576a714Brian Paul                                          texDestFormat, CHAN_TYPE,
3958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          dest, &_mesa_native_packing,
3961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                          transferOps
3978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          & IMAGE_POST_CONVOLUTION_BITS);
3988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               srcf += convWidth * 4;
399a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               dest += (dstRowStride / sizeof(GLchan));
4008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
4018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
4028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
4038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(convImage);
4048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(tmpImage);
4058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
4068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      else {
4078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
4088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * no convolution
4098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
4108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
41142f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul         GLchan *dest = (GLchan *) texDestAddr
41242f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul                      + dstZoffset * (dstImageStride / sizeof(GLchan))
413a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                      + dstYoffset * (dstRowStride / sizeof(GLchan))
414a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                      + dstXoffset * texComponents;
4158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
4168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *destRow = dest;
4178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
4188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *srcRow = _mesa_image_address(srcPacking,
4198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
4208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
4210299ad753224372c7a6147f598fdad33f576a714Brian Paul               _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat,
4220299ad753224372c7a6147f598fdad33f576a714Brian Paul                                       destRow, srcFormat, srcType, srcRow,
4231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                       srcPacking, transferOps);
424a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               destRow += (dstRowStride / sizeof(GLchan));
4258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
42642f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul            dest += dstImageStride / sizeof(GLchan);
4278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
4288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
4298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
4308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
4318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
4328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
4338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
4348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
4357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Transfer a texture image from user space to <destAddr> applying all
4367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * needed image transfer operations and storing the result in the format
4377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * specified by <dstFormat>.  <dstFormat> may be any format from texformat.h.
4386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param
4391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dimensions - 1, 2 or 3
4401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   baseInternalFormat - base format of the internal texture format
4411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *       specified by the user.  This is very important, see below.
4421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstFormat - destination image format
4431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstAddr - destination address
4441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcWidth, srcHeight, srcDepth - size of source iamge
4451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstX/Y/Zoffset - as specified by glTexSubImage
4467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *   dstRowStride - stride between dest rows in bytes
44742f916de5cb3f4362e4682cdaa5eea00fe2de857Brian Paul *   dstImageStride - stride between dest images in bytes
4486dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *   srcFormat, srcType - incoming image format and data type
4491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcAddr - source image address
4501c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcPacking - packing params of source image
4517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *
4527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * XXX this function is a bit more complicated than it should be.  If
4537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * _mesa_convert_texsubimage[123]d could handle any dest/source formats
4547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * or if transfer_teximage() could store in any MESA_FORMAT_* format, we
4557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * could simplify things here.
4567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul */
4577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulvoid
4587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
4591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        GLenum baseInternalFormat,
4607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_texture_format *dstFormat,
4617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLvoid *dstAddr,
4627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint srcWidth, GLint srcHeight, GLint srcDepth,
4637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
4647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstRowStride, GLint dstImageStride,
4657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLenum srcFormat, GLenum srcType,
4667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const GLvoid *srcAddr,
4677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_pixelstore_attrib *srcPacking)
4687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul{
4697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
4707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
4717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   GLboolean makeTemp;
4721c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
4731c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLboolean freeSourceData = GL_FALSE;
4741c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
4751c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
476e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   assert(baseInternalFormat > 0);
47789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(baseInternalFormat == GL_LUMINANCE ||
47889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          baseInternalFormat == GL_INTENSITY ||
47989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
48089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          baseInternalFormat == GL_ALPHA ||
48189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul          baseInternalFormat == GL_RGB ||
4822a7243481a40dee437d4a95ac39b84e550aa98f6Brian Paul          baseInternalFormat == GL_RGBA ||
483c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul          baseInternalFormat == GL_YCBCR_MESA ||
484a3f137094cd965d27e1b088499dd609b81a91906Brian Paul          baseInternalFormat == GL_COLOR_INDEX ||
4852a7243481a40dee437d4a95ac39b84e550aa98f6Brian Paul          baseInternalFormat == GL_DEPTH_COMPONENT);
486e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
4871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (transferOps & IMAGE_CONVOLUTION_BIT) {
4881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
4891c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                         &postConvHeight);
4901c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
4911c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /*
4931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * Consider this scenario:  The user's source image is GL_RGB and the
4941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * requested internal format is GL_LUMINANCE.  Now suppose the device
4951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the
4961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * texture format.  In that case we still need to do an intermediate
4971c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * conversion to luminance format so that the incoming red channel gets
4981c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * replicated into the dest red, green and blue channels.  The following
4991c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * code takes care of that.
5001c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
5011c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (dstFormat->BaseFormat != baseInternalFormat) {
5021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* Allocate storage for temporary image in the baseInternalFormat */
5031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint texelSize = _mesa_components_in_format(baseInternalFormat)
5041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         * sizeof(GLchan);
5051c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth;
5061c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpRowStride = texelSize * postConvWidth;
5071c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight;
5081c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      GLvoid *tmpImage = MALLOC(bytes);
5091c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage)
5101c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         return;
5111c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage,
5121c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcWidth, srcHeight, srcDepth,
5131c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        0, 0, 0, /* x/y/zoffset */
5141c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        tmpRowStride, tmpImgStride,
5151c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
5161c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
5171c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* this is our new source image */
5181c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcWidth = postConvWidth;
5191c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcHeight = postConvHeight;
5201c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcFormat = baseInternalFormat;
5211c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcType = CHAN_TYPE;
5221c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcAddr = tmpImage;
5231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcPacking = &_mesa_native_packing;
5241c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
5251c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transferOps = 0;  /* image transfer ops were completed */
5261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
5277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /* Let the optimized tex conversion functions take a crack at the
5291c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * image conversion if the dest format is a h/w format.
5301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
5317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
5321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps) {
5337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         makeTemp = GL_TRUE;
5347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
5367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (dimensions == 1) {
5377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat,
5387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset,
5397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth,
5407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
5417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
5427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
5437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else if (dimensions == 2) {
5457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat,
5467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset, dstYoffset,
5477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth, srcHeight,
5487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstRowStridePixels,
5497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
5507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
5517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
5527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else {
5547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            assert(dimensions == 3);
5557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat,
5567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
5577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
5587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
5597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
5607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
5617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (!makeTemp) {
5637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            /* all done! */
5641c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            if (freeSourceData)
5651c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul               FREE((void *) srcAddr);
5667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            return;
5677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
5717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software texture format */
5727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      makeTemp = GL_FALSE;
5737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (makeTemp) {
5767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
5777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLenum tmpFormat;
5787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLuint tmpComps, tmpTexelSize;
5797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint tmpRowStride, tmpImageStride;
5807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLubyte *tmpImage;
5817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5821c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps & IMAGE_CONVOLUTION_BIT) {
5837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
5847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                            &postConvHeight);
5857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      tmpFormat = dstFormat->BaseFormat;
5887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpComps = _mesa_components_in_format(tmpFormat);
58936f3712e85cafef1b038189678030f6ef4f8b7e9Brian Paul      tmpTexelSize = tmpComps * sizeof(GLchan);
5907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpRowStride = postConvWidth * tmpTexelSize;
5917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
5927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
5937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                    srcDepth * tmpTexelSize);
5941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage) {
5951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         if (freeSourceData)
5961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            FREE((void *) srcAddr);
5977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         return;
5981c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      }
5997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
6017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
6027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        0, 0, 0, /* x/y/zoffset */
6037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        tmpRowStride, tmpImageStride,
6041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
6051c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
6061c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (freeSourceData)
6071c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         FREE((void *) srcAddr);
6087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* the temp image is our new source image */
6107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcWidth = postConvWidth;
6117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcHeight = postConvHeight;
6127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcFormat = tmpFormat;
6137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcType = CHAN_TYPE;
6147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcAddr = tmpImage;
6157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcPacking = &_mesa_native_packing;
6161c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
6177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
6207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(makeTemp);
6217d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      if (dimensions == 1) {
6227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
6237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat,
6247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset,
6257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth,
6267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
6277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
6287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
6297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
630b305028464f02947c0cce0476af0e35f4ed1fafaBrian Paul         (void) b;
6317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
6327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else if (dimensions == 2) {
6337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
6347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat,
6357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset, dstYoffset,
6367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth, srcHeight,
6377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstRowStridePixels,
6387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
6397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
6407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
6417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
642b305028464f02947c0cce0476af0e35f4ed1fafaBrian Paul         (void) b;
6437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
6447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
6457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
6467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat,
6477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
6487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
6497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
6507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
6517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
6527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
653b305028464f02947c0cce0476af0e35f4ed1fafaBrian Paul         (void) b;
6547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
6557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
6577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software format */
6587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(!makeTemp);
6591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr,
6607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
6617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstXoffset, dstYoffset, dstZoffset,
6627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstRowStride, dstImageStride,
6631c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
6647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6651c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
6661c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (freeSourceData)
6671c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      FREE((void *) srcAddr);  /* the temp image */
6687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul}
6697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
67189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
67289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
67389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Given a user's uncompressed texture image, this function takes care of
67489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * pixel unpacking, pixel transfer, format conversion and compression.
67589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
67689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulstatic void
67789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paultransfer_compressed_teximage(GLcontext *ctx, GLuint dimensions,
67889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                             GLsizei width, GLsizei height, GLsizei depth,
67989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                             GLenum srcFormat, GLenum srcType,
68089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                             const struct gl_pixelstore_attrib *unpacking,
68189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                             const GLvoid *source,
6822ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                             const struct gl_texture_format *dstFormat,
6832ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                             GLubyte *dest,
68489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                             GLint dstRowStride)
68589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
68689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLchan *tempImage = NULL;
68789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint srcRowStride;
68889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLenum baseFormat;
68989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
69089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(dimensions == 2);
6912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* TexelBytes is zero if and only if it's a compressed format */
6922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(dstFormat->TexelBytes == 0);
69389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
6942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   baseFormat = dstFormat->BaseFormat;
69589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
69689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (srcFormat != baseFormat || srcType != CHAN_TYPE ||
69789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       ctx->_ImageTransferState != 0 || unpacking->SwapBytes) {
69889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* need to convert user's image to texImage->Format, GLchan */
69989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint comps = components_in_intformat(baseFormat);
70089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint postConvWidth = width, postConvHeight = height;
70189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
70289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* XXX convolution untested */
70389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
70489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
70589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                            &postConvHeight);
70689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
70789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
70889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      tempImage = (GLchan*) MALLOC(width * height * comps * sizeof(GLchan));
70989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (!tempImage) {
71089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
71189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         return;
71289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
71389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_teximage(ctx, dimensions,
71489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        baseFormat,             /* dest format */
71589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        tempImage,              /* dst address */
71689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        width, height, depth,   /* src size */
71789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        0, 0, 0,                /* x/y/zoffset */
71889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        comps * width,          /* dst row stride */
71989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        comps * width * height, /* dst image stride */
72089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        srcFormat, srcType,     /* src format, type */
72189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        source, unpacking,      /* src and src packing */
72289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                        ctx->_ImageTransferState);
72389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      source = tempImage;
72489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      width = postConvWidth;
72589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      height = postConvHeight;
72689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      srcRowStride = width;
72789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
72889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
72989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (unpacking->RowLength)
73089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcRowStride = unpacking->RowLength;
73189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else
73289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcRowStride = width;
73389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
73489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
73589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   _mesa_compress_teximage(ctx, width, height, baseFormat,
73689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           (const GLchan *) source, srcRowStride,
73789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstFormat, dest, dstRowStride);
73889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (tempImage) {
73989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      FREE(tempImage);
74089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
74189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
74289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
74389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
74489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
7457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
74689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
74789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
7488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
7498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
7508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
7518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
7528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
7538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
7548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
7558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
7568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
7578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
7588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
7598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
7608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
7618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
762e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
7638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
7658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
7668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
7678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
7697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
7707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
7717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
7727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
7734f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
7744f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
7758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
77619d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
77719d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes
7788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
77989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
78089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
78189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
78289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * texelBytes;
783aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
7847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
7857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
7867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
7877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
7888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
78989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
79089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
79189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
79289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
79389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
79489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
79589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       width);
79689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 1, width, 1, 1,
79789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type, packing,
7982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   pixels, texImage->TexFormat,
79989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   (GLubyte *) texImage->Data, dstRowStride);
80089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
80189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
802f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 1,
80389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Format, /* base format */
804f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
80589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              width, 1, 1,  /* src size */
80689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, 0, 0,      /* dstX/Y/Zoffset */
807f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstRowStride */
808f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstImageStride */
809f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
81089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
811f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
81289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
81389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
81489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
81589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
81689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
8173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
82289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
82389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
8248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
8258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
8268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
8278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
8308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
8318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
8328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
8338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
8348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
8358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
8368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
838e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
8398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
8418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
8428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
8438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
8448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
8467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
8477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
8487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
8497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
8504f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
8514f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
8522c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
8532c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
8548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
85689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
85789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
85889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
85989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
860aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
8617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
8627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
8637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
8647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
8658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
86689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
86789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
86889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
86989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
87089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
87189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
87289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       width);
87389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 2, width, height, 1,
87489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type, packing,
8752ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   pixels, texImage->TexFormat,
87689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   (GLubyte *) texImage->Data, dstRowStride);
87789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
87889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
879f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 2,
88089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Format,
881f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
88289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              width, height, 1,  /* src size */
88389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, 0, 0,           /* dstX/Y/Zoffset */
88489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Width * texelBytes, /* dstRowStride */
885f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstImageStride */
886f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
88789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
888f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
88989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
89089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
89189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
89289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
89389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
8943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
90089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
90189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
9028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
9038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
9048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
9058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
9078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
9088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
9098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
9108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
9118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
9128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
9138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
9148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
915e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
9168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
9187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
9197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
9207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
9217d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
9224f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
9234f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
9242c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
925197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
9268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
92889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
92989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
93089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
93189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
932aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
9337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
9347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
9357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
9367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
9378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
93889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
93989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
94089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
94189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
94289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
94389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
94489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       width);
94589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 3, width, height, depth,
94689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type, packing,
9472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   pixels, texImage->TexFormat,
94889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   (GLubyte *) texImage->Data, dstRowStride);
94989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
95089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
951f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 3,
95289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Format,
953f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
95489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              width, height, depth, /* src size */
95589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, 0, 0,  /* dstX/Y/Zoffset */
95689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Width * texelBytes, /* dstRowStride */
957f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->Width * texImage->Height * texelBytes,
958f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
95989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
960f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
96189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
96289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
96389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
96489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
96589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
9663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
9678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
97389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
97489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
9758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
9778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
9788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
9798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
9808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
9818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
9828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
9838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
98489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
98589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
98689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       texImage->Width);
98789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLubyte *dest = _mesa_compressed_image_address(xoffset, 0, 0,
98889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->IntFormat,
98989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->Width,
990f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                          (GLubyte*) texImage->Data);
99189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 1,             /* dimensions */
99289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   width, 1, 1,        /* size to replace */
99389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type,       /* source format/type */
99489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   packing,            /* source packing */
99589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   pixels,             /* source data */
9962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   texImage->TexFormat,/* dest format */
99789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   dest, dstRowStride);
99889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
99989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
100089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_transfer_teximage(ctx, 1,
100189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Format,
100289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->TexFormat, texImage->Data,
100389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              width, 1, 1, /* src size */
100489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              xoffset, 0, 0, /* dest offsets */
100589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, /* dstRowStride */
100689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, /* dstImageStride */
100789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              format, type, pixels, packing);
100889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
10093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
10103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
10113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1012d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
1013d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
10143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
10153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
10168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
10178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
10188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
101989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
10208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
102189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
102289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
10238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
10248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
10258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
10268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
10278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
10288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
10298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
10308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
10318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
10328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
103389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
103489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
103589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       texImage->Width);
103689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
103789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->IntFormat,
103889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->Width,
1039f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                          (GLubyte*) texImage->Data);
104089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 2,             /* dimensions */
104189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   width, height, 1,   /* size to replace */
104289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type,       /* source format/type */
104389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   packing,            /* source packing */
104489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   pixels,             /* source data */
10452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   texImage->TexFormat,/* dest format */
104689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   dest, dstRowStride);
104789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
104889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
104989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_transfer_teximage(ctx, 2,
105089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Format,
105189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->TexFormat, texImage->Data,
105289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              width, height, 1, /* src size */
105389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              xoffset, yoffset, 0, /* dest offsets */
105489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              texImage->Width *texImage->TexFormat->TexelBytes,
105589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              0, /* dstImageStride */
105689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                              format, type, pixels, packing);
105789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
10583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
10593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
10603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1061d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
1062d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
10633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
10643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
10658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
10668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
10678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
10688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
10698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
107089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
10718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
10728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
10738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
10748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
10758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
10768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
10778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
10788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
10798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
10808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
108189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed) {
108289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
108389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                       texImage->Width);
108489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, zoffset,
108589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->IntFormat,
108689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                                     texImage->Width,
1087f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                          (GLubyte*) texImage->Data);
108889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      transfer_compressed_teximage(ctx, 3,              /* dimensions */
108989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   width, height, depth,/* size to replace */
109089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   format, type,       /* source format/type */
109189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   packing,            /* source packing */
109289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   pixels,             /* source data */
10932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                   texImage->TexFormat,/* dest format */
109489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                   dest, dstRowStride);
109589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
109689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else {
109789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      const GLint texelBytes = texImage->TexFormat->TexelBytes;
109889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_transfer_teximage(ctx, 3,
109989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           texImage->Format,
11001c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
11018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, depth, /* src size */
1102c5853c63d0b333b71fef0ae3b7ffa6434ce694cbBrian Paul                           xoffset, yoffset, zoffset, /* dest offsets */
110389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           texImage->Width * texelBytes,  /* dst row stride */
110438f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texImage->Height * texelBytes,
11058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
110689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
110789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
11083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
11093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1110d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
1111d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
11123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
11133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
11148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
11158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11182aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul
11192aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
11208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
11218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
11228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
11238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
11248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
11258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
11268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
11278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
11288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
11298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
113089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
11318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
11328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
11368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
11378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
11388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
11398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
11408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
11418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
11428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
11438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
11448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
11458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
114689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
114789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
11488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
114989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
115089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
115189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
115289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
115389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
115489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
115589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
115689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
115789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
115889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
115989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
116089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
11614f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
11624f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
116389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
116489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
116589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
116689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
116789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
116889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
116989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
117089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
117189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
11724039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
117389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
11748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
11758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
11798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
11808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
11818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
11828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
11838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
11848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
11858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
11868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
11878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
11888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
11898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
119089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
11918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
11928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
11948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
119589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
119689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
1197e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
1198e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
119989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
120089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
120189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
120289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
120389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
120489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
120589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
1206e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
120789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
1208e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
1209e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
1210e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
121189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
121289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
121389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
121489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
121589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
121689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
121789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
121889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
121989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
122089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
122189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
122289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
122389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
122489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
122589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
122689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
122789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
122889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
122989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
123089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
123189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
123289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
123389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
123489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
123589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
123689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
123789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
123889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
123989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
124089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
124189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                         texImage->IntFormat,
1242f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
1243f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
124489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
124589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
124689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
124789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
124889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
124989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
125089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
125189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
125289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
125389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
125489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
125589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
125689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
125789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
125889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
125989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
126089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
126189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
126289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
126389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
126489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
126589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
126689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
126789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
126889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
126989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
127089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
127189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
127289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
12733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
12743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
12753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
12769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
12779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
12783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
12793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
12809228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
12819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
12829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
12833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
12849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
12859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
12869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
1287c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
12889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
1289c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
12909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
12913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
12923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
12933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
12949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
12953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
12963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
12973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
12987c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1301f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
13029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1303f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
13049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1305f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
13069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
1307f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
13083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
13093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
13123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
13139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
13153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
13163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
13177c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1320f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
13219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1322f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
13239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1324f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
13253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
13263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
13293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
13303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
13313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_COLOR_INDEX:
13323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
13339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
13353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
13363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
13377c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
1339f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
13403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
13413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
13443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
13459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
13473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
13483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
13497c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1352f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
13539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1354f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
13553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
13563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT:
13598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
13609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
13628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
13638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
13647c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
13678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
13688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
13698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
13708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
13718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
13728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
13738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
13749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
13768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
13778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
13787c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1381f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
13829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1383f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
13849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1385f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
13869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
1387f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
13888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
13898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
13908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
13918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
13928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
13939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
13948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
13958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
13968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
13977c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
13999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1400f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
14019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1402f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
14039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1404f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
14058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
14068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
14078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
14088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
14098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
14109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
14118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
14128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
14138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
14147c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
14159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
14169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
14179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
14189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
14199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
14209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
14219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
14229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
14239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
14249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
14259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
14269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
14279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
142807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
142907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
143007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
14318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
14328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
14338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
14348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
14358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
14368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
14379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
14388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
14398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
14408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
14417c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
14429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
14439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
14449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
14459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
14469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
14479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
14489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
14499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
14509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
14519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
14529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
14539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
14549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
14559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
14569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
14579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
14589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
145907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
146007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
146107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
146207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
14638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
14648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
14658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
14668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
14678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
14688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
14699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
14708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
14718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
14728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
14737c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
14749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
14759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
14769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
14779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
14789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
14799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
14809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
14819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
14829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
14839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
14849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
14859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
14869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
14879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
14889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
14899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
14909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
149107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
149207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
149307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
149407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
14958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
14968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
14978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
14988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
14998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
15008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
15019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
15028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
15038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
15048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
15057c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
15069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
15079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
15089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
15099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
15109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
15118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
15128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
15138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
15148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
15158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
15169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
15178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
15188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
15198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
15207c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
15219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
15229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
15239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
15249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
15259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
15269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
15279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
15289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
15299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
15309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
15319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
15329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
15339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
153407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
153507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
153607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
15378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
15388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
15398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
15408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
15418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
15428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
15438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
15448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
15458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
15469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
15478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
15488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
15498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
15507c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
15519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
15529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
15538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
15548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
15558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
15563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
15573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
15583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
15593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
15603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
15639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
15649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
15659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
15669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
15673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
15693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
15703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
15713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
15723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
15733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
15743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
15753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
15763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
15783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
15793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
15803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
15829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
15839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
15843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
15863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
15873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
15883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
15893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
15903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
15913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
15923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
15933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
15943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
15973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
15983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
15993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
16003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
16013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
16029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
16039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
16049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
16053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
16063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
16073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
16083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
16099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint row, colStride;
16109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
16119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   colStride = (srcWidth == dstWidth) ? 1 : 2;
16123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
16143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
16153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
16163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
16173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
16183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
16193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
16203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
16229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
16239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
16243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
16253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
16263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
16273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
16283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
16303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
16313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
16323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
16333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
16343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
16353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
16363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
16373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
16383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
16393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
16403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
16413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
16423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
16433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
16449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
16459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
16469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
16479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
16483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
16499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
16503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
16513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
16529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
16533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
16543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
16559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
16569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
16579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
16589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
16599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
16609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
16619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
16629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
16639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
16649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
16659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
16669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
16679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
16689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
16699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
16709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
16719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
16729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
16739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
16749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
16759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
16763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
16783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
16793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
16823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
16833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
16843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
16853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
16863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
16873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
16889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
16899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
16909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
16919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
16929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
16939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
16949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
16953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
16969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
16979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
16989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
16993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17005c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
17015c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
17029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
17039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
17049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
17059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
17069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
17079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
17089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
17093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
17103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
17113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
17139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
17149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
17169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
17173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
17199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
17203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
17229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
17233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
17259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
17269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
17279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
17289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
17299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
17309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
17313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
17334e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
17349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
17359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
17369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
17389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
17399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
17409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
17419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
17429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
17439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
17449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
17459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
17469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
17479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
17489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
17509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
17519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
17529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
17539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
17549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
17559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
17579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
17589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
17599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
17609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
17619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
17629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
17639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
17649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
17659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
17669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
17679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
17689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
17699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
17709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
17719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
17723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
17733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
17743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
17763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
17779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
17799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
17809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
17819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
17829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
17839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
17849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
17859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
17869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
17879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
17889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
17899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
17909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
17919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
17929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
17939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
17949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
17959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
17969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
17979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
17989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
17999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
18019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
18039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
18059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
18069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
18089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
18109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
18129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
18139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
18159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
18179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
18199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
18209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
18219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
18229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
18239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
18249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
18259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
18269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
18279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
18289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
18309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
18319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
18329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
18339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
18359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
18379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
18399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
18409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
18429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
18449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
18469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
18479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
18489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
18499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
18509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
18519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
18529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
18539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
18549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
18559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
18569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
18573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
18583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
18593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
18603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
18613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
18623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
18633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
18643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
18653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
1866d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
18673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
18683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
18693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
18702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
18712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
1872b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
1873b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
1874ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
18753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
18763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
187718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
18782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
18793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
1880ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
1881ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
18823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
18832ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
18842ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
18852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
1886d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
1887d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
18882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
18892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
18902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
18912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
18922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (srcImage->Format == GL_RGB) {
18932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
18942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
18952ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
18962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else if (srcImage->Format == GL_RGBA) {
18972ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
18982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
18992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
19002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
19012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps");
19022ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
19032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
19042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
19052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
19062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE)
19072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
19082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
1909f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      srcData = (GLubyte *) MALLOC(size);
19102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
19112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
19122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
19132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
1914f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      dstData = (GLubyte *) MALLOC(size / 2);  /* 1/4 would probably be OK */
19152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
19162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
19172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         FREE((void *) srcData);
19182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
19192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
19202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
19212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
19222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
19232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
1924d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
19252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
19264f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
19272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
192889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
192989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
193089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
19312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
19322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
19332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
19342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
193589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
19368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
1937cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
19389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
19393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
19403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
19413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
19423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
19433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
19443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
194589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
19463ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
19473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
19483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
19493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
19503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
19513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
19523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
19533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
19543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
19553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
19563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
19583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
19593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
19613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
19623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
19643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
19653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
19673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
19683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
19703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
19713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
19733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
19743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
19753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
19763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
197789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
197889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE((void *) srcData);
197989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE(dstData);
198089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
19813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
19823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
19833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
1984d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
1985a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
1986d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
1987a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
1988a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
1989d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
19903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
1991d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
1992d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
1993d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul         MESA_PBUFFER_FREE(dstImage->Data);
1994d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
1995d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
1996e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
199789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                 dstDepth, border, srcImage->IntFormat);
1998d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
1999d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
20004f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
20014f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
2002d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
20034f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
20044f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
2005d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
200689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
200789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
200889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
200989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
201089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
201189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize);
201289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
201389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
201489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
201589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
20162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
201789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
201889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
201989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
202089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
202189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
202289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
202389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
202489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                             * bytesPerTexel);
202589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
202689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
202789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
202889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
202989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
203089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
2031d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
2032d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
2033d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
2034d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
2035d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
2036d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
203789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
20382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
203989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
204089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
204189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
204289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
204389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
204489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
204589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
204689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
204789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
204889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
20492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
205089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
205189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
205289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
205389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
20542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
205589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
205689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
205789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
205889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
205989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
206089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
206189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
206289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
206389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
2064d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
206589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
206689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
206789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
20682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
20692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
20702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
20712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                                          dstWidth);
20722ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
20732ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_compress_teximage(ctx,
20742ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                 dstWidth, dstHeight, /* size */
20752ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                 srcFormat,           /* source format */
2076612cf792dbcb8b69819751c62f8df5fe47aae9b4Brian Paul                (const GLchan *) dstData,             /* source buffer */
20772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                 dstWidth,            /* source row stride */
20782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                 dstImage->TexFormat, /* dest format */
2079f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                      (GLubyte*) dstImage->Data,      /* dest buffer */
20802ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                 dstRowStride );      /* dest row stride */
208189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
208289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
208389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
208489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
208589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
208689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
208789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2088d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
20893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
2090