texstore.c revision 8bd06931018d5662b92f1cfeee2abaf352d0044c
18bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul/* $Id: texstore.c,v 1.26 2001/05/22 21:49:03 brianp Exp $ */
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
38e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
58e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Version:  3.5
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
32e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "mem.h"
38371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul#include "texutil.h"
428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Given an internal texture format enum or 1, 2, 3, 4 return the
468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * number of components for the format.  Return -1 if invalid enum.
496b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes *
506b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes * GH: Do we really need this?  We have the number of bytes per texel
516b406bf09dc18f4d84ccb636d043c990a30da4e1Gareth Hughes * in the texture format structures, so why don't we just use that?
528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulstatic GLint
548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulcomponents_in_intformat( GLint format )
558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   switch (format) {
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA:
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA4:
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA8:
608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA12:
618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_ALPHA16:
628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 1:
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE:
658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE4:
668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE8:
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12:
688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE16:
698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 2:
718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE_ALPHA:
728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE4_ALPHA4:
738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE6_ALPHA2:
748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE8_ALPHA8:
758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12_ALPHA4:
768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE12_ALPHA12:
778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_LUMINANCE16_ALPHA16:
788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 2;
798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY:
808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY4:
818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY8:
828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY12:
838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_INTENSITY16:
848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 3:
868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB:
878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_R3_G3_B2:
888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB4:
898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB5:
908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB8:
918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB10:
928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB12:
938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB16:
948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 3;
958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case 4:
968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA:
978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA2:
988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA4:
998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB5_A1:
1008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA8:
1018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGB10_A2:
1028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA12:
1038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_RGBA16:
1048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 4;
1058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX:
1068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX1_EXT:
1078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX2_EXT:
1088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX4_EXT:
1098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX8_EXT:
1108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX12_EXT:
1118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      case GL_COLOR_INDEX16_EXT:
1128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return 1;
113f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT:
114f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT16_SGIX:
115f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT24_SGIX:
116f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      case GL_DEPTH_COMPONENT32_SGIX:
117f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         return 1;
1188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      default:
1198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return -1;  /* error */
1208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
1218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
1228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
1258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This function is used to transfer the user's image data into a texture
1268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * image buffer.  We handle both full texture images and subtexture images.
1278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * We also take care of all image transfer operations here, including
1288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convolution, scale/bias, colortables, etc.
1298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
1308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The destination texel channel type is always GLchan.
1318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
1328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * A hardware driver may use this as a helper routine to unpack and
1338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * apply pixel transfer ops into a temporary image buffer.  Then,
1348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * convert the temporary image into the special hardware format.
1358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
1368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Input:
1378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   dimensions - 1, 2, or 3
1388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
1398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *               GL_RGB or GL_RGBA
14056671022f97cfbc199a47b3338125431e42030eeBrian Paul *   texDestAddr - destination image address
1418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
1428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   dstXoffset, dstYoffset, dstZoffset - position to store the image within
1438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *      the destination 3D texture
14456671022f97cfbc199a47b3338125431e42030eeBrian Paul *   dstRowStride, dstImageStride - dest image strides in bytes
1458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
1468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
1478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   srcPacking - describes packing of incoming image.
1481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   transferOps - mask of pixel transfer operations
1498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
1507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulstatic void
1517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paultransfer_teximage(GLcontext *ctx, GLuint dimensions,
1527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLenum texDestFormat, GLvoid *texDestAddr,
1537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint srcWidth, GLint srcHeight, GLint srcDepth,
1547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
1557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLint dstRowStride, GLint dstImageStride,
1567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  GLenum srcFormat, GLenum srcType,
1577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                  const GLvoid *srcAddr,
1581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                  const struct gl_pixelstore_attrib *srcPacking,
1591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                  GLuint transferOps)
1608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
1618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint texComponents;
1628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(ctx);
1648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dimensions >= 1 && dimensions <= 3);
16556671022f97cfbc199a47b3338125431e42030eeBrian Paul   ASSERT(texDestAddr);
1668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcWidth >= 1);
1678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcHeight >= 1);
1688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcDepth >= 1);
1698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstXoffset >= 0);
1708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstYoffset >= 0);
1718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstZoffset >= 0);
1728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstRowStride >= 0);
1738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(dstImageStride >= 0);
1748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcAddr);
1758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   ASSERT(srcPacking);
1768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1770299ad753224372c7a6147f598fdad33f576a714Brian Paul   texComponents = components_in_intformat(texDestFormat);
1788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* try common 2D texture cases first */
1801c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) {
1818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1820299ad753224372c7a6147f598fdad33f576a714Brian Paul      if (srcFormat == texDestFormat) {
1838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
1848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * GL_LUMINANCE_ALPHA, etc. texture formats.  Use memcpy().
1858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
1868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLchan *src = (const GLchan *) _mesa_image_address(
1878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcPacking, srcAddr, srcWidth, srcHeight,
1888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcFormat, srcType, 0, 0, 0);
1898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                               srcWidth, srcFormat, srcType);
1918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
19256671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride
1938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                      + dstXoffset * texComponents;
1948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
1958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            MEMCPY(dst, src, srcHeight * widthInBytes);
1968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
1978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         else {
1988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLint i;
1998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (i = 0; i < srcHeight; i++) {
2008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               MEMCPY(dst, src, widthInBytes);
2018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               src += srcRowStride;
2028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               dst += dstRowStride;
2038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
2048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2070299ad753224372c7a6147f598fdad33f576a714Brian Paul      else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) {
2088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /* commonly used by Quake */
2098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLchan *src = (const GLchan *) _mesa_image_address(
2108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcPacking, srcAddr, srcWidth, srcHeight,
2118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcFormat, srcType, 0, 0, 0);
2128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
2138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                               srcWidth, srcFormat, srcType);
21456671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride
2158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                      + dstXoffset * texComponents;
2168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint i, j;
2178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (i = 0; i < srcHeight; i++) {
2188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLchan *s = src;
2198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *d = dst;
2208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (j = 0; j < srcWidth; j++) {
2218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*red*/
2228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*green*/
2238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*blue*/
2248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               s++;          /*alpha*/
2258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
2268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            src += srcRowStride;
2278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            dst += dstRowStride;
2288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
2328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /*
2348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * General case solutions
2358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
2360299ad753224372c7a6147f598fdad33f576a714Brian Paul   if (texDestFormat == GL_COLOR_INDEX) {
2378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* color index texture */
2381ceda0f84fdfe07951071fdf4fa643d07f09a4d7Brian Paul      const GLenum texType = CHAN_TYPE;
2398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      GLint img, row;
24056671022f97cfbc199a47b3338125431e42030eeBrian Paul      GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
2418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                    + dstYoffset * dstRowStride
2428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                    + dstXoffset * texComponents;
2438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      for (img = 0; img < srcDepth; img++) {
2448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLchan *destRow = dest;
2458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (row = 0; row < srcHeight; row++) {
2468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
2478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
2491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                    srcType, src, srcPacking, transferOps);
2508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            destRow += dstRowStride;
2518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         dest += dstImageStride;
2538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
2550299ad753224372c7a6147f598fdad33f576a714Brian Paul   else if (texDestFormat == GL_DEPTH_COMPONENT) {
256f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      /* Depth texture (shadow maps) */
257f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      GLint img, row;
25856671022f97cfbc199a47b3338125431e42030eeBrian Paul      GLubyte *dest = (GLubyte *) texDestAddr
25956671022f97cfbc199a47b3338125431e42030eeBrian Paul                    + dstZoffset * dstImageStride
260f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                    + dstYoffset * dstRowStride
261f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                    + dstXoffset * texComponents;
262f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      for (img = 0; img < srcDepth; img++) {
26356671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLubyte *destRow = dest;
264f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         for (row = 0; row < srcHeight; row++) {
265f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
266f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
26756671022f97cfbc199a47b3338125431e42030eeBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow,
268e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul                                    srcType, src, srcPacking);
269f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul            destRow += dstRowStride;
270f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         }
271f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         dest += dstImageStride;
272f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      }
273f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul   }
2748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   else {
2758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* regular, color texture */
2768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
2778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
2788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
2798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
2808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * Fill texture image with convolution
2818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
2828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
2838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint convWidth = srcWidth, convHeight = srcHeight;
2848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLfloat *tmpImage, *convImage;
2858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
2868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!tmpImage) {
28708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
2888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
2898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
2918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!convImage) {
29208836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
2938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            FREE(tmpImage);
2948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
2958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
2988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLfloat *srcf;
2998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLfloat *dstf = tmpImage;
3008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *dest;
3018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* unpack and do transfer ops up to convolution */
3038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
3048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *src = _mesa_image_address(srcPacking,
3058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
3068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
3078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
3088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         srcFormat, srcType, src, srcPacking,
3091c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                         transferOps & IMAGE_PRE_CONVOLUTION_BITS,
3108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         GL_TRUE);
3118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               dstf += srcWidth * 4;
3128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* convolve */
3158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            if (dimensions == 1) {
3168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
3178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
3188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            else {
3208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
3218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
3228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          tmpImage, convImage);
3238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               else {
3258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
3268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
3278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                           tmpImage, convImage);
3288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* packing and transfer ops after convolution */
3328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            srcf = convImage;
33356671022f97cfbc199a47b3338125431e42030eeBrian Paul            dest = (GLchan *) texDestAddr + (dstZoffset + img) * dstImageStride
3348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                 + dstYoffset * dstRowStride;
3358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < convHeight; row++) {
3368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_pack_float_rgba_span(ctx, convWidth,
3378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          (const GLfloat (*)[4]) srcf,
3380299ad753224372c7a6147f598fdad33f576a714Brian Paul                                          texDestFormat, CHAN_TYPE,
3398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          dest, &_mesa_native_packing,
3401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                          transferOps
3418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          & IMAGE_POST_CONVOLUTION_BITS);
3428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               srcf += convWidth * 4;
3438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               dest += dstRowStride;
3448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(convImage);
3488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(tmpImage);
3498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
3508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      else {
3518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
3528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * no convolution
3538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
3548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
35556671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
3568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       + dstYoffset * dstRowStride
3578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       + dstXoffset * texComponents;
3588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
3598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *destRow = dest;
3608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
3618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *srcRow = _mesa_image_address(srcPacking,
3628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
3638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
3640299ad753224372c7a6147f598fdad33f576a714Brian Paul               _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat,
3650299ad753224372c7a6147f598fdad33f576a714Brian Paul                                       destRow, srcFormat, srcType, srcRow,
3661c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                       srcPacking, transferOps);
3678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               destRow += dstRowStride;
3688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            dest += dstImageStride;
3708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
3728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
3738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
3748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
3787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Transfer a texture image from user space to <destAddr> applying all
3797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * needed image transfer operations and storing the result in the format
3807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * specified by <dstFormat>.  <dstFormat> may be any format from texformat.h.
3817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Input:
3821c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dimensions - 1, 2 or 3
3831c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   baseInternalFormat - base format of the internal texture format
3841c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *       specified by the user.  This is very important, see below.
3851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstFormat - destination image format
3861c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstAddr - destination address
3871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcWidth, srcHeight, srcDepth - size of source iamge
3881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstX/Y/Zoffset - as specified by glTexSubImage
3897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *   dstRowStride - stride between dest rows in bytes
3907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *   dstImagetride - stride between dest images in bytes
3911c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcFormat, srcType - incoming image format and datatype
3921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcAddr - source image address
3931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcPacking - packing params of source image
3947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *
3957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * XXX this function is a bit more complicated than it should be.  If
3967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * _mesa_convert_texsubimage[123]d could handle any dest/source formats
3977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * or if transfer_teximage() could store in any MESA_FORMAT_* format, we
3987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * could simplify things here.
3997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul */
4007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulvoid
4017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
4021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        GLenum baseInternalFormat,
4037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_texture_format *dstFormat,
4047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLvoid *dstAddr,
4057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint srcWidth, GLint srcHeight, GLint srcDepth,
4067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
4077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstRowStride, GLint dstImageStride,
4087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLenum srcFormat, GLenum srcType,
4097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const GLvoid *srcAddr,
4107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_pixelstore_attrib *srcPacking)
4117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul{
4127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
4137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
4147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   GLboolean makeTemp;
4151c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
4161c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLboolean freeSourceData = GL_FALSE;
4171c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
4181c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4191c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (transferOps & IMAGE_CONVOLUTION_BIT) {
4201c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
4211c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                         &postConvHeight);
4221c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
4231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4241c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /*
4251c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * Consider this scenario:  The user's source image is GL_RGB and the
4261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * requested internal format is GL_LUMINANCE.  Now suppose the device
4271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the
4281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * texture format.  In that case we still need to do an intermediate
4291c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * conversion to luminance format so that the incoming red channel gets
4301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * replicated into the dest red, green and blue channels.  The following
4311c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * code takes care of that.
4321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
4331c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (dstFormat->BaseFormat != baseInternalFormat) {
4341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* Allocate storage for temporary image in the baseInternalFormat */
4351c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint texelSize = _mesa_components_in_format(baseInternalFormat)
4361c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         * sizeof(GLchan);
4371c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth;
4381c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpRowStride = texelSize * postConvWidth;
4391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight;
4401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      GLvoid *tmpImage = MALLOC(bytes);
4411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage)
4421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         return;
4431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage,
4441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcWidth, srcHeight, srcDepth,
4451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        0, 0, 0, /* x/y/zoffset */
4461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        tmpRowStride, tmpImgStride,
4471c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
4481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* this is our new source image */
4501c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcWidth = postConvWidth;
4511c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcHeight = postConvHeight;
4521c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcFormat = baseInternalFormat;
4531c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcType = CHAN_TYPE;
4541c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcAddr = tmpImage;
4551c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcPacking = &_mesa_native_packing;
4561c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
4571c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transferOps = 0;  /* image transfer ops were completed */
4581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
4597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
4601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /* Let the optimized tex conversion functions take a crack at the
4611c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * image conversion if the dest format is a h/w format.
4621c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
4637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
4641c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps) {
4657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         makeTemp = GL_TRUE;
4667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
4677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
4687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (dimensions == 1) {
4697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat,
4707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset,
4717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth,
4727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
4737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
4747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
4757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else if (dimensions == 2) {
4777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat,
4787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset, dstYoffset,
4797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth, srcHeight,
4807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstRowStridePixels,
4817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
4827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
4837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
4847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else {
4867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            assert(dimensions == 3);
4877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat,
4887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
4897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
4907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
4917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
4927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
4937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (!makeTemp) {
4957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            /* all done! */
4961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            if (freeSourceData)
4971c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul               FREE((void *) srcAddr);
4987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            return;
4997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
5037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software texture format */
5047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      makeTemp = GL_FALSE;
5057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (makeTemp) {
5087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
5097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLenum tmpFormat;
5107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLuint tmpComps, tmpTexelSize;
5117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint tmpRowStride, tmpImageStride;
5127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLubyte *tmpImage;
5137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5141c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps & IMAGE_CONVOLUTION_BIT) {
5157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
5167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                            &postConvHeight);
5177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5191c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      tmpFormat = dstFormat->BaseFormat;
5207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpComps = _mesa_components_in_format(tmpFormat);
52136f3712e85cafef1b038189678030f6ef4f8b7e9Brian Paul      tmpTexelSize = tmpComps * sizeof(GLchan);
5227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpRowStride = postConvWidth * tmpTexelSize;
5237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
5247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
5257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                    srcDepth * tmpTexelSize);
5261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage) {
5271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         if (freeSourceData)
5281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            FREE((void *) srcAddr);
5297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         return;
5301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      }
5317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
5337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
5347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        0, 0, 0, /* x/y/zoffset */
5357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        tmpRowStride, tmpImageStride,
5361c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
5371c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
5381c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (freeSourceData)
5391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         FREE((void *) srcAddr);
5407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* the temp image is our new source image */
5427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcWidth = postConvWidth;
5437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcHeight = postConvHeight;
5447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcFormat = tmpFormat;
5457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcType = CHAN_TYPE;
5467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcAddr = tmpImage;
5477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcPacking = &_mesa_native_packing;
5481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
5497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
5527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(makeTemp);
5537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      if (dimensions == 1) {
5547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat,
5567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset,
5577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth,
5587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
5597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
5607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
5617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else if (dimensions == 2) {
5647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat,
5667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset, dstYoffset,
5677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth, srcHeight,
5687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstRowStridePixels,
5697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
5707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
5717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
5727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
5757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat,
5777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
5787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
5797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
5807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
5817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
5827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
5867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software format */
5877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(!makeTemp);
5881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr,
5897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
5907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstXoffset, dstYoffset, dstZoffset,
5917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstRowStride, dstImageStride,
5921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
5937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
5951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (freeSourceData)
5961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      FREE((void *) srcAddr);  /* the temp image */
5977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul}
5987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
6018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage1D().
6028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
6038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
6048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
6058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
6068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
6078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
6088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
6098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
6108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
6118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
6128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
6138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
6148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
6158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
6168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
61719d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes   GLint texelBytes;
6188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
6208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
6218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
6228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
6247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
6257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
6267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
6277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
6288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
62919d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
63019d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes
6318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
6327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->Data = MALLOC(postConvWidth * texelBytes);
6337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
6347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
6357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
6367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
6391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 1, _mesa_base_tex_format(ctx, internalFormat),
6401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
6418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, 1, 1, 0, 0, 0,
6428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstRowStride */
6438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
6448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
6453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
6463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
6473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
6483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
6493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
6503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
6518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
6528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
6558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage2D().
6568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
6578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
6588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
6598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
6608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
6618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
6628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
6638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
6648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
6658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
6668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
6678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
6688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
6698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
6708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
6712c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   GLint texelBytes;
6728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
6748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
6758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
6768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
6778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
6797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
6807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
6817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
6827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
6833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
6842c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
6852c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
6868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
6887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->Data = MALLOC(postConvWidth * postConvHeight * texelBytes);
6897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
6907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
6917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
6927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
6951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 2, _mesa_base_tex_format(ctx, internalFormat),
6961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
6978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, 1, 0, 0, 0,
6982c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes                           texImage->Width * texelBytes,
6998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
7008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
7013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
7023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
7033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
7043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
7053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
7063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
7078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
7088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
7128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage3D().
7138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
7148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
7158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
7168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
7178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
7188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
7198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
7208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
7218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
7228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
7238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
7248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
7258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
7268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
7272c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   GLint texelBytes;
7288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
7307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
7317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
7327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
7337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
7342c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
735197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
7368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
7387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->Data = MALLOC(width * height * depth * texelBytes);
7397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
7407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
7417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
7427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
7438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
7451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 3, _mesa_base_tex_format(ctx, internalFormat),
7461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
7478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, depth, 0, 0, 0,
7482c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes                           texImage->Width * texelBytes,
7492c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes                           texImage->Width * texImage->Height * texelBytes,
7508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
7513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
7523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
7533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
7543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
7553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
7563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
7578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
7588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
7638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage1D().
7648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
7658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
7668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
7678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
7688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
7698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
7708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
7718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
7728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
7731c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 1,
7741c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
7751c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
7768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, 1, 1, /* src size */
7778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, 0, 0, /* dest offsets */
7788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstRowStride */
7798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
7808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
7813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
7823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
7833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
7843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
7853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
7863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
7878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
7888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
7918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage2D().
7928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
7938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
7948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
7958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
7968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
7978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
7988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
7998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
8008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
8018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8021c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 2,
8031c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
8041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
8058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, 1, /* src size */
8068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, yoffset, 0, /* dest offsets */
80738f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texImage->TexFormat->TexelBytes,
8088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
8098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
8103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
8113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
8123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
8133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
8143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
8153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
8218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
8248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
8258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
8268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
8278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
8288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
8298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
8308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
83138f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes   const GLint texelBytes = texImage->TexFormat->TexelBytes;
8321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 3,
8331c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
8341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
8358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, depth, /* src size */
8368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, yoffset, xoffset, /* dest offsets */
83738f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texelBytes,
83838f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texImage->Height * texelBytes,
8398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
8403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
8413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
8423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
8433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
8443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8492aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul
8502aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
8518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
8528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
8558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
8568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
8578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
8588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
8598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
8608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
8628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
8638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
8648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
8708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
8738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
8748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
8758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
8768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
8778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
8788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
8808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
8818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
8828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
8888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
8918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
8928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
8938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
8948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
8958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
8968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
8978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
8998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
9008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
9018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
9068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the fallback for Driver.TestProxyTexImage().
9078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9088e39ad2cd67d49be40ff0822f3269affdf83d601Brian PaulGLboolean
9098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
9108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint internalFormat, GLenum format, GLenum type,
9118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth, GLint border)
9128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
9138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_unit *texUnit;
9148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_object *texObj;
9158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_image *texImage;
9168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   (void) format;
9188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   (void) type;
9198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
9218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texObj = _mesa_select_tex_object(ctx, texUnit, target);
9228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
9238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* We always pass.
9258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The core Mesa code will have already tested the image size, etc.
9268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * Drivers may have more stringent texture limits to enforce and will
9278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * have to override this function.
9288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
9297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
9307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
9317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
9327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
9337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
9348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   return GL_TRUE;
9368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
9383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
9393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
9403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
9413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
9423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
9433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * to the same data.  The source rows are to be twice as long as the
9443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * dest row.
9453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
9463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
9473893e638e6521b9c070e01c0b31d22754ff97a88Brian Pauldo_row(const struct gl_texture_format *format, GLint dstWidth,
9483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB, GLvoid *dstRow)
9493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
9503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
9513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
9523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
9533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLuint i, j;
9543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
9553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
9563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
9573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
9583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
9593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
9603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
9613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
9623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
9633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][2] + rowB[j+1][2]) >> 2;
9643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][3] = (rowA[j][3] + rowA[j+1][3] +
9653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][3] + rowB[j+1][3]) >> 2;
9663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
9673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
9683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
9693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
9703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
9713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLuint i, j;
9723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
9733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
9743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
9753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
9763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
9773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
9783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
9793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
9803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
9813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][2] + rowB[j+1][2]) >> 2;
9823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
9833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
9843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
9853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
9863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
9873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
9883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_COLOR_INDEX:
9893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
9903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLuint i, j;
9913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
9923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
9933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
9943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
9953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i] = (rowA[j] + rowA[j+1] + rowB[j] + rowB[j+1]) >> 2;
9963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
9973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
9983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
9993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
10003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
10013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLuint i, j;
10023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
10033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
10043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
10053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
10073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
10083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
10093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
10103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
10113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
10123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
10133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT:
10148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
10168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
10178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
10188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
10198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (rowA[j] + rowA[j+1] + rowB[j] + rowB[j+1]) * 0.25F;
10218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
10228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
10238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
10248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
10258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
10268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
10278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
10298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
10308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
10318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
10328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
10348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
10358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
10368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
10378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
10388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][2] + rowB[j+1][2]) >> 2;
10398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][3] = (rowA[j][3] + rowA[j+1][3] +
10408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][3] + rowB[j+1][3]) >> 2;
10418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
10428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
10438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
10448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
10458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
10478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
10488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
10498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
10508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
10528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
10538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
10548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
10558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
10568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][2] + rowB[j+1][2]) >> 2;
10578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
10588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
10598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
10608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
10618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
10638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
10648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
10658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
10668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr0 = rowA[j]   & 0x1f;
10688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr1 = rowA[j+1] & 0x1f;
10698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr0 = rowB[j]   & 0x1f;
10708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr1 = rowB[j+1] & 0x1f;
10718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg0 = (rowA[j]   >> 5) & 0x3f;
10728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg1 = (rowA[j+1] >> 5) & 0x3f;
10738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg0 = (rowB[j]   >> 5) & 0x3f;
10748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg1 = (rowB[j+1] >> 5) & 0x3f;
10758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb0 = (rowA[j]   >> 11) & 0x1f;
10768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb1 = (rowA[j+1] >> 11) & 0x1f;
10778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb0 = (rowB[j]   >> 11) & 0x1f;
10788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb1 = (rowB[j+1] >> 11) & 0x1f;
10798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
10808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
10818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
10828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
10838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
10848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
10858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
10868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
10878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
10898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
10908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
10918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
10928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
10938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr0 = rowA[j]   & 0xf;
10948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr1 = rowA[j+1] & 0xf;
10958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr0 = rowB[j]   & 0xf;
10968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr1 = rowB[j+1] & 0xf;
10978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg0 = (rowA[j]   >> 4) & 0xf;
10988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg1 = (rowA[j+1] >> 4) & 0xf;
10998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg0 = (rowB[j]   >> 4) & 0xf;
11008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg1 = (rowB[j+1] >> 4) & 0xf;
11018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb0 = (rowA[j]   >> 8) & 0xf;
11028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb1 = (rowA[j+1] >> 8) & 0xf;
11038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb0 = (rowB[j]   >> 8) & 0xf;
11048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb1 = (rowB[j+1] >> 8) & 0xf;
11058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAa0 = (rowA[j]   >> 12) & 0xf;
11068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAa1 = (rowA[j+1] >> 12) & 0xf;
11078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBa0 = (rowB[j]   >> 12) & 0xf;
11088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBa1 = (rowB[j+1] >> 12) & 0xf;
11098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
11108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
11118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
11128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
11138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
11148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
11188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
11208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
11218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
11228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
11238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
11248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr0 = rowA[j]   & 0x1f;
11258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr1 = rowA[j+1] & 0x1f;
11268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr0 = rowB[j]   & 0x1f;
11278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr1 = rowB[j+1] & 0xf;
11288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg0 = (rowA[j]   >> 5) & 0x1f;
11298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg1 = (rowA[j+1] >> 5) & 0x1f;
11308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg0 = (rowB[j]   >> 5) & 0x1f;
11318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg1 = (rowB[j+1] >> 5) & 0x1f;
11328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb0 = (rowA[j]   >> 10) & 0x1f;
11338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb1 = (rowA[j+1] >> 10) & 0x1f;
11348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb0 = (rowB[j]   >> 10) & 0x1f;
11358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb1 = (rowB[j+1] >> 10) & 0x1f;
11368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAa0 = (rowA[j]   >> 15) & 0x1;
11378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAa1 = (rowA[j+1] >> 15) & 0x1;
11388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBa0 = (rowB[j]   >> 15) & 0x1;
11398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBa1 = (rowB[j+1] >> 15) & 0x1;
11408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
11418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
11428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
11438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
11448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
11458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
11498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
11518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
11528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
11538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
11548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
11558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
11568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][0] + rowB[j+1][0]) >> 2;
11578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
11588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul                         rowB[j][1] + rowB[j+1][1]) >> 2;
11598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
11638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
11658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
11668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
11678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
11688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
11698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr0 = rowA[j]   & 0x3;
11708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAr1 = rowA[j+1] & 0x3;
11718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr0 = rowB[j]   & 0x3;
11728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBr1 = rowB[j+1] & 0x3;
11738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg0 = (rowA[j]   >> 2) & 0x7;
11748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAg1 = (rowA[j+1] >> 2) & 0x7;
11758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg0 = (rowB[j]   >> 2) & 0x7;
11768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBg1 = (rowB[j+1] >> 2) & 0x7;
11778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb0 = (rowA[j]   >> 5) & 0x7;
11788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowAb1 = (rowA[j+1] >> 5) & 0x7;
11798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb0 = (rowB[j]   >> 5) & 0x7;
11808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint rowBb1 = (rowB[j+1] >> 5) & 0x7;
11818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
11828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
11838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
11848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
11858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
11898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
11908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
11918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
11928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLuint i, j;
11948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
11958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
11968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
11978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         for (i = j = 0; i < dstWidth; i++, j+=2) {
11988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (rowA[j] + rowA[j+1] + rowB[j] + rowB[j+1]) >> 2;
11998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
12033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
12043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
12053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
12063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
12113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
12123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
12133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
12143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
12153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
12163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
12173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
12183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
12203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
12213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
12223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
12243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   do_row(format, dstWidth - 2 * border, src, src, dst);
12253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
12273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
12283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
12293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
12303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
12313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
12323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
12333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
12343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
12353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
12383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
12393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
12403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
12413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
12423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
12433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
12443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
12453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
12463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
12473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint row;
12483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
12503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
12513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
12523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
12533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
12543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
12553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
12563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   for (row = 0; row < dstHeight - 2 * border; row++) {
12583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      do_row(format, dstWidth - 2 * border, srcA, srcB, dst);
12593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
12603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
12613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
12623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
12633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
12653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
12663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
12673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
12683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
12693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
12703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
12713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
12723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
12733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
12743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
12753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
12763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
12773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
12783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
12793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      do_row(format, dstWidth - 2 * border,
12803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + bpt, srcPtr + bpt, dstPtr + bpt);
12813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
12823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      do_row(format, dstWidth - 2 * border,
12833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
12843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
12853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
12863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
12873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      for (row = 0; row < dstHeight - 2 * border; row += 2) {
12883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLubyte tempPixel[32];
12893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLint srcOffset;
12903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         srcOffset = (srcWidth * (row * 2 + 1)) * bpt;
12913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
12923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         srcOffset = (srcWidth * (row * 2 + 2)) * bpt;
12933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         MEMCPY(tempPixel + bpt, srcPtr + srcOffset, bpt);
12943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         do_row(format, 1, tempPixel, tempPixel,
12953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                dstPtr + (dstWidth * row + 1) * bpt);
12963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         srcOffset = (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt;
12973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
12983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         srcOffset = (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt;
12993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
13003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         do_row(format, 1, tempPixel, tempPixel,
13013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
13023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
13053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
13083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
13093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
13103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
13113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
13123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
13133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
13143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLvoid *tmpRowA = MALLOC(dstWidth * format->TexelBytes);
13153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLvoid *tmpRowB = MALLOC(dstWidth * format->TexelBytes);
13163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB, *srcC, *srcD;
13173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
13183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (!tmpRowA || !tmpRowB) {
13203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (tmpRowA)
13213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         FREE(tmpRowA);
13223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /*
13263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul    * XXX lots of work to do here yet
13273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul    */
13283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   for (img = 0; img < dstDepth - 2 * border; img++) {
13303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      for (row = 0; row < dstHeight - 2 * border; row++) {
13323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         do_row(format, dstWidth - 2 * border, srcA, srcB, tmpRowA);
13333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         do_row(format, dstWidth - 2 * border, srcC, srcD, tmpRowB);
13343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
13373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
13403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
13413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
13423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
13453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
13463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
13473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
13483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
13493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
13503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul_mesa_generate_mipmap(GLcontext *ctx,
13513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
13523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
13533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
13543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets1D[] = { GL_TEXTURE_1D, 0 };
13553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets2D[] = { GL_TEXTURE_2D, 0 };
13563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets3D[] = { GL_TEXTURE_3D, 0 };
13573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targetsCube[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
13583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
13593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
13603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
13613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
13623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
13633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  0 };
13643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum *targets;
13653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLuint level;
13663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
13683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj->Image[texObj->BaseLevel]);
13693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (texObj->Dimensions) {
13713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 1:
13723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets1D;
13733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
13743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 2:
13753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets2D;
13763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
13773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 3:
13783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets3D;
13793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
13803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 6:
13813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targetsCube;
13823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
13833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
13843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(ctx,
13853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                    "Bad texture object dimension in _mesa_generate_mipmaps");
13863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
13873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
13908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul           && level < ctx->Const.MaxTextureLevels; level++) {
13913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* generate level+1 from level */
13923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
13933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
13943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
13953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
13963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
13973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint t;
13983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcImage = texObj->Image[level];
14003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
14013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
14023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
14033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
14043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
14053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      bytesPerTexel = srcImage->TexFormat->TexelBytes;
14063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
14083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
14093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
14103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
14123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
14133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
14153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
14163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
14183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
14193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
14213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
14223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
14243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
14253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
14283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
14293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
14303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
14313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
14323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* Need this loop just because of cubemaps */
14353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      for (t = 0; targets[t]; t++) {
14363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         ASSERT(t < 6);
14373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage = _mesa_select_tex_image(ctx, texUnit, targets[t], level+1);
14393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (!dstImage) {
14403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dstImage = _mesa_alloc_texture_image();
14413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            if (!dstImage) {
14423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
14433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               return;
14443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            }
14453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_set_tex_image(texObj, targets[t], level + 1, dstImage);
14463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
14473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* Free old image data */
14493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (dstImage->Data)
14503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            FREE(dstImage->Data);
14513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* initialize new image */
14533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight,
14543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                    dstDepth, border, srcImage->Format);
14553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->DriverData = NULL;
14563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->TexFormat = srcImage->TexFormat;
14573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->FetchTexel = srcImage->FetchTexel;
14583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
14603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* alloc new image buffer */
14623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->Data = MALLOC(dstWidth * dstHeight * dstDepth
14633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                 * bytesPerTexel);
14643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (!dstImage->Data) {
14653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
14663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            return;
14673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
14683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /*
14703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          * We use simple 2x2 averaging to compute the next mipmap level.
14713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          */
14723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         switch (texObj->Dimensions) {
14733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 1:
14743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_1d_mipmap(srcImage->TexFormat, border,
14753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, (const GLubyte *) srcImage->Data,
14763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, (GLubyte *) dstImage->Data);
14773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
14783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 2:
14793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 6:
14803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_2d_mipmap(srcImage->TexFormat, border,
14813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, srcHeight, (const GLubyte *) srcImage->Data,
14823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, dstHeight, (GLubyte *) dstImage->Data);
14833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
14843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 3:
14853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_3d_mipmap(srcImage->TexFormat, border,
14863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, srcHeight, srcDepth, (const GLubyte *) srcImage->Data,
14873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, dstHeight, dstDepth, (GLubyte *) dstImage->Data);
14883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
14893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         default:
14903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
14913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            return;
14923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
14933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      } /* loop over tex image targets */
14943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   } /* loop over tex levels */
14953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
1496