texstore.c revision aeb4434563c4014a662ea334878b60d3031bb3c1
1aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul/* $Id: texstore.c,v 1.35 2002/03/19 16:47:05 brianp Exp $ */
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
38e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
5aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul * Version:  4.0.2
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
7aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul * Copyright (C) 1999-2002  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);
192a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul         GLchan *dst = (GLchan *) texDestAddr
193a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstYoffset * (dstRowStride / sizeof(GLchan))
194a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstXoffset * texComponents;
1958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
1968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            MEMCPY(dst, src, srcHeight * widthInBytes);
1978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
1988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         else {
1998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLint i;
2008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (i = 0; i < srcHeight; i++) {
2018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               MEMCPY(dst, src, widthInBytes);
202a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               src += (srcRowStride / sizeof(GLchan));
203a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               dst += (dstRowStride / sizeof(GLchan));
2048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
2058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2080299ad753224372c7a6147f598fdad33f576a714Brian Paul      else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) {
2098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /* commonly used by Quake */
2108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLchan *src = (const GLchan *) _mesa_image_address(
2118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcPacking, srcAddr, srcWidth, srcHeight,
2128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                   srcFormat, srcType, 0, 0, 0);
2138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
2148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                               srcWidth, srcFormat, srcType);
215a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul         GLchan *dst = (GLchan *) texDestAddr
216a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstYoffset * (dstRowStride / sizeof(GLchan))
217a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                     + dstXoffset * texComponents;
2188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint i, j;
2198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (i = 0; i < srcHeight; i++) {
2208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLchan *s = src;
2218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *d = dst;
2228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (j = 0; j < srcWidth; j++) {
2238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*red*/
2248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*green*/
2258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               *d++ = *s++;  /*blue*/
2268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               s++;          /*alpha*/
2278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
228a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            src += (srcRowStride / sizeof(GLchan));
229a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            dst += (dstRowStride / sizeof(GLchan));
2308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         return;  /* all done */
2328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
2348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /*
2368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * General case solutions
2378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
2380299ad753224372c7a6147f598fdad33f576a714Brian Paul   if (texDestFormat == GL_COLOR_INDEX) {
2398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* color index texture */
2401ceda0f84fdfe07951071fdf4fa643d07f09a4d7Brian Paul      const GLenum texType = CHAN_TYPE;
2418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      GLint img, row;
24256671022f97cfbc199a47b3338125431e42030eeBrian Paul      GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
243a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                   + dstYoffset * (dstRowStride / sizeof(GLchan))
244a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                   + dstXoffset * texComponents;
2458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      for (img = 0; img < srcDepth; img++) {
2468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLchan *destRow = dest;
2478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (row = 0; row < srcHeight; row++) {
2488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
2498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
2511c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                    srcType, src, srcPacking, transferOps);
252a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            destRow += (dstRowStride / sizeof(GLchan));
2538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         dest += dstImageStride;
2558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
2568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
2570299ad753224372c7a6147f598fdad33f576a714Brian Paul   else if (texDestFormat == GL_DEPTH_COMPONENT) {
258f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      /* Depth texture (shadow maps) */
259f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      GLint img, row;
26056671022f97cfbc199a47b3338125431e42030eeBrian Paul      GLubyte *dest = (GLubyte *) texDestAddr
26156671022f97cfbc199a47b3338125431e42030eeBrian Paul                    + dstZoffset * dstImageStride
262a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                    + dstYoffset * (dstRowStride / sizeof(GLchan))
263f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                    + dstXoffset * texComponents;
264f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      for (img = 0; img < srcDepth; img++) {
26556671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLubyte *destRow = dest;
266f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         for (row = 0; row < srcHeight; row++) {
267f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
268f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
26956671022f97cfbc199a47b3338125431e42030eeBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow,
270e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul                                    srcType, src, srcPacking);
271a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul            destRow += (dstRowStride / sizeof(GLchan));
272f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         }
273f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul         dest += dstImageStride;
274f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul      }
275f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul   }
2768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   else {
2778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      /* regular, color texture */
2788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
2798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
2808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
2818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
2828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * Fill texture image with convolution
2838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
2848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
2858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint convWidth = srcWidth, convHeight = srcHeight;
2868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLfloat *tmpImage, *convImage;
2878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
2888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!tmpImage) {
28908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
2908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
2918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
2938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         if (!convImage) {
29408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
2958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            FREE(tmpImage);
2968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            return;
2978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
2988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
3008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            const GLfloat *srcf;
3018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLfloat *dstf = tmpImage;
3028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *dest;
3038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* unpack and do transfer ops up to convolution */
3058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
3068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *src = _mesa_image_address(srcPacking,
3078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
3088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
3098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
3108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         srcFormat, srcType, src, srcPacking,
3111c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                         transferOps & IMAGE_PRE_CONVOLUTION_BITS,
3128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                         GL_TRUE);
3138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               dstf += srcWidth * 4;
3148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* convolve */
3178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            if (dimensions == 1) {
3188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
3198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
3208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            else {
3228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
3238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
3248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          tmpImage, convImage);
3258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               else {
3278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
3288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
3298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                           tmpImage, convImage);
3308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               }
3318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            /* packing and transfer ops after convolution */
3348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            srcf = convImage;
33556671022f97cfbc199a47b3338125431e42030eeBrian Paul            dest = (GLchan *) texDestAddr + (dstZoffset + img) * dstImageStride
336a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                 + dstYoffset * (dstRowStride / sizeof(GLchan));
3378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < convHeight; row++) {
3388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               _mesa_pack_float_rgba_span(ctx, convWidth,
3398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          (const GLfloat (*)[4]) srcf,
3400299ad753224372c7a6147f598fdad33f576a714Brian Paul                                          texDestFormat, CHAN_TYPE,
3418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          dest, &_mesa_native_packing,
3421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                          transferOps
3438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                          & IMAGE_POST_CONVOLUTION_BITS);
3448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               srcf += convWidth * 4;
345a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               dest += (dstRowStride / sizeof(GLchan));
3468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(convImage);
3508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         FREE(tmpImage);
3518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
3528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      else {
3538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         /*
3548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          * no convolution
3558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul          */
3568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         GLint img, row;
35756671022f97cfbc199a47b3338125431e42030eeBrian Paul         GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
358a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                      + dstYoffset * (dstRowStride / sizeof(GLchan))
359a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul                      + dstXoffset * texComponents;
3608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         for (img = 0; img < srcDepth; img++) {
3618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            GLchan *destRow = dest;
3628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            for (row = 0; row < srcHeight; row++) {
3638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul               const GLvoid *srcRow = _mesa_image_address(srcPacking,
3648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcAddr, srcWidth, srcHeight,
3658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                              srcFormat, srcType, img, row, 0);
3660299ad753224372c7a6147f598fdad33f576a714Brian Paul               _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat,
3670299ad753224372c7a6147f598fdad33f576a714Brian Paul                                       destRow, srcFormat, srcType, srcRow,
3681c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                       srcPacking, transferOps);
369a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul               destRow += (dstRowStride / sizeof(GLchan));
3708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            }
3718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul            dest += dstImageStride;
3728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul         }
3738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      }
3748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
3758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
3768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
3807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Transfer a texture image from user space to <destAddr> applying all
3817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * needed image transfer operations and storing the result in the format
3827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * specified by <dstFormat>.  <dstFormat> may be any format from texformat.h.
3837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * Input:
3841c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dimensions - 1, 2 or 3
3851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   baseInternalFormat - base format of the internal texture format
3861c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *       specified by the user.  This is very important, see below.
3871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstFormat - destination image format
3881c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstAddr - destination address
3891c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcWidth, srcHeight, srcDepth - size of source iamge
3901c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   dstX/Y/Zoffset - as specified by glTexSubImage
3917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *   dstRowStride - stride between dest rows in bytes
3927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *   dstImagetride - stride between dest images in bytes
3931c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcFormat, srcType - incoming image format and datatype
3941c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcAddr - source image address
3951c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul *   srcPacking - packing params of source image
3967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul *
3977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * XXX this function is a bit more complicated than it should be.  If
3987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * _mesa_convert_texsubimage[123]d could handle any dest/source formats
3997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * or if transfer_teximage() could store in any MESA_FORMAT_* format, we
4007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul * could simplify things here.
4017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul */
4027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paulvoid
4037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
4041c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        GLenum baseInternalFormat,
4057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_texture_format *dstFormat,
4067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLvoid *dstAddr,
4077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint srcWidth, GLint srcHeight, GLint srcDepth,
4087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
4097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLint dstRowStride, GLint dstImageStride,
4107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        GLenum srcFormat, GLenum srcType,
4117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const GLvoid *srcAddr,
4127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        const struct gl_pixelstore_attrib *srcPacking)
4137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul{
4147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
4157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
4167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   GLboolean makeTemp;
4171c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
4181c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLboolean freeSourceData = GL_FALSE;
4191c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
4201c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
421e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   assert(baseInternalFormat > 0);
422e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
4231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (transferOps & IMAGE_CONVOLUTION_BIT) {
4241c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
4251c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                                         &postConvHeight);
4261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
4271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /*
4291c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * Consider this scenario:  The user's source image is GL_RGB and the
4301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * requested internal format is GL_LUMINANCE.  Now suppose the device
4311c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the
4321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * texture format.  In that case we still need to do an intermediate
4331c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * conversion to luminance format so that the incoming red channel gets
4341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * replicated into the dest red, green and blue channels.  The following
4351c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * code takes care of that.
4361c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
4371c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (dstFormat->BaseFormat != baseInternalFormat) {
4381c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* Allocate storage for temporary image in the baseInternalFormat */
4391c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint texelSize = _mesa_components_in_format(baseInternalFormat)
4401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         * sizeof(GLchan);
4411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth;
4421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpRowStride = texelSize * postConvWidth;
4431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight;
4441c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      GLvoid *tmpImage = MALLOC(bytes);
4451c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage)
4461c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         return;
4471c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage,
4481c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcWidth, srcHeight, srcDepth,
4491c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        0, 0, 0, /* x/y/zoffset */
4501c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        tmpRowStride, tmpImgStride,
4511c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
4521c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
4531c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      /* this is our new source image */
4541c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcWidth = postConvWidth;
4551c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcHeight = postConvHeight;
4561c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcFormat = baseInternalFormat;
4571c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcType = CHAN_TYPE;
4581c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcAddr = tmpImage;
4591c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      srcPacking = &_mesa_native_packing;
4601c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
4611c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transferOps = 0;  /* image transfer ops were completed */
4621c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   }
4637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
4641c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   /* Let the optimized tex conversion functions take a crack at the
4651c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    * image conversion if the dest format is a h/w format.
4661c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul    */
4677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
4681c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps) {
4697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         makeTemp = GL_TRUE;
4707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
4717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
4727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (dimensions == 1) {
4737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat,
4747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset,
4757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth,
4767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
4777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
4787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
4797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else if (dimensions == 2) {
4817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat,
4827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstXoffset, dstYoffset,
4837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcWidth, srcHeight,
4847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstRowStridePixels,
4857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcFormat, srcType,
4867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    srcPacking, srcAddr,
4877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                                    dstAddr);
4887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         else {
4907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            assert(dimensions == 3);
4917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat,
4927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
4937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
4947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
4957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
4967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
4977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
4987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         if (!makeTemp) {
4997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            /* all done! */
5001c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            if (freeSourceData)
5011c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul               FREE((void *) srcAddr);
5027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul            return;
5037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         }
5047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
5077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software texture format */
5087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      makeTemp = GL_FALSE;
5097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (makeTemp) {
5127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
5137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLenum tmpFormat;
5147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLuint tmpComps, tmpTexelSize;
5157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLint tmpRowStride, tmpImageStride;
5167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      GLubyte *tmpImage;
5177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5181c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (transferOps & IMAGE_CONVOLUTION_BIT) {
5197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
5207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                            &postConvHeight);
5217d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5231c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      tmpFormat = dstFormat->BaseFormat;
5247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpComps = _mesa_components_in_format(tmpFormat);
52536f3712e85cafef1b038189678030f6ef4f8b7e9Brian Paul      tmpTexelSize = tmpComps * sizeof(GLchan);
5267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpRowStride = postConvWidth * tmpTexelSize;
5277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
5287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
5297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                    srcDepth * tmpTexelSize);
5301c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (!tmpImage) {
5311c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         if (freeSourceData)
5321c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul            FREE((void *) srcAddr);
5337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         return;
5341c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      }
5357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
5377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
5387d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        0, 0, 0, /* x/y/zoffset */
5397d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        tmpRowStride, tmpImageStride,
5401c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
5411c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
5421c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      if (freeSourceData)
5431c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul         FREE((void *) srcAddr);
5447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* the temp image is our new source image */
5467d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcWidth = postConvWidth;
5477d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcHeight = postConvHeight;
5487d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcFormat = tmpFormat;
5497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcType = CHAN_TYPE;
5507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcAddr = tmpImage;
5517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      srcPacking = &_mesa_native_packing;
5521c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      freeSourceData = GL_TRUE;
5537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
5557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (_mesa_is_hardware_tex_format(dstFormat)) {
5567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(makeTemp);
5577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      if (dimensions == 1) {
5587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat,
5607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset,
5617d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth,
5627d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
5637d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
5647d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
5657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else if (dimensions == 2) {
5687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat,
5707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstXoffset, dstYoffset,
5717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcWidth, srcHeight,
5727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstRowStridePixels,
5737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcFormat, srcType,
5747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         srcPacking, srcAddr,
5757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                         dstAddr);
5767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      else {
5797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         GLboolean b;
5807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat,
5817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstXoffset, dstYoffset, dstZoffset,
5827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcWidth, srcHeight, srcDepth,
5837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      dstRowStridePixels, dstImageStridePixels,
5847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcFormat, srcType,
5857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                      srcPacking, srcAddr, dstAddr);
5867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul         assert(b);
5877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      }
5887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   else {
5907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      /* software format */
5917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      assert(!makeTemp);
5921c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr,
5937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        srcWidth, srcHeight, srcDepth,
5947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstXoffset, dstYoffset, dstZoffset,
5957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                        dstRowStride, dstImageStride,
5961c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                        srcFormat, srcType, srcAddr, srcPacking, transferOps);
5977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
5981c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul
5991c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   if (freeSourceData)
6001c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul      FREE((void *) srcAddr);  /* the temp image */
6017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul}
6027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul
6047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
6058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage1D().
6068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
6078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
6088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
6098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
6108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
6118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
6128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
6138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
6148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
6158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
6168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
6178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
6188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
6198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
6208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
621e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
6228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
6248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
6258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
6268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
6287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
6297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
6307d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
6317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
6329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
6338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
63419d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
63519d1e432612cf7db797da11793b13a6c1c6aac16Gareth Hughes
636e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   /* Compute image size, in bytes */
637e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   if (texImage->IsCompressed) {
638e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(ctx->Driver.CompressedTextureSize);
639e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
640e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(sizeInBytes > 0);
641e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      texImage->CompressedSize = sizeInBytes;
642e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
643e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   else {
644e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = postConvWidth * texelBytes;
645e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
646e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
6478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
648aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
6497d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
6507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
6517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
6527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
6538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
654f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul   if (pixels) {
655f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* unpack image, apply transfer ops and store in texImage->Data */
656f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 1,
657f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              _mesa_base_tex_format(ctx, internalFormat),
658f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
659f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              width, 1, 1, 0, 0, 0,
660f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstRowStride */
661f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstImageStride */
662f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
663f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
664f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* GL_SGIS_generate_mipmap */
665f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
666f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul         _mesa_generate_mipmap(ctx,
667f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
668f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               texObj);
669f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      }
6703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
6718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
6728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
6758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage2D().
6768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
6778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
6788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
6798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
680e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * NOTE: if real texture compression is supported, this whole function
681e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * will need to be overridden.
6828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
6838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
6848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
6858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
6868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
6878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
6888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
6898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
6908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
6918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
6928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
693e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
6948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
6958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
6968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
6978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
6988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
6998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
7017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
7027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
7037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
7047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
7053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
7062c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
7072c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
7088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
709e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   /* Compute image size, in bytes */
710e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   if (texImage->IsCompressed) {
711e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(ctx->Driver.CompressedTextureSize);
712e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
713e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(sizeInBytes > 0);
714e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      texImage->CompressedSize = sizeInBytes;
715e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
716e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   else {
717e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
718e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
719e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
7208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
721aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
7227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
7237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
7247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
7257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
7268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
727f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul   if (pixels) {
728f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* unpack image, apply transfer ops and store in texImage->Data */
729f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 2,
730f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              _mesa_base_tex_format(ctx, internalFormat),
731f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
732f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              width, height, 1, 0, 0, 0,
733f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->Width * texelBytes,
734f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              0, /* dstImageStride */
735f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
736f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
737f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* GL_SGIS_generate_mipmap */
738f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
739f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul         _mesa_generate_mipmap(ctx,
740f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
741f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               texObj);
742f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      }
7433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
7448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
7458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
7498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexImage3D().
7508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image type will be GLchan.
7518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
7528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
7538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
7548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
7558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
7568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
7578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
7588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
7598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
7608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
7618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
7628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
7638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
764e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
7658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
7667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
7677d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
7687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
7697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
7707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
7719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
7722c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
773197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
7748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
775e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   /* Compute image size, in bytes */
776e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   if (texImage->IsCompressed) {
777e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(ctx->Driver.CompressedTextureSize);
778e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage);
779e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      assert(sizeInBytes > 0);
780e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      texImage->CompressedSize = sizeInBytes;
781e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
782e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   else {
783e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul      sizeInBytes = width * height * depth * texelBytes;
784e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   }
785e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
7868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
787aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
7887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
7897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
7907d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
7917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
7928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
793f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul   if (pixels) {
794f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* unpack image, apply transfer ops and store in texImage->Data */
795f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      _mesa_transfer_teximage(ctx, 3,
796f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              _mesa_base_tex_format(ctx, internalFormat),
797f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->TexFormat, texImage->Data,
798f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              width, height, depth, 0, 0, 0,
799f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->Width * texelBytes,
800f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              texImage->Width * texImage->Height * texelBytes,
801f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                              format, type, pixels, packing);
802f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
803f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      /* GL_SGIS_generate_mipmap */
804f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
805f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul         _mesa_generate_mipmap(ctx,
806f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
807f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul                               texObj);
808f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul      }
8093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage1D().
8178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
8208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
8218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
8228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
8238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
8248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
8258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8261c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 1,
8271c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
8281c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
8298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, 1, 1, /* src size */
8308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, 0, 0, /* dest offsets */
8318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstRowStride */
8328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
8338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
8343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
8353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
8363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
8373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
8383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
8393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage2D().
8458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
8488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
8498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
8508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
8518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
8528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
8538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
8548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
8551c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 2,
8561c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
8571c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
8588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, 1, /* src size */
8598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, yoffset, 0, /* dest offsets */
86038f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texImage->TexFormat->TexelBytes,
8618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           0, /* dstImageStride */
8628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
8633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
8643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
8653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
8663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
8673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
8683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
8728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
8738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
8748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
8758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
8768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
8778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
8788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
8798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
8808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
8818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
8828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
8838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
88438f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes   const GLint texelBytes = texImage->TexFormat->TexelBytes;
8851c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul   _mesa_transfer_teximage(ctx, 3,
8861c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           _mesa_base_tex_format(ctx, texImage->IntFormat),
8871c85aa33321821b44bea83d3dee702ab4e05f406Brian Paul                           texImage->TexFormat, texImage->Data,
8888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           width, height, depth, /* src size */
8898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           xoffset, yoffset, xoffset, /* dest offsets */
89038f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texelBytes,
89138f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes                           texImage->Width * texImage->Height * texelBytes,
8928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                           format, type, pixels, packing);
8933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
8943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
8953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
8963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
8973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
8988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
8998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9022aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul
9032aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
9048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
9058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
9078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
9088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
9098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
9108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
9118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
9128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
9138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
9148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
9158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
9168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
9178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
9228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
9238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
9258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
9268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
9278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
9288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
9298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
9308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
9318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
9328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
9338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
9348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
9358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
9408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
9418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
9438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
9448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
9458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
9468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
9478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
9488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
9498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
9508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
9518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* Nothing here.
9528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The device driver has to do it all.
9538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
9548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
9558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
959e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * Fallback for Driver.GetCompressedTexImage3D()
960e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * This will probably work find for hardware drivers.  That is, hardware
961e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * drivers won't have to override this function, unless the compressed
962e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul * texture must first be fetched from the TRAM.
963e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
964e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
965e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target,
966e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul                              GLint level, void *image,
967e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul                              const struct gl_texture_object *texObj,
968e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul                              struct gl_texture_image *texImage)
969e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
970e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   assert(texImage->IsCompressed);
971e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   assert(texImage->CompressedSize > 0);
972e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   MEMCPY(image, texImage->Data, texImage->CompressedSize);
973e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
974e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
975e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
976e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
977e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul/*
9788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the fallback for Driver.TestProxyTexImage().
9798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9808e39ad2cd67d49be40ff0822f3269affdf83d601Brian PaulGLboolean
9818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
9828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint internalFormat, GLenum format, GLenum type,
9838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth, GLint border)
9848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
9858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_unit *texUnit;
9868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_object *texObj;
9878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   struct gl_texture_image *texImage;
9888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   (void) format;
9908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   (void) type;
9918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
9938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texObj = _mesa_select_tex_object(ctx, texUnit, target);
9948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
9958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* We always pass.
9978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * The core Mesa code will have already tested the image size, etc.
9989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * If a driver has more stringent texture limits to enforce it will
9998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    * have to override this function.
10008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
10017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
10027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
10037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
10047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
10057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
10068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
10078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   return GL_TRUE;
10088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
10093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
10103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
10113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
10123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
10133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
10143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
10159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
10169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
10173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
10183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
10199228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
10209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
10219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
10223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
10239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
10249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
10259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
10269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
10279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
10283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
10293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
10303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
10319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
10323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
10333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
10343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
10357c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
10369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
10379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1038f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
10399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1040f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
10419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1042f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
10439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
1044f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
10453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
10463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
10473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
10483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
10493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
10509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
10513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
10523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
10533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
10547c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
10559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
10569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1057f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
10589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1059f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
10609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1061f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
10623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
10633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
10643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
10653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
10663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
10673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
10683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_COLOR_INDEX:
10693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
10709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
10713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
10723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
10733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
10747c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
10759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
1076f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
10773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
10783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
10793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
10803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
10813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
10829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
10833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
10843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
10853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
10867c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
10879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
10889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1089f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
10909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1091f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
10923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
10933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
10943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
10953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT:
10968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
10979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
10988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
10998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
11008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
11017c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
11029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
11039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
11048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
11088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
11098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
11108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
11128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
11138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
11148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
11157c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
11169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
11179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1118f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
11199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1120f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
11219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1122f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
11239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
1124f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
11258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
11298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
11318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
11328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
11338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
11347c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
11359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
11369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
1137f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
11389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
1139f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
11409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
1141f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
11428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
11468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
11488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
11498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
11508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
11517c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
11529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
11539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
11549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
11559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
11569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
11579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
11589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
11599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
11609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
11619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
11629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
11639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
11649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
11658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
11668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
11678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
11688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
11698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
11708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
11718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
11728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
11738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
11749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
11758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
11768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
11778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
11787c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
11799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
11809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
11819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
11829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
11839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
11849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
11859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
11869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
11879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
11889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
11899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
11909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
11919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
11929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
11939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
11949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
11959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
11968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
11978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
11988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
11998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
12008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
12018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
12058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
12069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
12078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
12088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
12098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
12107c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
12129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
12139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
12149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
12159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
12169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
12179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
12189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
12199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
12209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
12219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
12229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
12239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
12249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
12259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
12269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
12279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
12288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
12298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
12308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
12318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
12328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
12338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
12378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
12389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
12398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
12408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
12418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
12427c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
12449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
12459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
12469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
12479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
12488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
12528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
12539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
12548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
12558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
12568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
12577c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
12599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
12609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
12619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
12629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
12639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
12649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
12659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
12669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
12679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
12689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
12699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
12709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
12718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
12728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
12738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
12748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
12758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
12798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
12808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
12818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
12828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
12839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
12848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
12858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
12868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
12877c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
12899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
12908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
12918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
12928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
12933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
12943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
12953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
12963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
12973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
12999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
13009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
13019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
13029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
13039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
13043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
13063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
13073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
13083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
13093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
13103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
13113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
13123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
13133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
13153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
13163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
13173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
13199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
13209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
13213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
13233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
13243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
13253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
13263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
13273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
13283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
13293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
13313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
13343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
13353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
13363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
13373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
13383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
13399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
13409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
13419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
13423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
13433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
13443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
13453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
13469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint row, colStride;
13479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
13489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   colStride = (srcWidth == dstWidth) ? 1 : 2;
13493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
13513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
13523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
13533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
13543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
13553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
13563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
13573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
13599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
13609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
13613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
13623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
13633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
13643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
13653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
13668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
13673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
13683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
13693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
13703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
13713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
13723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
13733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
13743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
13753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
13763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
13773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
13783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
13793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
13803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
13819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
13829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
13839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
13849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
13853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
13869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
13873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
13883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
13899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
13903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
13913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
13929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
13939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
13949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
13959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
13969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
13979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
13989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
13999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
14009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
14019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
14029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
14039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
14049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
14059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
14069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
14079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
14089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
14099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
14109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
14119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
14129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
14133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
14143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
14153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
14163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
14193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
14203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
14213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
14223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
14233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
14243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
14259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
14269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
14279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
14289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
14299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
14309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
14319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
14323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
14339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
14349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
14359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
14363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14375c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
14385c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
14399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
14409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
14419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
14429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
14439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
14449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
14459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
14463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
14473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
14483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
14509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
14519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
14529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
14539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
14543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
14569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
14573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
14599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
14603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
14629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
14639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
14649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
14659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
14669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
14679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
14683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
14699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
14709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
14719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
14729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
14739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
14749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
14759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
14769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
14779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
14789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
14799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
14809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
14819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
14829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
14839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
14849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
14859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
14869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
14879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
14889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
14899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
14909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
14919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
14929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
14939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
14949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
14959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
14969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
14979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
14989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
14999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
15009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
15019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
15029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
15039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
15049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
15059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
15069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
15079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
15089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
15093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
15103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
15113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
15133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
15149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
15169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
15179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
15189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
15199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
15209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
15219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
15229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
15239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
15249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
15259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
15269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
15279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
15289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
15299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
15309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
15319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
15339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
15349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
15359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
15369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
15389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
15409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
15429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
15439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
15459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
15479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
15499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
15509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
15529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
15549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
15569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
15579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
15589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
15599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
15609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
15619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
15629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
15639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
15649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
15659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
15679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
15689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
15699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
15709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
15729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
15749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
15769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
15779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
15799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
15819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
15839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
15849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
15859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
15869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
15879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
15889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
15899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
15909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
15919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
15929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
15939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
15943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
15953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
15973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
15983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
15993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
16003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
16013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
16023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
16033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul_mesa_generate_mipmap(GLcontext *ctx,
16043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
16053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
16063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
16073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets1D[] = { GL_TEXTURE_1D, 0 };
16083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets2D[] = { GL_TEXTURE_2D, 0 };
16093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targets3D[] = { GL_TEXTURE_3D, 0 };
16103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum targetsCube[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
16113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
16123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
16133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
16143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
16153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
16163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                  0 };
16173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLenum *targets;
16187c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz   GLint level;
1619cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   GLint maxLevels = 0;
16203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
16223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj->Image[texObj->BaseLevel]);
16233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (texObj->Dimensions) {
16253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 1:
16263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets1D;
1627cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxTextureLevels;
16283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
16293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 2:
16303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets2D;
1631cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxTextureLevels;
16323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
16333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 3:
16343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targets3D;
1635cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.Max3DTextureLevels;
16363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
16373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case 6:
16383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      targets = targetsCube;
1639cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxCubeTextureLevels;
16403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      break;
16413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
16423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(ctx,
16433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                    "Bad texture object dimension in _mesa_generate_mipmaps");
16443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
16453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
16463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
1648cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
16499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
16503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
16513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
16523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
16533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
16543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
16553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint t;
16563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcImage = texObj->Image[level];
16583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
16593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
16603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
16613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
16623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
16633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      bytesPerTexel = srcImage->TexFormat->TexelBytes;
16643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
16663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
16673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
16683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
16703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
16713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
16733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
16743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
16763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
16773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
16793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
16803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
16823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
16833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
16863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
16873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
16883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
16893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
16903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
16913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* Need this loop just because of cubemaps */
16933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      for (t = 0; targets[t]; t++) {
16943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         ASSERT(t < 6);
16953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
16963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage = _mesa_select_tex_image(ctx, texUnit, targets[t], level+1);
16973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (!dstImage) {
16983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            dstImage = _mesa_alloc_texture_image();
16993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            if (!dstImage) {
17003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
17013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               return;
17023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            }
17033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_set_tex_image(texObj, targets[t], level + 1, dstImage);
17043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
17053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* Free old image data */
17073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (dstImage->Data)
1708aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul            MESA_PBUFFER_FREE(dstImage->Data);
17093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* initialize new image */
17113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight,
17123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                    dstDepth, border, srcImage->Format);
17133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->DriverData = NULL;
17143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->TexFormat = srcImage->TexFormat;
17153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstImage->FetchTexel = srcImage->FetchTexel;
17169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(dstImage->TexFormat);
17179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(dstImage->FetchTexel);
17183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
17203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* alloc new image buffer */
1722aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
17233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                                 * bytesPerTexel);
17243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         if (!dstImage->Data) {
17253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
17263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            return;
17273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
17283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
17293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /*
17303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          * We use simple 2x2 averaging to compute the next mipmap level.
17313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          */
17323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         switch (texObj->Dimensions) {
17333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 1:
17343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_1d_mipmap(srcImage->TexFormat, border,
17353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, (const GLubyte *) srcImage->Data,
17363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, (GLubyte *) dstImage->Data);
17373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
17383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 2:
17393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 6:
17403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_2d_mipmap(srcImage->TexFormat, border,
17413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, srcHeight, (const GLubyte *) srcImage->Data,
17423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, dstHeight, (GLubyte *) dstImage->Data);
17433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
17443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         case 3:
17453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            make_3d_mipmap(srcImage->TexFormat, border,
17463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               srcWidth, srcHeight, srcDepth, (const GLubyte *) srcImage->Data,
17473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               dstWidth, dstHeight, dstDepth, (GLubyte *) dstImage->Data);
17483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            break;
17493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         default:
17503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
17513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul            return;
17523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
17533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      } /* loop over tex image targets */
17543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   } /* loop over tex levels */
17553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
1756