texstore.c revision 1cfe1e8925f8e1b89df5330895255a038be7f122
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
34f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Version:  6.1
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
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++) {
230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(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
302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            = (const GLubyte *) _mesa_image_address(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
452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (const GLubyte *) _mesa_image_address(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
525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmemcpy_texture(const struct gl_texture_format *dstFormat,
526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstRowStride, GLint dstImageStride,
529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(srcPacking,
539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_memcpy(dstImage, srcImage, bytesPerTexture);
555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  either 1 or 2 or 3
584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat  user-specified base internal format
585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat  destination Mesa texture format
586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr  destination image address
587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride  destination image row stride, in bytes
589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride  destination image layer stride, in bytes
590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth  source image size, in pixels
591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  incoming image format
592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  incoming image data type
593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image packing parameters
595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum baseInternalFormat,
599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_texture_format *dstFormat,
600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLvoid *dstAddr,
601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstRowStride, GLint dstImageStride,
603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum srcFormat, GLenum srcType,
605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const GLvoid *srcAddr,
606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_pixelstore_attrib *srcPacking)
607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr
642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstZoffset * dstImageStride
643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstYoffset * dstRowStride
644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstXoffset * dstFormat->TexelBytes;
645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
648bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(srcPacking, srcAddr,
649bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul                           srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
6658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
6729c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
6819c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
699a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a floating point depth component texture image.
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
702a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component_float32(STORE_PARAMS)
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
704a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
705a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
706a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
710a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
711a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
712a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_FLOAT) {
713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
731a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow,
732a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                    srcType, src, srcPacking);
733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
743a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
746a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component16(STORE_PARAMS)
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
748a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
749a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component16);
750a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
756a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
769a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
773a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLfloat depthTemp[MAX_WIDTH];
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
776a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
777a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            _mesa_unpack_depth_span(ctx, srcWidth, depthTemp,
778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
779a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
780a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dst16[col] = (GLushort) (depthTemp[col] * 65535.0F);
781a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
792defb035b6cf03c555318d9dd48864242ed036f39Brian Paul * Store an rgb565 or rgb565_rev texture image.
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
795a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_rgb565(STORE_PARAMS)
796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
797defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
798defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgb565_rev);
799a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 2);
800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
803defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgb565 &&
804a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
805a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
806a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
813a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
814a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
815a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
816a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
817a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
818a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
819a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
820a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
821a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
822a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
823a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         _mesa_image_address(srcPacking, srcAddr, srcWidth, srcHeight,
824a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
825a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
826a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstZoffset * dstImageStride
827a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstYoffset * dstRowStride
828a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstXoffset * dstFormat->TexelBytes;
829a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint row, col;
830a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (row = 0; row < srcHeight; row++) {
831a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLubyte *srcUB = (const GLubyte *) src;
832a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLushort *dstUS = (GLushort *) dst;
833defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         /* check for byteswapped format */
834f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         if (dstFormat == &_mesa_texformat_rgb565) {
835f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
836f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
837f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
838f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
839f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         }
840f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         else {
841f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
842f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
843f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
844f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
845defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         }
846a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dst += dstRowStride;
847a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         src += srcRowStride;
848a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
849a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
852a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
853a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
854a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
855a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
856a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
857a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
858a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
864a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
865a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
866a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
870a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
871defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
872f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
873f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
874f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
875f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
876f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
877f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
878f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
879f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
880f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
881f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
882f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
883f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
884f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
885f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
886f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS)
900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
901defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
902defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
907defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
909defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
910defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
9198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
938f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
939f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
940f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
941f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
942f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
943f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
944f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
945f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
947f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
948f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
949f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
950f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
951f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
952f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
953f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
954f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
955a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
956a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
957a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
958a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
959a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
960a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
961a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
962a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
963a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
964a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
965a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
966a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS)
968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
972defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
973defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
978defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
982defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
983defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
989defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
990a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
991defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
992a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
993a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
994a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
995defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
996defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
997a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
998a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
999a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1000a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1001a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1002a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1003a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1004a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1005a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1006a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1007a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1008a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1009a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1010a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1011a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1012a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1013a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1014a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1015a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1016a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1017a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1018a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1019a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1020a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1021a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1022a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1023f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1024f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1025f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1026f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1027f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1028f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1029f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1030f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1031a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1032f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1033f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1034f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1035f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1036f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1037f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1038f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1039f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1040defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1041a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1042a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1043a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1044a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1045a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1046a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1047a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1048a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1049a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS)
1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1076a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
1078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
1085bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(srcPacking, srcAddr,
1086bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul                           srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
11087c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1156a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_bgr888(STORE_PARAMS)
1157a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1158a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLuint ui = 1;
1159a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1160a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1161a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1162a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1163a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1164a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1165a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1166a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1167a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1168a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1169a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1170a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
1171a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1172a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1173a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1174a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1175a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1176a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1177a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1178a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1179a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1180a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1181a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1182a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1183a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1184a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1185a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1186a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1187a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1188a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
1189a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(srcPacking, srcAddr,
1190a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                           srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1191a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1192a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1193a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1194a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1195a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1196a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1197a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1198a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1199a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1200a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1201a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1202a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1203a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1204a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1205a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1206a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1207a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1208a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1209a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1210a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1211a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
12127c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1213a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1214a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1215a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1216a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1217a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1218a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1219a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1220a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1221a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1222a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1223a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1224a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1225a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1226a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1227a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1228a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1229a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1230a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1231a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1232a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1233a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1234a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1235a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1236a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1237a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1238a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1239a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1240a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS)
1242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1243defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1244defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1249defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1252defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
12618f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1280f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1281f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1282f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1283f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1284f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1285f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1286f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1287f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1289f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1290f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1291f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1292f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1293f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1294f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1295f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1296f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1297a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1298a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1299a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1300a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1301a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1302a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1303a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1304a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1305a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1306a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1307a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1308defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1309a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS)
1311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1312defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1313defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1318defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1321defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13308f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1349f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1350f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1351f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1352f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1353f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1354f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1355f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1356f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1358f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1359f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1360f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1361f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1362f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1363f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1364f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1365f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1366a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1367a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1368a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1369a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1370a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1371a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1372a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1373a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1374a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1375a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS)
1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1383defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1384defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1389defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1421f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
1422f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1423f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1424f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
1425f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
1426f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1427f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1429f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1430f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1431f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1432f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
1433f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
1434f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1435f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1436a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1437a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1438a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1439a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1440a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1441a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1442a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1443a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1444a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1445a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1446a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1447a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS)
1449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS)
1504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
15228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS)
1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1558a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
1584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS)
1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1605a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
1617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRowStride, dstImageStride,
1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLushort *pImage = (GLushort *) ((GLubyte *) dstAddr
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstZoffset * dstImageStride
1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstYoffset * dstRowStride
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstXoffset * dstFormat->TexelBytes);
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *pRow = pImage;
1635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_swap2(pRow, srcWidth);
1637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            pRow += dstRowStride;
1638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         pImage += dstImageStride;
1640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
1650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
1651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
1652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
1653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
1654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
1655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
1656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS)
1659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
1663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
1664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
1665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
1666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
1667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
1668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
1675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
1680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
16959c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
1696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
17049c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dst = dstImage;
1707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dst, src, bytesPerRow);
1709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += dstRowStride;
1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
1723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS)
1726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
1730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
1731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
1734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
1735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
1747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
1774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
1775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
1776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
1777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
17917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
17927a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate acces to a PBO for texture data.
17937a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul *
17947a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the
17957a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing.
17967a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
17977a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
17987a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth,
17997a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
18007a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                       const struct gl_pixelstore_attrib *unpack )
18017a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
18027a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
18037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
18047a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18057a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
18067a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
18077a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                      type, pixels)) {
18087a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return ADD_POINTERS(unpack->BufferObj->Data, pixels);
18097a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
18107a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   /* bad access! */
18117a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   return NULL;
18127a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18137a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18147a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18157a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
18167a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate that unpacking compressed texture image data from a PBO
18177a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * won't go out of bounds.
18187a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul *
18197a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the
18207a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing.
18217a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
18227a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
18237a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels,
18247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                               const struct gl_pixelstore_attrib *packing)
18257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
18267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
18277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
18287a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18297a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
18307a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   else {
18317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* using a PBO */
18327a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      if ((const GLubyte *) pixels + imageSize >
18337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul          (const GLubyte *) packing->BufferObj->Size) {
18347a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul         /* out of bounds read! */
18357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul         return NULL;
18367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      }
18377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* OK! */
18387a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return ADD_POINTERS(packing->BufferObj->Data, pixels);
18397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
18407a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18417a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
184389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
18447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
184589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
1846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
18478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
18488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
18498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
18508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
18518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
18528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
18538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
18548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
18558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
18568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
18578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
1858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
1859a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
18608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
18628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
18638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
18648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18657d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
18667d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
1867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
1868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                         format, type);
18697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
18704f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
18714f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
18728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
187489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
187589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
187689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
1877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
1878aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
18797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
18807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
18817d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
18827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
18838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18847a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing);
188589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
188689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
188789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
1893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1904f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
190589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
190689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
190789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
190889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
190989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
19103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
19118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
191589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
191689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
1917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
1918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special memory allocation needs
1919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Unusual row/image strides
1920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
19218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
19248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
19258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
19268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
19278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
19288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
19298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
19308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
1932e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
1933a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
19348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
19368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
19378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
19388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
19398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19407d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
19417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
19427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
19437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
19447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
19454f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
19464f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
19472c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
19482c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
19498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
195189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
195289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
195389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
195489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
1955aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
19567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
19577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
19587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
19597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
19608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, 1,
19627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
196389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
196489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
196589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
1968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
1970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
1971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
19739c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
1974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
1982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1988f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
198989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
199089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
199189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
199289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
199389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
19943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
19958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
200089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
200189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
20028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
20058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
20068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
20078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
20088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
20098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
20108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
20118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2012e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2013a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
20148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
20167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
20177d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
20187d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
20197d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
20204f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
20214f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
20222c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2023197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
20248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
202689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
202789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
202889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
202989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
2030aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
20317d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
20327d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
20337d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
20347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
20358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, depth,
20377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
203889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
203989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
204089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
204189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2066f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
206789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
206889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
206989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
207089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
207189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
20723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
20738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
207989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
208089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
20818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
20848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
20858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
20868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
20878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
20888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
20898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
20907a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, 1, 1,
20917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
20927a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
20937a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
20947a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
21113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
21123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
21133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2114d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2115d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
21163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
21173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
21188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
212189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
212389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
212489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
21258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
21288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
21298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
21308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
21318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
21328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
21338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
21348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
21357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, 1,
21367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
21377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
21387a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
2142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
2152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
21633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
21643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
21653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2166d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2167d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
21683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
21693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
21708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
21748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
217589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
21768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
21798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
21808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
21818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
21828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
21838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
21848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
21858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   pixels = validate_pbo_teximage(width, height, depth,
2187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                  format, type, pixels, packing);
2188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
22168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
22173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
22183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2219d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2220d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
22223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
22238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22262aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
22278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
22288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
22318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
22328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
22338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
22348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
22358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
22368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
223789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2238a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2239a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2240a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2241a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2242a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2243a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2244a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
22458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
22508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
22518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
22548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
22558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
22568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
22578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
22588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
22598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2260a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2261a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
226289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
226389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
22648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
226589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
226689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
226789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
226889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
226989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
227089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
227189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
227289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
227389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
227489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
227589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
227689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
22774f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
22784f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
227989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
228089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
228189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
228289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
228389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
228489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
228589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
228689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
22877a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
22887a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
22897a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
22907a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
229189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
22924039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
229389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
22948f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
22958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
22968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
22978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
22988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22998f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
23008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
23018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
23068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
23078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
23108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
23118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
23128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
23138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
23148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
23158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
231789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2318a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2319a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2320a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2321a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2322a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2323a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2324a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2325a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
23268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
233089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
233189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2332e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2333e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
233489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
233589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
233689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
233789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
233889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
233989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
234089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2341e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
234289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2343a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2344a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2345a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2346a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2347a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2348a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2349a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2350e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2351e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2352e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
235389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
235489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
235589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
235689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
235789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
235889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
235989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
236089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
236189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
236289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
236389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
236489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
236589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
236689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
236789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
236889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
236989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
2370a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
237189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
237289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
237389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
237489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
237589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
237689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
237789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
23787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
23797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
23807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
23817a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
238289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
238389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
238489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
238589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
238689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
238789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
238889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                         texImage->IntFormat,
2389f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2390f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
239189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
239289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
239389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
239489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
239589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
239689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
239789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
239889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
239989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
24008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
24018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
24028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
24038f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
24048f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
24058f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
24068f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
240789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
240889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
240989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
241089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
241189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
241289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
241389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
241489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
241589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
241689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
241789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
241889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
241989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
242089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
242189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
242289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
242389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2424a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2425a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2426a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
2427a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2428a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2429a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2430a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2431a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
243289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
243389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
243489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
24353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
24363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
24373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
24389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
24399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
24403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
24413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
24429228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
24439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
24449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
24453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
24469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
24479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
24489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
2449c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
24509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
2451c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
24529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
24533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
24543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
24553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
24569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
24583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
24593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
24607c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
24629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2463f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
24649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2465f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
24669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2467f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
24689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2469f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
24703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
24713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
24723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
24733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
24743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
24759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
24773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
24783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
24797c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
24819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2482f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
24839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2484f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
24859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2486f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
24873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
24883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
24893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
24903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
24913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
24923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
24933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
24949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
24963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
24973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
24987c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
2500f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
25013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
25053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
25083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
25093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
25107c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2513f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2515f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
2519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
25208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
25238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
25248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
25257c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
25288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT16:
2532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
2535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
2536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
2537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
2540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
25438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
25448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
2545defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
25468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
2547defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
25488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
25518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
25528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
25537c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2556f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2558f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2560f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2562f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
25638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
25668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
2567a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
25688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
25718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
25728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
25737c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2576f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2578f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2580f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
25848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
2585defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
25868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
25898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
25908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
25917c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
25949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
25959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
25969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
25979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
25989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
25999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
26009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
26019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
26029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
26039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
26049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
260507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
260607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
260707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
26088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
26098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
2613defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
26148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26197c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
26229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
26239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
26249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
26259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
26269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
26279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
26289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
26299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
26309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
26319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
26329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
26339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
26349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
26359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
26369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
263707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
263807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
263907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
264007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
26418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
26428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
2646defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
26478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26527c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
26559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
26569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
26579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
26589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
26599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
26609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
26619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
26629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
26639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
26649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
26659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
26669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
26679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
26689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
26699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
267007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
267107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
267207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
267307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
26748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
26758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
2679defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
26808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
26838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
26848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
26857c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
26889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
26899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
26909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
26918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
26958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
26988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
26998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
27007c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
27039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
27049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
27059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
27069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
27079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
27089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
27099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
27109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
27119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
27129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
27139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
271407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
271507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
271607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
27178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
27188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
27228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
27238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
27248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
27258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
27288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
27298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
27307c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
27338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
2737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
2740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
2741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
2742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
2752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
2756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
2759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
2760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
2761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
2764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
2775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
2778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
2779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
2780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
2792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
2795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
2796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
2797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
2800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
2811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
2814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
2815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
2816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
2826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
2829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
2830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
2831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
2834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
2845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
2846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
2847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
2850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
2851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
2852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
2855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
2859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
2860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
2861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
2864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
2865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
2866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
2869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
2870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
2871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
2872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
2873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
28783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
28793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
28803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
28813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
28823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
28859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
28869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
28879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
28889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
28893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
28913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
28923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
28933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
28943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
28953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
28963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
28973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
28983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
29003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
29013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
29023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
29049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
29059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
29063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
29083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
29093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
29103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
29113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
29123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
29133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
29143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
29193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
29203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
29213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
29223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
29249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
29259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
29269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
29273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
29283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
29293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
29303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
2931462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
29323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
29343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
29353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
29363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
29373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
29383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
29393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
29403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
29429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
29439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
29443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
29453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
29463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
29473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
29503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
29513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
29523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
29533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
29543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
29553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
29563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
29573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
29583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
29593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
29603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
29613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
29623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
29633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
29649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
29659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
29669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
29679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
29683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
29699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
29703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
29713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
29729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
29733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
29743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
29759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
29769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
29779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
29789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
29799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
29809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
29819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
29829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
29839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
29849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
29859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
29869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
29879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
29889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
29899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
29909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
29919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
29929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
29939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
29949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
29959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
29963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
29973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
30033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
30043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
30053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
30063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
30073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
30099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
30109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
30119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
30129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
30139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
30149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
30153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
30169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
30179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
30189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
30193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30205c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
30215c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
30229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
30239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
30249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
30259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
30269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
30279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
30289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
30293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
30339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
30349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
30369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
30373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
30399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
30403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
30429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
30433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
30459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
30469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
30479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
30489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
30499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
30509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
30513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
30534e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
30549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
30559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
30569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
30589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
30599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
30619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
30629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
30639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
30649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
30659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
30669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
30679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
30689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
30709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
30719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
30729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
30739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
30749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
30759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
30779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
30789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
30799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
30809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
30819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
30829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
30839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
30849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
30859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
30869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
30879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
30889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
30899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
30909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
30919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
30923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
30963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
30979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
30999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
31009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
31019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
31029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
31039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
31049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
31069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
31079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
31089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
31099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
31109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
31119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
31129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
31139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
31149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
31169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
31179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
31189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
31219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
31239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
31259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
31289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
31309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
31329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
31359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
31379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
31399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
31419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
31429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
31439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
31449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
31459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
31469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
31479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
31489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
31509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
31519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
31529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
31539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
31559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
31579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
31599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
31609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
31629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
31649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
31669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
31679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
31699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
31739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
31749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
31759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
31769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
31773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
31783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
31813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
31823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
31833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
31843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
31853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3186d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
31873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
31883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
31893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
31902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
31912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3192b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3193b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3194ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
31953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
319718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
31982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
31993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3200ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3201ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
32023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
32042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
32052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3206d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3207d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
32082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
32092ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
32112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (srcImage->Format == GL_RGB) {
32132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
32142ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
32152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else if (srcImage->Format == GL_RGBA) {
32172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
32182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
32192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
32212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps");
32222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
32262ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE)
32272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
32282ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
3229f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      srcData = (GLubyte *) MALLOC(size);
32302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
32312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
32322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3234f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      dstData = (GLubyte *) MALLOC(size / 2);  /* 1/4 would probably be OK */
32352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
32362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
32372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         FREE((void *) srcData);
32382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
32422ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
32432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3244d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
32452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
32464f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
32472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
324889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
324989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
325089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
32512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
32522ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
32532ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
32542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
325589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
32568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3257cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
32589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
32593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
32603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
32613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
32623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
32633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
32643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
326589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
32663ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
32673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
32683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
32693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
32703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
32713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
32723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
32743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
32753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
32763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
32783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
32793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
32813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
32823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
32843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
32853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
32873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
32883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
32903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
32913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
32923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
32943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
32953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
32963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
329789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
329889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE((void *) srcData);
329989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE(dstData);
330089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
33013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
33023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3304d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3305a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3306d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3307a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3308a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3309d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
33103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3311d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3312d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
3313d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul         MESA_PBUFFER_FREE(dstImage->Data);
3314d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3315d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3316e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
331789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                 dstDepth, border, srcImage->IntFormat);
3318d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3319d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
33204f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
33214f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
3322d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
33234f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
33244f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3325d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
332689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
332789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
332889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
332989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
333089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
333189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize);
333289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
333389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
333489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
333589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
33362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
333789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
333889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
333989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
334089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
334189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
334289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
334389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
334489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                             * bytesPerTexel);
334589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
334689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
334789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
334889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
334989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
335089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3351d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3352d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3353d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3354d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3355d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3356d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
335789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
33582ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
335989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
336089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
336189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
336289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
336389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
336489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
336589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
336689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
336789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
336889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
33692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
337089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
337189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
337289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
337389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
33742ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
337589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
337689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
337789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
337889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
337989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
338089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
338189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
338289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
338389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3384d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
338589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
338689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
338789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
33882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
33892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
33902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
33912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                                          dstWidth);
33922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
33938f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format,
33948f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
33958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
33968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
33978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
33988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
33998f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
34008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
34018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
340289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
340389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
340489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
340589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
340689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
340789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3408d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
34093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
341080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
341180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
341280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
341380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
341480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
341580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
341680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
341780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
341880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
34191cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
34201cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
34211cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
34221cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
34231cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
34241cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
34251cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
342680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
342780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
342880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
342980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
343080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
343180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
343280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
343380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
34341cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
343580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
343680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
343780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
343880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
343980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
344080fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
344180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
344280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
344380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
34441cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
344580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
34461cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
344780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
344880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
344980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
345080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
345180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
345280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
345380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
345480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
345580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
345680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
34571cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
345880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
345980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
346080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
346180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
346280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
346380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
346480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
346580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
346680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
346780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
346880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
346980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
347080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
347180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
347280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
347380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
347480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
347580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
347680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
347780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
347880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
347980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
348080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
348180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
348280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
348380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
348433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
348533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
348633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
348733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
348833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
348933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
349033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
349133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
349233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
349333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
349433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
349533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
349633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
349733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
349833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
349933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
350033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
350133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
3502701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
350333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
350433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
350533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
350633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
350733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
350833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
350933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
351033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
351133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
351233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
351333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
351433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
351533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
351633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
351733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
3518