texstore.c revision c0ebc4931a003b7b14e92c3b537b6ba76259507c
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
3c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Version:  6.3
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul#include "bufferobj.h"
56e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
6289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h"
63371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
68f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic const GLint ZERO = 1000, ONE = 1001;
69f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
70f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
71f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the
72f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components.
73f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that.
74f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  the logical format of the texture
75f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the final texture format
76f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return map[4]  the four mapping values
77f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
78f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
79f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
80f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                          GLint map[4])
81f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
82f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* compute mapping from dest components back to src components */
8313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   switch (textureBaseFormat) {
8413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGB:
8513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGBA:
8613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
8713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
8813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
8913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
9013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = ONE;
9113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
9213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
9313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
9413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = ZERO;
95f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         map[3] = 0;
9613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
9713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
9813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
9913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
10013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = 0;
10113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
10213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE_ALPHA:
10313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
10413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
10513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = 1;
10613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
10713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_RGB:
10813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
10913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
11013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 1;
11113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[2] = 2;
11213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = ONE;
11313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
11413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
11513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
11613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = map[3] = 0;
11713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_LUMINANCE_ALPHA:
12013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
12113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
12213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
12313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = ONE;
12413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
12613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = ZERO;
12713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
12813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
13013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
13113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
13213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
13313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
13413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
13513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = 0;
13613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components.
143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat.
163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat *
165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims,
166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum logicalBaseFormat,
167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum textureBaseFormat,
168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum srcFormat, GLenum srcType,
170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const GLvoid *srcAddr,
171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const struct gl_pixelstore_attrib *srcPacking)
172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLfloat *tempImage;
175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY ||
184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_COLOR_INDEX ||
185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_DEPTH_COMPONENT);
186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY ||
193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_COLOR_INDEX ||
194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_DEPTH_COMPONENT);
195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* conventional color image */
197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* need image convolution */
202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint preConvTransferOps
203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint postConvTransferOps
205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint convWidth, convHeight;
208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage;
209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* pre-convolution image buffer (3D) */
211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* post-convolution image buffer (2D) */
217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage) {
220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* loop over 3D image slices */
225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* unpack and do transfer ops up to convolution */
229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
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/**
1792c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
1793c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
1794c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
1795c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * The caller _must_ call unmap_teximage_pbo() too!
17967a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
17977a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
1798c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulvalidate_pbo_teximage(GLcontext *ctx,
1799c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      GLsizei width, GLsizei height, GLsizei depth,
1800c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      GLenum format, GLenum type, const GLvoid *pixels,
1801c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      const struct gl_pixelstore_attrib *unpack,
1802c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                      const char *funcName)
18037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
1804c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
1805c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
18067a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
18077a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
18087a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18097a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1810c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!_mesa_validate_pbo_access(unpack, width, height, depth, format,
1811c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  type, pixels)) {
1812c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
1813c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
18147a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1815c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1816c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   buf = ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1817c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                               GL_READ_ONLY_ARB, unpack->BufferObj);
1818c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
1819c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
1820c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
1821c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1822c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1823c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
18247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
1828c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
1829c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
1830c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
1831c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
1832c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * The caller _must_ call unmap_teximage_pbo() too!
18337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
18347a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
1835c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulvalidate_pbo_compressed_teximage(GLcontext *ctx,
1836c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
1837c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
1838c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
18397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
1840c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
1841c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
18427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
18437a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
18447a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
18457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1846c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
1847c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul       (const GLubyte *) packing->BufferObj->Size) {
1848c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
1849c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
1850c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
1851c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1852c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1853c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   buf = ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1854c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                               GL_READ_ONLY_ARB, packing->BufferObj);
1855c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
1856c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
1857c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
18587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
1859c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1860c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
18617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
18627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
18637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
1864c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
1865c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
1866c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
1867c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
1868c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulstatic void
1869c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paulunmap_teximage_pbo(GLcontext *ctx, const struct gl_pixelstore_attrib *unpack)
1870c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
1871c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
1872c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
1873c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
1874c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
1875c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
1876c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
187789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
18787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
187989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
1880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
18818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
18828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
18838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
18848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
18858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
18868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
18878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
18888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
18898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
18908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
18918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
1893a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
18948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
18968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
18978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
18988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
19007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                         format, type);
19037d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
19044f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
19054f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
19068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
190889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
190989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
191089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
1911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
1912aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
19137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
19147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
19157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
19167d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
19178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1918c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, 1, 1, format, type, pixels,
1919c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexImage1D");
192089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
192189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
192289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
1925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
1928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
1933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1938f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
193989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
194089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
194189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
194289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
194389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
19443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
1945c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
1946c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
19478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
195189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
195289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
1953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
1954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special memory allocation needs
1955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Unusual row/image strides
1956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
19578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
19608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
19618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
19628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
19638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
19648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
19658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
19668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
1968e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
1969a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
19708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
19728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
19738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
19748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
19758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
19777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
19787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
19797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
19807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
19814f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
19824f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
19832c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
19842c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
19858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
198789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
198889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
198989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
199089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
1991aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
19927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
19937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
19947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
19957d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
19968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
1997c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, height, 1, format, type, pixels,
1998c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexImage2D");
199989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
200089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
200189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
2004f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2005f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2006f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
2007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
20099c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
2010f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2011f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
2013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2015f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2018f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2019f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2021f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2022f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2023f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
202489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
202589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
202689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
202789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
202889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
20293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2030c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2031c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
20328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
203789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
203889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
20398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
20428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
20438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
20448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
20458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
20468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
20478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
20488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2049e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2050a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
20518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
20537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
20547d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
20557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
20567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
20574f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
20584f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
20592c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2060197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
20618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
206389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
206489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
206589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
206689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
2067aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
20687d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
20697d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
20707d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
20717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
20728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2073c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, height, depth, format, type,
2074c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  pixels, packing, "glTexImage3D");
207589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
207689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
207789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
207889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
2079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
2084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
2085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
2088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
2089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2102f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
210389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
210489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
210589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
210689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
210789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
21083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2109c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2110c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
21118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
211789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
211889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
21198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
21228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
21238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
21248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
21258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
21268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
21278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2128c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, 1, 1, format, type, pixels,
2129c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexSubImage1D");
21307a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
21317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21327a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
2138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
21483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
21493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
21503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2151d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2152d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
21533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
21543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2155c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2156c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
21578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
216089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
216289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
216389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
21648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
21678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
21688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
21698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
21708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
21718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
21728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
21738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2174c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, height, 1, format, type, pixels,
2175c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  packing, "glTexSubImage2D");
21767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
21777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
2181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
2191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
22013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
22023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
22033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2204d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2205d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
22073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2208c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2209c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
22108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
22148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
221589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
22168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
22198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
22208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
22218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
22228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
22238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
22248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
22258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2226c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   pixels = validate_pbo_teximage(ctx, width, height, depth, format, type,
2227c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                  pixels, packing, "glTexSubImage3D");
2228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
22558f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
22563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
22573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2258d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2259d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
22613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2262c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2263c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, packing);
22648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22672aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
22688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
22698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
22728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
22738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
22748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
22758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
22768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
22778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
227889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2279a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2280a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2281a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2282a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2283a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2284a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2285a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
22868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
22878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
22908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
22918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
22928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
22958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
22968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
22978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
22988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
22998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2301a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2302a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
230389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
230489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
23058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
230689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
230789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
230889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
230989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
231089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
231189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
231289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
231389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
231489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
231589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
231689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
231789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
23184f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
23194f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
232089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
232189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
232289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
232389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
232489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
232589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
232689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
232789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2328c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
2329c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                           "glCompressedTexImage2D");
23307a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
23317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
23327a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
233389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
23344039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
233589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
23368f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
23378f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
23388f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
23398f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
23408f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
23418f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
23428f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2343c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2344c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, &ctx->Unpack);
23458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
23508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
23518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
23548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
23558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
23568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
23578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
23588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
23598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
23608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
236189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2362a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2363a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2364a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2365a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2366a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2367a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2368a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2369a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
23708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
237489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
237589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2376e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2377e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
237889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
237989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
238089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
238189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
238289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
238389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
238489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2385e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
238689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2387a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2388a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2389a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2390a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2391a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2392a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2393a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2394e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2395e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2396e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
239789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
239889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
239989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
240089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
240189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
240289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
240389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
240489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
240589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
240689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
240789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
240889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
240989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
241089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
241189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
241289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
241389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
2414a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
241589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
241689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
241789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
241889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
241989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
242089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
242189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2422c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
2423c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                           "glCompressedTexSubImage2D");
24247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
24257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
24267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
242789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
242889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
242989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
243089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
243189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
243289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
243389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                         texImage->IntFormat,
2434f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2435f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
243689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
243789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
243889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
243989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
244089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
244189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
244289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
244389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
244489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
24458f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
24468f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
24478f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
24488f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
24498f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
24508f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
24518f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2452c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2453c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   unmap_teximage_pbo(ctx, &ctx->Unpack);
245489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
245589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
245689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
245789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
245889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
245989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
246089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
246189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
246289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
246389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
246489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
246589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
246689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
246789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
246889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
246989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
247089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2471a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2472a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2473a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
2474a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2475a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2476a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2477a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2478a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
247989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
248089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
248189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
24823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
24833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
24843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
24859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
24869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
24873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
24883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
24899228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
24909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
24919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
24923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
24939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
24949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
24959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
2496c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
24979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
2498c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
24999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
25003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
25013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
25023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
25053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
25063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
25077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2510f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2512f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2514f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2516f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
25173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
25213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
25243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
25253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
25267c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2529f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2531f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2533f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
25343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
25383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
25393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
25403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
25433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
25443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
25457c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
2547f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
25483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
25513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
25523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
25539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
25553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
25563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
25577c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2560f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
25619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2562f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
25633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
25643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
25653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
2566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
25678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
25708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
25718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
25727c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
25758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT16:
2579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
2582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
2583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
2584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
2587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
25908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
25918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
2592defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
25938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
2594defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
25958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
25988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
25998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
26007c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2603f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
26049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2605f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
26069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2607f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
26089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2609f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
26108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
2614a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
26158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
26188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
26198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
26207c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2623f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
26249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2625f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
26269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2627f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
26288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
2632defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
26338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26387c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
26419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
26429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
26439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
26449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
26459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
26469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
26479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
26489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
26499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
26509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
26519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
265207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
265307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
265407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
26558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
26568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
2660defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
26618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26667c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
26679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
26689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
26699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
26709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
26719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
26729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
26739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
26749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
26759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
26769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
26779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
26789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
26799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
26809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
26819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
26829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
26839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
268407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
268507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
268607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
268707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
26888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
26898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
26908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
26918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
26928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
2693defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
26948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
26959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
26968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
26978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
26988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
26997c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
27029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
27039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
27049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
27059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
27069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
27079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
27089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
27099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
27109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
27119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
27129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
27139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
27149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
27159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
27169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
271707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
271807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
271907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
272007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
27218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
27228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
2726defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
27278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
27308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
27318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
27327c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
27359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
27369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
27379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
27388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
27428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
27458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
27468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
27477c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
27509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
27519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
27529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
27539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
27549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
27559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
27569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
27579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
27589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
27599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
27609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
276107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
276207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
276307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
27648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
27658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
27688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
27698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
27708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
27718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
27728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
27739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
27748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
27758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
27768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
27777c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
27789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
27799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
27808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
27818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
27828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
2784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
2787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
2788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
2789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
2799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
2803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
2806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
2807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
2808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
2811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
2822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
2825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
2826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
2827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
2839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
2842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
2843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
2844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
2847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
2858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
2861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
2862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
2863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
2873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
2876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
2877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
2878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
2881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
2892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
2893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
2894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
2897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
2898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
2899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
2902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
2906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
2907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
2908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
2911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
2912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
2913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
2916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
2917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
2918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
2919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
2920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
29253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
29263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
29273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
29329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
29339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
29349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
29359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
29363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
29383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
29393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
29403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
29413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
29433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
29443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
29453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
29473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
29483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
29493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
29519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
29529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
29533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
29553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
29563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
29573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
29583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
29593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
29603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
29613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
29663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
29673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
29683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
29693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
29719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
29729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
29739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
29743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
29753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
29763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
29773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
2978462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
29793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
29813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
29823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
29833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
29843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
29853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
29863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
29873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
29899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
29909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
29913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
29923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
29933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
29943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
29953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
29973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
29983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
29993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
30003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
30013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
30023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
30033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
30043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
30053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
30063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
30073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
30083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
30093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
30103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
30119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
30129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
30139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
30149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
30153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
30169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
30173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
30183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
30199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
30203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
30213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
30229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
30239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
30249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
30259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
30269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
30279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
30289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
30299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
30309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
30319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
30329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
30339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
30349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
30359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
30369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
30379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
30389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
30399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
30409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
30419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
30429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
30433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
30463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
30503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
30513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
30523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
30533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
30543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
30569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
30579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
30589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
30599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
30619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
30623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
30639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
30649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
30659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
30663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30675c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
30685c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
30699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
30709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
30719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
30729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
30739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
30749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
30759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
30763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
30783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
30809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
30819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
30839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
30869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
30899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
30903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
30929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
30939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
30949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
30959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
30969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
30979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
30983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
31004e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
31019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
31029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
31039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
31069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
31079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
31089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
31099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
31109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
31119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
31129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
31139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
31149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
31159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
31179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
31189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
31199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
31209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
31219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
31229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
31249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
31259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
31269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
31279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
31289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
31299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
31309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
31319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
31329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
31339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
31349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
31359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
31369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
31379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
31389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
31393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
31403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
31413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
31433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
31449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
31469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
31479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
31489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
31499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
31509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
31519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
31529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
31539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
31549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
31559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
31569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
31579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
31589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
31599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
31609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
31619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
31639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
31649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
31659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
31689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
31709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
31729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
31759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
31779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
31799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
31829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
31839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
31849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
31859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
31869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
31879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
31889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
31899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
31909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
31919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
31929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
31939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
31949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
31959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
31969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
31979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
31989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
31999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
32029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
32049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
32069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
32099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
32119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
32139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
32159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
32169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
32179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
32189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
32199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
32209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
32219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
32229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
32239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
32243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
32253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
32283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
32293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
32303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
32313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
32323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3233d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
32343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
32353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
32363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
32372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
32382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3239b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3240b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3241ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
32423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
324418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
32452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
32463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3247ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3248ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
32493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
32502ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
32512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
32522ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3253d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3254d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
32552ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
32562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32572ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
32582ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32592ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (srcImage->Format == GL_RGB) {
32602ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
32612ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
32622ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32632ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else if (srcImage->Format == GL_RGBA) {
32642ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
32652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
32662ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32672ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
32682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps");
32692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32722ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
32732ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE)
32742ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
32752ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
3276f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      srcData = (GLubyte *) MALLOC(size);
32772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
32782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
32792ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32802ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3281f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      dstData = (GLubyte *) MALLOC(size / 2);  /* 1/4 would probably be OK */
32822ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
32832ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
32842ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         FREE((void *) srcData);
32852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
32862ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
32872ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
32882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
32892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
32902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3291d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
32922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
32934f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
32942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
329589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
329689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
329789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
32982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
32992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
33002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
33012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
330289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
33038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3304cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
33059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
33063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
33073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
33083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
33093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
33103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
33113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
331289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
33133ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
33143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
33153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
33163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
33173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
33183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
33193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
33213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
33223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
33233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
33263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
33283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
33293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
33323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
33343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
33353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
33373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
33383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
33413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
33423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
33433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
334489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
334589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE((void *) srcData);
334689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE(dstData);
334789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
33483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
33493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
33503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3351d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3352a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3353d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3354a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3355a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3356d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
33573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3358d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3359d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
3360d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul         MESA_PBUFFER_FREE(dstImage->Data);
3361d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3362d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3363e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
336489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                 dstDepth, border, srcImage->IntFormat);
3365d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3366d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
33674f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
33684f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
3369d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
33704f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
33714f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3372d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
337389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
337489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
337589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
337689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
337789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
337889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize);
337989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
338089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
338189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
338289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
33832ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
338489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
338589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
338689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
338789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
338889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
338989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
339089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
339189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                             * bytesPerTexel);
339289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
339389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
339489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
339589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
339689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
339789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3398d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3399d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3400d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3401d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3402d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3403d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
340489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
34052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
340689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
340789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
340889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
340989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
341089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
341189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
341289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
341389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
341489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
341589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
34162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
341789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
341889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
341989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
342089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
34212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
342289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
342389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
342489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
342589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
342689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
342789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
342889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
342989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
343089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3431d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
343289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
343389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
343489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
34352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
34362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
34372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
34382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                                          dstWidth);
34392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
34408f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format,
34418f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
34428f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
34438f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
34448f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
34458f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
34468f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
34478f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
34488f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
344989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
345089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
345189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
345289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
345389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
345489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3455d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
34563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
345780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
345880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
345980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
346080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
346180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
346280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
346380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
346480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
346580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
34661cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
34671cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
34681cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
34691cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
34701cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
34711cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
34721cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
347380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
347480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
347580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
347680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
347780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
347880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
347980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
348080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
34811cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
348280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
348380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
348480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
348580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
348680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
348780fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
348880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
348980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
349080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
34911cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
349280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
34931cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
349480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
349580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
349680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
349780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
349880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
349980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
350080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
350180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
350280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
350380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
35041cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
350580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
350680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
350780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
350880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
350980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
351080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
351180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
351280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
351380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
351480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
351580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
351680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
351780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
351880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
351980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
352080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
352180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
352280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
352380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
352480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
352580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
352680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
352780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
352880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
352980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
353080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
353133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
353233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
353333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
353433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
353533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
353633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
353733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
353833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
353933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
354033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
354133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
354233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
354333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
354433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
354533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
354633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
354733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
354833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
3549701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
355033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
355133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
355233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
355333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
355433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
355533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
355633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
355733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
355833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
355933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
356033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
356133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
356233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
356333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
356433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
3565