texstore.c revision 6b6c96bdeb580052cb9fa3831f1cd574f0e85728
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
3c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Version:  6.3
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul#include "bufferobj.h"
56e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
6289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h"
63371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
68f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic const GLint ZERO = 1000, ONE = 1001;
69f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
70f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
71f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the
72f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components.
73f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that.
74f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  the logical format of the texture
75f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the final texture format
76f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return map[4]  the four mapping values
77f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
78f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
79f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
80f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                          GLint map[4])
81f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
82f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* compute mapping from dest components back to src components */
8313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   switch (textureBaseFormat) {
8413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGB:
8513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGBA:
8613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
8713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
8813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
8913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
9013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = ONE;
9113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
9213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
9313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
9413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = ZERO;
95f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         map[3] = 0;
9613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
9713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
9813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
9913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
10013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = 0;
10113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
10213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE_ALPHA:
10313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
10413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
10513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = 1;
10613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
10713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_RGB:
10813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
10913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
11013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 1;
11113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[2] = 2;
11213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = ONE;
11313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
11413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
11513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
11613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = map[3] = 0;
11713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_LUMINANCE_ALPHA:
12013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
12113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
12213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
12313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = ONE;
12413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
12613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = ZERO;
12713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
12813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
13013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
13113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
13213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
13313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
13413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
13513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = 0;
13613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components.
143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat.
163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat *
165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims,
166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum logicalBaseFormat,
167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum textureBaseFormat,
168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum srcFormat, GLenum srcType,
170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const GLvoid *srcAddr,
171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const struct gl_pixelstore_attrib *srcPacking)
172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLfloat *tempImage;
175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY ||
184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_COLOR_INDEX ||
185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_DEPTH_COMPONENT);
186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY ||
193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_COLOR_INDEX ||
194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_DEPTH_COMPONENT);
195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* conventional color image */
197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* need image convolution */
202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint preConvTransferOps
203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint postConvTransferOps
205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint convWidth, convHeight;
208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage;
209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* pre-convolution image buffer (3D) */
211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* post-convolution image buffer (2D) */
217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage) {
220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* loop over 3D image slices */
225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* unpack and do transfer ops up to convolution */
229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
23060909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcAddr, srcWidth, srcHeight,
232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcFormat, srcType, img, row, 0);
233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcFormat, srcType, src,
235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking,
236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          preConvTransferOps);
237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * 4;
238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do convolution */
241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convWidth = srcWidth;
244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convHeight = srcHeight;
245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (dims == 1) {
246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          src, convImage);
253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               else {
255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           src, convImage);
258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do post-convolution transfer and pack into tempImage */
263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
2642b012578ee519561365640e23272b71898378c45Brian Paul            const GLint logComponents
2652b012578ee519561365640e23272b71898378c45Brian Paul               = _mesa_components_in_format(logicalBaseFormat);
266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLfloat *src = convImage;
267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (row = 0; row < convHeight; row++) {
269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_pack_rgba_span_float(ctx, convWidth,
270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          (const GLfloat (*)[4]) src,
271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          logicalBaseFormat, GL_FLOAT,
272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, &ctx->DefaultPacking,
273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          postConvTransferOps);
274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += convWidth * 4;
2752b012578ee519561365640e23272b71898378c45Brian Paul               dst += convWidth * logComponents;
276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      } /* loop over 3D image slices */
279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(convImage);
281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* might need these below */
283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcWidth = convWidth;
284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcHeight = convHeight;
285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* no convolution */
288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint components = _mesa_components_in_format(logicalBaseFormat);
289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *dst;
292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * components * sizeof(GLfloat));
296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      dst = tempImage;
300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *src
30260909388ab136d849d99eab49e782a53772a618fBrian Paul            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcWidth, srcHeight,
304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcFormat, srcType,
305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    img, 0, 0);
306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, srcFormat, srcType, src,
309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking, transferOps);
310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * components;
311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcStride;
312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* more work */
318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *newImage;
321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint map[4];
323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
32413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
32513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
32613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLfloat));
335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0.0F;
349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 1.0F;
351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLchan components.
366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLchan.
386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
3878f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian PaulGLchan *
3888f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
3898f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum logicalBaseFormat,
3908f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum textureBaseFormat,
3918f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
3928f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum srcFormat, GLenum srcType,
3938f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const GLvoid *srcAddr,
3948f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const struct gl_pixelstore_attrib *srcPacking)
395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(logicalBaseFormat);
398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLboolean freeSrcImage = GL_FALSE;
399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint img, row;
400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLchan *tempImage, *dst;
401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY);
410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY);
417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* get convolved image */
422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage = make_temp_float_image(ctx, dims,
423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcAddr, srcPacking);
428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage)
429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* the convolved image is our new source image */
431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcAddr = convImage;
432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcFormat = logicalBaseFormat;
433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcType = GL_FLOAT;
434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcPacking = &ctx->DefaultPacking;
435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      transferOps = 0;
437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      freeSrcImage = GL_TRUE;
438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* unpack and transfer the source image */
441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       * components * sizeof(GLchan));
443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!tempImage)
444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return NULL;
445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   dst = tempImage;
447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   for (img = 0; img < srcDepth; img++) {
448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcWidth, srcFormat,
450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcType);
451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLubyte *src
45260909388ab136d849d99eab49e782a53772a618fBrian Paul         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight,
454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 img, 0, 0);
456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (row = 0; row < srcHeight; row++) {
4579c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
4589c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      srcFormat, srcType, src, srcPacking,
4599c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      transferOps);
460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dst += srcWidth * components;
461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         src += srcStride;
462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* If we made a temporary image for convolution, free it here */
466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (freeSrcImage) {
467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) srcAddr);
468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one more conversion step */
472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *newImage;
475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint map[4];
477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
47813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
47913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
48013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLchan));
489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0;
503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = CHAN_MAX;
505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
52560909388ab136d849d99eab49e782a53772a618fBrian Paulmemcpy_texture(GLuint dimensions,
52660909388ab136d849d99eab49e782a53772a618fBrian Paul               const struct gl_texture_format *dstFormat,
527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstRowStride, GLint dstImageStride,
530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
53960909388ab136d849d99eab49e782a53772a618fBrian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
54060909388ab136d849d99eab49e782a53772a618fBrian Paul        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_memcpy(dstImage, srcImage, bytesPerTexture);
556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  either 1 or 2 or 3
585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat  user-specified base internal format
586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat  destination Mesa texture format
587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr  destination image address
588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride  destination image row stride, in bytes
590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride  destination image layer stride, in bytes
591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth  source image size, in pixels
592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  incoming image format
593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  incoming image data type
594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image packing parameters
596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum baseInternalFormat,
600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_texture_format *dstFormat,
601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLvoid *dstAddr,
602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstRowStride, GLint dstImageStride,
604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum srcFormat, GLenum srcType,
606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const GLvoid *srcAddr,
607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_pixelstore_attrib *srcPacking)
608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
63060909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
63160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr
644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstZoffset * dstImageStride
645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstYoffset * dstRowStride
646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstXoffset * dstFormat->TexelBytes;
647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
65060909388ab136d849d99eab49e782a53772a618fBrian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
65160909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
6678f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
6749c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
6839c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
701a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a floating point depth component texture image.
702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
704a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component_float32(STORE_PARAMS)
705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
706a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
707a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
708a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
712a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
713a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
714a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_FLOAT) {
715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
71660909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
71760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
73260909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
734a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow,
735a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                    srcType, src, srcPacking);
736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
746a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
749a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component16(STORE_PARAMS)
750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
751a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
752a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component16);
753a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
759a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
76160909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
76260909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
773a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
777a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLfloat depthTemp[MAX_WIDTH];
77860909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
780a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
781a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, depthTemp,
782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
783a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
784a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dst16[col] = (GLushort) (depthTemp[col] * 65535.0F);
785a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
796defb035b6cf03c555318d9dd48864242ed036f39Brian Paul * Store an rgb565 or rgb565_rev texture image.
797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
799a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_rgb565(STORE_PARAMS)
800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
801defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
802defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgb565_rev);
803a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 2);
804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
807defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgb565 &&
808a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
809a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
810a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
81260909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
81360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
818a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
819a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
820a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
821a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
822a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
823a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
824a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
825a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
826a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
827a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
82860909388ab136d849d99eab49e782a53772a618fBrian Paul         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
829a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
830a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
831a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstZoffset * dstImageStride
832a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstYoffset * dstRowStride
833a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstXoffset * dstFormat->TexelBytes;
834a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint row, col;
835a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (row = 0; row < srcHeight; row++) {
836a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLubyte *srcUB = (const GLubyte *) src;
837a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLushort *dstUS = (GLushort *) dst;
838defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         /* check for byteswapped format */
839f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         if (dstFormat == &_mesa_texformat_rgb565) {
840f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
841f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
842f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
843f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
844f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         }
845f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         else {
846f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
847f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
848f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
849f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
850defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         }
851a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dst += dstRowStride;
852a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         src += srcRowStride;
853a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
854a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
857a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
858a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
859a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
860a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
861a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
862a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
863a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
869a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
870a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
871a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
875a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
876defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
877f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
878f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
879f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
880f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
881f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
882f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
883f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
884f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
885f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
886f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
887f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
888f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
889f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
890f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
891f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS)
905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
906defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
907defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
912defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
914defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
915defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
91760909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
91860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
9258f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
944f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
945f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
946f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
947f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
948f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
949f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
950f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
951f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
953f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
954f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
955f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
956f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
957f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
958f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
959f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
960f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
961a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
962a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
963a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
964a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
965a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
966a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
967a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
968a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
969a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
970a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
971a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
972a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS)
974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
978defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
979defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
984defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
988defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
989defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
99060909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
99160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
996defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
997a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
998defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
999a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
1000a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
1001a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1002defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1003defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
100460909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
100560909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1006a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1007a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1008a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1009a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1010a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1011a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1012a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1013a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1014a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1015a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1016a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1017a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1018a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1019a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1020a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1021a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1022a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1023a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1024a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1025a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1026a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1027a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1028a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1029a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1030a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1031f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1032f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1033f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1034f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1035f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1036f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1037f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1038f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1039a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1040f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1041f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1042f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1043f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1044f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1045f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1046f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1047f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1048defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1049a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1050a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1051a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1052a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1053a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1054a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1055a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1056a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1057a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS)
1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
107560909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
107660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1085a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
1087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
109460909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
109560909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
11177c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1165a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_bgr888(STORE_PARAMS)
1166a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1167a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLuint ui = 1;
1168a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1169a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1170a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1171a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1172a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1173a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1174a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1175a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1176a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1177a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1178a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1179a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
118060909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
118160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1182a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1183a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1184a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1185a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1186a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1187a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1188a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1189a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1190a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1191a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1192a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1193a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1194a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1195a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1196a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1197a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1198a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
119960909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
120060909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1201a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1202a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1203a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1204a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1205a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1206a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1207a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1208a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1209a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1210a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1211a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1212a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1213a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1214a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1215a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1216a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1217a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1218a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1219a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1220a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1221a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
12227c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1223a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1224a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1225a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1226a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1227a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1228a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1229a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1230a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1231a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1232a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1233a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1234a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1235a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1236a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1237a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1238a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1239a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1240a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1241a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1242a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1243a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1244a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1245a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1246a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1247a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1248a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1249a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1250a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS)
1252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1253defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1254defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1259defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1262defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
126460909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
126560909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
12728f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1291f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1292f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1293f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1294f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1295f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1296f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1297f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1298f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1300f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1301f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1302f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1303f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1304f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1305f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1306f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1307f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1308a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1309a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1310a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1311a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1312a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1313a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1314a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1315a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1316a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1317a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1318a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1319defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1320a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS)
1322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1323defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1324defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1329defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1332defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
133460909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
133560909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13428f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1361f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1362f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1363f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1364f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1365f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1366f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1367f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1368f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1370f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1371f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1372f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1373f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1374f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1375f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1376f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1377f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1378a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1379a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1380a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1381a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1382a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1383a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1384a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1385a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1386a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1387a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS)
1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1395defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1396defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1401defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
140760909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
140860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14158f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1434f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
1435f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1436f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1437f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
1438f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
1439f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1440f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1442f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1443f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1444f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1445f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
1446f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
1447f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1448f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1449a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1450a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1451a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1452a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1453a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1454a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1455a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1456a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1457a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1458a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1459a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1460a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS)
1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
147160909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
147260909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14798f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS)
1518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
152960909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
153060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
15378f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS)
1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1573a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
158360909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
158460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
159960909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS)
1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1621a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
163360909388ab136d849d99eab49e782a53772a618fBrian Paul   memcpy_texture(dims,
163460909388ab136d849d99eab49e782a53772a618fBrian Paul                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRowStride, dstImageStride,
1636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
1645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLushort *pImage = (GLushort *) ((GLubyte *) dstAddr
1646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstZoffset * dstImageStride
1647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstYoffset * dstRowStride
1648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstXoffset * dstFormat->TexelBytes);
1649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *pRow = pImage;
1652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_swap2(pRow, srcWidth);
1654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            pRow += dstRowStride;
1655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         pImage += dstImageStride;
1657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
1667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
1668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
1669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
1670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
1671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
1672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
1673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS)
1676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
1680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
1681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
1682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
1683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
1684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
1685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
1692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
1697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
169860909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
169960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
17139c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
1714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
17229c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
1723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dst = dstImage;
1725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dst, src, bytesPerRow);
1727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += dstRowStride;
1728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS)
1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
1748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
1749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
1750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
1751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
1752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
1753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
1760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
1765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
176660909388ab136d849d99eab49e782a53772a618fBrian Paul      memcpy_texture(dims,
176760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
1781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
1793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
1794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
1795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
1796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
18107a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
1811c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
1812c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
1813c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
1814c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * The caller _must_ call unmap_teximage_pbo() too!
18157a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
18167a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
181760909388ab136d849d99eab49e782a53772a618fBrian Paulvalidate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
1818c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      GLsizei width, GLsizei height, GLsizei depth,
1819c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      GLenum format, GLenum type, const GLvoid *pixels,
1820c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      const struct gl_pixelstore_attrib *unpack,
1821c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      const char *funcName)
18227a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
1823c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
1824c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
18257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
18267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
18277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18287a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
182960909388ab136d849d99eab49e782a53772a618fBrian Paul   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
183060909388ab136d849d99eab49e782a53772a618fBrian Paul                                  format, type, pixels)) {
1831c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
1832c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
18337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1834c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1835c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   buf = ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1836c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                               GL_READ_ONLY_ARB, unpack->BufferObj);
1837c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
1838c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
1839c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
1840c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1841c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1842c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
18437a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18447a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18467a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
1847c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
1848c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
1849c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
1850c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
1851c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * The caller _must_ call unmap_teximage_pbo() too!
18527a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
18537a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
1854c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulvalidate_pbo_compressed_teximage(GLcontext *ctx,
1855c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
1856c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
1857c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
18587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
1859c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
1860c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
18617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
18627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
18637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18647a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1865c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
1866c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul       (const GLubyte *) packing->BufferObj->Size) {
1867c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
1868c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
1869c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
1870c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1871c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1872c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   buf = ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1873c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                               GL_READ_ONLY_ARB, packing->BufferObj);
1874c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
1875c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
1876c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
18777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1878c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1879c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
18807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18817a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18827a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
1883c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
1884c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
1885c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
1886c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
1887c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulstatic void
1888c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulunmap_teximage_pbo(GLcontext *ctx, const struct gl_pixelstore_attrib *unpack)
1889c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
1890c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
1891c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1892c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
1893c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1894c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
1895c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
189689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
18977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
189889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
19006b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
19018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
19048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
19058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
19068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
19078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
19088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
19098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
19108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
1912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
1913a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
19148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
19168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
19178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
19188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
19207d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
1921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
1922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                         format, type);
19237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
19244f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
19254f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
19268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
192889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
192989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
193089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
1931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
1932aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
19337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
19347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
19357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
19367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
19378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
193860909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels,
1939c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexImage1D");
19406b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
19416b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
19426b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
19436b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
194489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
19456b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
19466b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
1947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
1951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
1956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
1959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1960f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1961f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
196289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
196389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
196489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
196589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
196689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
19673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
1968c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1969c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
19708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19736b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
197489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
197589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
19766b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * We store the image in heap memory.  We know nothing about on-board
19776b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * VRAM here.  But since most DRI drivers rely on keeping a copy of all
19786b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * textures in main memory, this routine will typically be used by
19796b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * hardware drivers too.
19806b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *
1981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
19826b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Special memory allocation needs (VRAM, AGP, etc)
19836b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Unusual row/image strides or padding
1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
19856b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Using VRAM-based Pixel Buffer Objects
19868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
19898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
19908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
19918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
19928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
19938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
19948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
19958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
1997e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
1998a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
19998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
20018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
20028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
20038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
20048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20057d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
20067d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
20077d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
20087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
20097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
20104f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
20114f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
20122c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
20132c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
20148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
201689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
201789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
201889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
201989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
2020aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
20217d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
20227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
20237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
20247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
20258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
202660909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
202760909388ab136d849d99eab49e782a53772a618fBrian Paul                                  pixels, packing, "glTexImage2D");
20286b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
20296b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
20306b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
20316b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
203289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
20336b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
20346b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
20419c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2055f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
205689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
205789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
205889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
205989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
206089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
20613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2062c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2063c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
20648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20686b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
206989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
207089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
20716b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
20728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
20758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
20768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
20778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
20788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
20798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
20808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
20818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2082e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2083a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
20848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
20867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
20877d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
20887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
20897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
20904f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
20914f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
20922c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2093197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
20948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
209689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
209789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
209889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
209989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
2100aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
21017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
21027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
21037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
21047d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
21058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
210660909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 3, width, height, depth, format, type,
2107c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  pixels, packing, "glTexImage3D");
21086b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
21096b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
21106b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
21116b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
211289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
21136b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
21146b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
2119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
2120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
2123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
2124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2137f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
213889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
213989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
214089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
214189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
214289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
21433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2144c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2145c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
21468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
215289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
215389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
21548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
21578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
21588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
21598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
21608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
21618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
21628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
216360909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels,
2164c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexSubImage1D");
21657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
21667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21677a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
2173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
21833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
21843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
21853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2186d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2187d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
21883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
21893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2190c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2191c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
21928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
219589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
219789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
219889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
21998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
22028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
22038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
22048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
22058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
22068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
22078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
22088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
220960909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
221060909388ab136d849d99eab49e782a53772a618fBrian Paul                                  pixels, packing, "glTexSubImage2D");
22117a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
22127a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
22137a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
2216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
2226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
22363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
22373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
22383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2239d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2240d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
22423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2243c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2244c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
22458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
22498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
225089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
22518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
22548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
22558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
22568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
22578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
22588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
22598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
22608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
226160909388ab136d849d99eab49e782a53772a618fBrian Paul   pixels = validate_pbo_teximage(ctx, 3, width, height, depth, format, type,
2262c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  pixels, packing, "glTexSubImage3D");
2263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
22908f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
22913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
22923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2293d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2294d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
22963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2297c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2298c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
22998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23022aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
23038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
23048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
23078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
23088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
23098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
23108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
23118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
231389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2314a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2315a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2316a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2317a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2318a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2319a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2320a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
23218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
23268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
23278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
23308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
23318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
23328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
23338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
23348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2336a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2337a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
233889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
233989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
23408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
234189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
234289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
234389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
234489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
234589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
234689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
234789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
234889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
234989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
235089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
235189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
235289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
23534f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
23544f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
235589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
235689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
235789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
235889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
235989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
236089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
236189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
236289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2363c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
2364c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                           "glCompressedTexImage2D");
23657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
23667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
23677a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
236889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
23694039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
237089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
23718f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
23728f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
23738f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
23748f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
23758f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
23768f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
23778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2378c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2379c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, &ctx->Unpack);
23808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
23858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
23868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
23898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
23908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
23918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
23928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
23938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
23948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
239689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2397a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2398a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2399a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2400a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2401a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2402a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2403a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2404a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
24058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
24068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
240989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
241089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2411e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2412e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
241389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
241489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
241589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
241689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
241789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
241889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
241989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2420e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
242189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2422a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2423a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2424a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2425a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2426a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2427a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2428a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2429e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2430e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2431e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
243289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
243389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
243489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
243589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
243689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
243789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
243889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
243989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
244089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
244189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
244289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
244389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
244489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
244589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
244689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
244789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
244889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
2449a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
245089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
245189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
245289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
245389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
245489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
245589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
245689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2457c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
2458c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                           "glCompressedTexSubImage2D");
24597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
24607a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
24617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
246289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
246389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
246489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
246589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
246689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
246789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
246889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                         texImage->IntFormat,
2469f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2470f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
247189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
247289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
247389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
247489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
247589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
247689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
247789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
247889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
247989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
24808f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
24818f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
24828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
24838f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
24848f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
24858f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
24868f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2487c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2488c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, &ctx->Unpack);
248989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
249089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
249189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
249289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
249389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
249489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
249589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
249689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
249789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
249889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
249989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
250089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
250189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
250289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
250389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
250489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
250589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2506a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2507a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2508a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
2509a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2510a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2511a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2512a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2513a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
251489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
251589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
251689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
25173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
25183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
25193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
25209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
25219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
25223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
25233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
25249228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
25259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
25269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
25273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
25289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
25299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
25309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
2531c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
25329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
2533c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
25349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
25353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
25363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
25373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
25403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
25413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
25427c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2545f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2547f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2549f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2551f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
25523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
25563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
25593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
25603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
25617c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2564f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2566f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2568f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
25733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
25743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
25753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
25783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
25793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
25807c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
2582f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
25833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
25873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
25903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
25913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
25927c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2595f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2597f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
26003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
2601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
26028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
26058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
26068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
26077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
26108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT16:
2614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
2617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
2619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
2622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
26258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
26268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
2627defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
26288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
2629defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
26308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
26338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
26348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
26357c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2638f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
26399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2640f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
26419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2642f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
26439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2644f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
26458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
2649a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
26508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
26538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
26548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
26557c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2658f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
26599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2660f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
26619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2662f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
26638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
2667defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
26688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26737c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
26769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
26779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
26789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
26799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
26809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
26819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
26829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
26839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
26849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
26859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
26869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
268707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
268807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
268907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
26908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
26918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
2695defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
26968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
27008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
27017c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
27049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
27059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
27069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
27079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
27089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
27099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
27109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
27119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
27129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
27139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
27149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
27159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
27169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
27179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
27189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
271907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
272007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
272107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
272207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
27238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
27248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
2728defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
27298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
27328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
27338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
27347c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
27379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
27389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
27399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
27409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
27419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
27429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
27439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
27449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
27459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
27469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
27479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
27489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
27499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
27509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
27519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
275207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
275307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
275407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
275507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
27568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
27578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
2761defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
27628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
27658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
27668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
27677c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
27709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
27719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
27729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
27738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
27778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
27808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
27818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
27827c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
27859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
27869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
27879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
27889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
27899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
27909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
27919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
27929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
27939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
27949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
27959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
279607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
279707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
279807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
27998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
28008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
28018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
28028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
28038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
28048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
28058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
28068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
28078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
28089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
28098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
28108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
28118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
28127c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
28139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
28149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
28158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
28168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
28178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
2819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
2822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
2823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
2824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
2834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
2838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
2841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
2842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
2843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
2846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
2857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
2860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
2861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
2862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
2874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
2877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
2878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
2879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
2882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
2893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
2896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
2897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
2898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
2908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
2911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
2912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
2913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
2916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
2927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
2928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
2929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
2932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
2933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
2934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
2937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
2941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
2942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
2943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
2946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
2947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
2948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
2951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
2952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
2953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
2954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
2955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
29603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
29613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
29623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
29679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
29689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
29699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
29709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
29713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
29733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
29743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
29753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
29763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
29783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
29793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
29803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
29823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
29833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
29843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
29869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
29879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
29883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
29903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
29913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
29923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
29933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
29943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
29953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
29963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
30023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
30033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
30043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
30069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
30079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
30089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
30093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
30103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
30113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
30123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
3013462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
30143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
30163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
30173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
30183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
30193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
30203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
30213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
30223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
30249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
30259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
30263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
30273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
30283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
30293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
30323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
30333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
30343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
30353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
30363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
30373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
30383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
30393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
30403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
30413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
30423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
30433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
30443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
30453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
30469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
30479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
30489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
30499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
30503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
30519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
30523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
30533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
30549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
30553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
30563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
30579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
30589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
30599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
30619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
30629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
30639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
30649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
30659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
30669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
30679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
30689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
30699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
30709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
30719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
30729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
30739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
30749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
30759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
30769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
30779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
30783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
30813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
30853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
30863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
30883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
30893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
30919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
30929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
30939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
30949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
30959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
30969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
30973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
30989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
30999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
31009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
31013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31025c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
31035c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
31049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
31069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
31079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
31089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
31099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
31109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
31113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
31123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
31133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
31159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
31169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
31189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
31193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
31219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
31223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
31249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
31253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
31279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
31289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
31299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
31309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
31319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
31329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
31333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
31354e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
31369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
31379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
31389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
31409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
31419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
31429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
31439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
31449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
31459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
31469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
31479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
31489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
31499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
31509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
31529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
31539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
31549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
31559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
31569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
31579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
31599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
31609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
31619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
31629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
31639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
31649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
31659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
31669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
31679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
31689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
31699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
31709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
31729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
31739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
31743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
31753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
31763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
31783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
31799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
31819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
31829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
31839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
31849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
31859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
31869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
31879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
31889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
31899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
31909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
31919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
31929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
31939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
31949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
31959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
31969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
31989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
31999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
32009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
32019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
32039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
32059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
32079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
32089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
32109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
32129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
32149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
32159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
32179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
32199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
32219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
32229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
32239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
32249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
32259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
32269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
32279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
32289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
32299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
32309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
32329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
32339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
32349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
32379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
32399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
32419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
32449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
32469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
32489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
32519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
32539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
32559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
32579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
32589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
32593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
32603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
32633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
32643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
32653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
32663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
32673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3268d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
32693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
32703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
32713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
32722ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
32732ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3274b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3275b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3276ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
32773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
327918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
32802ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
32813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3282ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3283ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
32843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
32862ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
32872ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3288d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3289d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
32902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
32912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
32932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (srcImage->Format == GL_RGB) {
32952ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
32962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
32972ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else if (srcImage->Format == GL_RGBA) {
32992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
33002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
33012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
33022ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
33032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps");
33042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
33052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
33062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
33072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
33082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE)
33092ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
33102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
3311f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      srcData = (GLubyte *) MALLOC(size);
33122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
33132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
33142ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
33152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3316f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      dstData = (GLubyte *) MALLOC(size / 2);  /* 1/4 would probably be OK */
33172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
33182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
33192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         FREE((void *) srcData);
33202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
33212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
33222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
33232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
33242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
33252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3326d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
33272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
33284f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
33292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
333089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
333189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
333289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
33332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
33342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
33352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
33362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
333789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
33388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3339cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
33409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
33413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
33423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
33433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
33443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
33453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
33463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
334789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
33483ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
33493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
33503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
33513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
33523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
33533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
33543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
33563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
33573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
33583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
33613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
33633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
33643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
33673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
33693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
33703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
33733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
33763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
33773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
33783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
337989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
338089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE((void *) srcData);
338189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE(dstData);
338289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
33833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
33843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3386d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3387a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3388d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3389a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3390a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3391d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
33923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3393d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3394d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
3395d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul         MESA_PBUFFER_FREE(dstImage->Data);
3396d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3397d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3398e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
339989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                 dstDepth, border, srcImage->IntFormat);
3400d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3401d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
34024f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
34034f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
3404d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
34054f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
34064f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3407d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
340889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
340989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
341089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
341189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
341289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
341389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize);
341489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
341589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
341689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
341789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
34182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
341989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
342089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
342189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
342289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
342389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
342489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
342589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
342689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                             * bytesPerTexel);
342789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
342889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
342989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
343089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
343189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
343289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3433d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3434d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3435d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3436d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3437d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3438d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
343989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
34402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
344189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
344289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
344389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
344489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
344589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
344689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
344789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
344889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
344989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
345089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
34512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
345289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
345389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
345489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
345589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
34562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
345789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
345889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
345989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
346089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
346189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
346289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
346389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
346489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
346589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3466d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
346789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
346889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
346989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
34702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
34712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
34722ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
34732ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                                          dstWidth);
34742ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
34758f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format,
34768f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
34778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
34788f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
34798f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
34808f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
34818f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
34828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
34838f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
348489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
348589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
348689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
348789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
348889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
348989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3490d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
34913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
349280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
349380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
349480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
349580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
349680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
349780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
349880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
349980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
350080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
35011cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
35021cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
35031cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
35041cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
35051cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
35061cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
35071cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
350880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
350980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
351080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
351180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
351280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
351380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
351480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
351580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
35161cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
351780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
351880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
351980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
352080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
352180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
352280fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
352380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
352480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
352580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
35261cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
352780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
35281cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
352980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
353080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
353180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
353280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
353380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
353480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
353580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
353680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
353780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
353880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
35391cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
354080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
354180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
354280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
354380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
354480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
354580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
354680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
354780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
354880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
354980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
355080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
355180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
355280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
355380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
355480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
355580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
355680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
355780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
355880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
355980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
356080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
356180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
356280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
356380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
356480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
356580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
356633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
356733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
356833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
356933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
357033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
357133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
357233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
357333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
357433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
357533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
357633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
357733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
357833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
357933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
358033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
358133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
358233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
358333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
3584701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
358533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
358633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
358733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
358833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
358933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
359033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
359133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
359233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
359333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
359433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
359533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
359633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
359733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
359833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
359933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
3600