texstore.c revision 0a4be7036864efa6b30d78e0aac449d34b812c13
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
3a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul * Version:  6.5.1
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
5ef8653a83800bc4b8e116e03ad52604097224378Brian Paul * Copyright (C) 1999-2006  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
6871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellstatic const GLint ZERO = 4, ONE = 5;
6971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
7071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellstatic GLboolean can_swizzle(GLenum logicalBaseFormat)
7171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
7271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   switch (logicalBaseFormat) {
7371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_RGBA:
7471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_RGB:
7571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_LUMINANCE_ALPHA:
7671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_INTENSITY:
7771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_ALPHA:
7871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_LUMINANCE:
7971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      return GL_TRUE;
8071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   default:
8171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      return GL_FALSE;
8271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
8371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
8471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
85f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
86f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
87f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the
88f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components.
89f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that.
90f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  the logical format of the texture
91f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the final texture format
92f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return map[4]  the four mapping values
93f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
94f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
95f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
9671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                          GLubyte map[6])
97f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
9871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   map[ZERO] = ZERO;
9971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   map[ONE] = ONE;
10071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* compute mapping from dest components back to src components */
10213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   switch (textureBaseFormat) {
10313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGB:
10413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul   case GL_RGBA:
10513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
10613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
10713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
10813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
10913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = ONE;
11013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
11113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
11213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
11313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = ZERO;
114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         map[3] = 0;
11513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
11613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
11713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
11813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         if (textureBaseFormat == GL_RGBA)
11913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul            map[3] = 0;
12013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE_ALPHA:
12213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
12313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = 0;
12413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = 1;
12513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
12613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_RGB:
12713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         ASSERT(textureBaseFormat == GL_RGBA);
12813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
12913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 1;
13013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[2] = 2;
13113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[3] = ONE;
13213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
13371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      case GL_RGBA:
13471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         ASSERT(textureBaseFormat == GL_RGBA);
13571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         map[0] = 0;
13671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         map[1] = 1;
13771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         map[2] = 2;
13871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         map[3] = 3;
13971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         break;
14013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
14113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
14213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = map[2] = map[3] = 0;
14313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_LUMINANCE_ALPHA:
14613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      switch (logicalBaseFormat) {
14713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_LUMINANCE:
14813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
14913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = ONE;
15013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
15113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_ALPHA:
15213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = ZERO;
15313ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
15413ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
15513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      case GL_INTENSITY:
15613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = 0;
15713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[1] = 0;
15813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         break;
15913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      default:
16013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         _mesa_problem(NULL, "Unexpected logicalBaseFormat");
16113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul         map[0] = map[1] = 0;
16213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      }
16371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
16471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   default:
16571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_problem(NULL, "Unexpected logicalBaseFormat");
16671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      map[0] = map[1] = 0;
16771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
16871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components.
174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat.
194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat *
196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims,
197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum logicalBaseFormat,
198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum textureBaseFormat,
199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum srcFormat, GLenum srcType,
201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const GLvoid *srcAddr,
202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const struct gl_pixelstore_attrib *srcPacking)
203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLfloat *tempImage;
206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY ||
215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_COLOR_INDEX ||
216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_DEPTH_COMPONENT);
217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY ||
224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_COLOR_INDEX ||
225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_DEPTH_COMPONENT);
226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* conventional color image */
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* need image convolution */
233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint preConvTransferOps
234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint postConvTransferOps
236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint convWidth, convHeight;
239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage;
240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* pre-convolution image buffer (3D) */
242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* post-convolution image buffer (2D) */
248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage) {
251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* loop over 3D image slices */
256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* unpack and do transfer ops up to convolution */
260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
26160909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcAddr, srcWidth, srcHeight,
263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcFormat, srcType, img, row, 0);
264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcFormat, srcType, src,
266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking,
267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          preConvTransferOps);
268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * 4;
269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do convolution */
272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convWidth = srcWidth;
275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convHeight = srcHeight;
276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (dims == 1) {
277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          src, convImage);
284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               else {
286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           src, convImage);
289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do post-convolution transfer and pack into tempImage */
294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
2952b012578ee519561365640e23272b71898378c45Brian Paul            const GLint logComponents
2962b012578ee519561365640e23272b71898378c45Brian Paul               = _mesa_components_in_format(logicalBaseFormat);
297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLfloat *src = convImage;
298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (row = 0; row < convHeight; row++) {
300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_pack_rgba_span_float(ctx, convWidth,
301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          (const GLfloat (*)[4]) src,
302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          logicalBaseFormat, GL_FLOAT,
303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, &ctx->DefaultPacking,
304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          postConvTransferOps);
305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += convWidth * 4;
3062b012578ee519561365640e23272b71898378c45Brian Paul               dst += convWidth * logComponents;
307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      } /* loop over 3D image slices */
310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(convImage);
312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* might need these below */
314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcWidth = convWidth;
315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcHeight = convHeight;
316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* no convolution */
319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint components = _mesa_components_in_format(logicalBaseFormat);
320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *dst;
323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * components * sizeof(GLfloat));
327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      dst = tempImage;
331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *src
33360909388ab136d849d99eab49e782a53772a618fBrian Paul            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcWidth, srcHeight,
335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcFormat, srcType,
336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    img, 0, 0);
337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, srcFormat, srcType, src,
340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking, transferOps);
341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * components;
342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcStride;
343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* more work */
349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *newImage;
352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
35371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte map[6];
354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
35513ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
35613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
35713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLfloat));
366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0.0F;
380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 1.0F;
382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLchan components.
397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLchan.
417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
4188f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian PaulGLchan *
4198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
4208f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum logicalBaseFormat,
4218f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum textureBaseFormat,
4228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
4238f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum srcFormat, GLenum srcType,
4248f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const GLvoid *srcAddr,
4258f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const struct gl_pixelstore_attrib *srcPacking)
426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(logicalBaseFormat);
429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLboolean freeSrcImage = GL_FALSE;
430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint img, row;
431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLchan *tempImage, *dst;
432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY);
441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY);
448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* get convolved image */
453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage = make_temp_float_image(ctx, dims,
454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcAddr, srcPacking);
459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage)
460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* the convolved image is our new source image */
462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcAddr = convImage;
463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcFormat = logicalBaseFormat;
464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcType = GL_FLOAT;
465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcPacking = &ctx->DefaultPacking;
466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      transferOps = 0;
468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      freeSrcImage = GL_TRUE;
469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* unpack and transfer the source image */
472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       * components * sizeof(GLchan));
474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!tempImage)
475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return NULL;
476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   dst = tempImage;
478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   for (img = 0; img < srcDepth; img++) {
479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcWidth, srcFormat,
481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcType);
482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLubyte *src
48360909388ab136d849d99eab49e782a53772a618fBrian Paul         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight,
485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 img, 0, 0);
487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (row = 0; row < srcHeight; row++) {
4889c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
4899c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      srcFormat, srcType, src, srcPacking,
4909c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      transferOps);
491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dst += srcWidth * components;
492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         src += srcStride;
493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* If we made a temporary image for convolution, free it here */
497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (freeSrcImage) {
498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) srcAddr);
499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one more conversion step */
503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *newImage;
506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
50771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte map[6];
508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
50913ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
51013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
51113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
5192dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul                                         * texComponents * sizeof(GLchan));
520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0;
534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = CHAN_MAX;
536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
549c039af165d5919008c6df599795951f85dea164dBrian Paul/**
550c039af165d5919008c6df599795951f85dea164dBrian Paul * Copy GLubyte pixels from <src> to <dst> with swizzling.
551c039af165d5919008c6df599795951f85dea164dBrian Paul * \param dst  destination pixels
552c039af165d5919008c6df599795951f85dea164dBrian Paul * \param dstComponents  number of color components in destination pixels
553c039af165d5919008c6df599795951f85dea164dBrian Paul * \param src  source pixels
554c039af165d5919008c6df599795951f85dea164dBrian Paul * \param srcComponents  number of color components in source pixels
555c039af165d5919008c6df599795951f85dea164dBrian Paul * \param map  the swizzle mapping
556c039af165d5919008c6df599795951f85dea164dBrian Paul * \param count  number of pixels to copy/swizzle.
557c039af165d5919008c6df599795951f85dea164dBrian Paul */
558c039af165d5919008c6df599795951f85dea164dBrian Paulstatic void
559c039af165d5919008c6df599795951f85dea164dBrian Paulswizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
560c039af165d5919008c6df599795951f85dea164dBrian Paul             GLuint srcComponents, const GLubyte *map, GLuint count)
56171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
56271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLubyte tmp[8];
563edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul   GLuint i;
56471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
56571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   tmp[ZERO] = 0x0;
56671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   tmp[ONE] = 0xff;
56771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
56871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   switch (dstComponents) {
56971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 4:
57071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
57171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
57271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
57371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
57471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
57571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[2] = tmp[map[2]];
57671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[3] = tmp[map[3]];
57771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 4;
57871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
57971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
58071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 3:
58171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
58271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
58371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
58471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
58571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
58671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[2] = tmp[map[2]];
58771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 3;
58871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
58971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
59071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 2:
59171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
59271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
59371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
59471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
59571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
59671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 2;
59771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
59871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
59971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
60071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
60171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
60271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
603c039af165d5919008c6df599795951f85dea164dBrian Paul/**
604c039af165d5919008c6df599795951f85dea164dBrian Paul * Transfer a GLubyte texture image with component swizzling.
605c039af165d5919008c6df599795951f85dea164dBrian Paul */
60671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellstatic void
60771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_swizzle_ubyte_image(GLcontext *ctx,
60871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLuint dimensions,
60971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLenum srcFormat,
61071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const GLubyte *dstmap, GLint dstComponents,
61171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
61271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLvoid *dstAddr,
61371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
614b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul			  GLint dstRowStride,
615b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                          const GLuint *dstImageOffsets,
61671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
61771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint srcWidth, GLint srcHeight, GLint srcDepth,
61871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const GLvoid *srcAddr,
61971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const struct gl_pixelstore_attrib *srcPacking )
62071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
62171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint srcComponents = _mesa_components_in_format(srcFormat);
62271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLubyte srcmap[6], map[4];
62371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint i;
62471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
625c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcRowStride =
626c039af165d5919008c6df599795951f85dea164dBrian Paul      _mesa_image_row_stride(srcPacking, srcWidth,
627c039af165d5919008c6df599795951f85dea164dBrian Paul                             srcFormat, GL_UNSIGNED_BYTE);
628c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcImageStride
629c039af165d5919008c6df599795951f85dea164dBrian Paul      = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
630c039af165d5919008c6df599795951f85dea164dBrian Paul                                 GL_UNSIGNED_BYTE);
631c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLubyte *srcImage
632c039af165d5919008c6df599795951f85dea164dBrian Paul      = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
633c039af165d5919008c6df599795951f85dea164dBrian Paul                                              srcWidth, srcHeight, srcFormat,
634c039af165d5919008c6df599795951f85dea164dBrian Paul                                              GL_UNSIGNED_BYTE, 0, 0, 0);
63571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
636edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul   (void) ctx;
637edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul
63871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   compute_component_mapping(srcFormat, GL_RGBA, srcmap);
63971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   for (i = 0; i < 4; i++)
64171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      map[i] = srcmap[dstmap[i]];
64271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   if (srcRowStride == srcWidth * srcComponents &&
644b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul       dimensions < 3) {
645b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      /* 1 and 2D images only */
646b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
647b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstYoffset * dstRowStride
648b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstXoffset * dstComponents;
64971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
650b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul		   srcWidth * srcHeight);
65171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
65271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else {
65371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLint img, row;
65471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
65571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLubyte *srcRow = srcImage;
656b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
657b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstComponents
658b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
659b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstComponents;
66071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
66171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
66271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
66371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
66471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
66571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         srcImage += srcImageStride;
66671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
66771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
66871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
66971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
67071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
67717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwellmemcpy_texture(GLcontext *ctx,
67817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell	       GLuint dimensions,
67960909388ab136d849d99eab49e782a53772a618fBrian Paul               const struct gl_texture_format *dstFormat,
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
682b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               GLint dstRowStride,
683b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               const GLuint *dstImageOffsets,
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
69360909388ab136d849d99eab49e782a53772a618fBrian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
69460909388ab136d849d99eab49e782a53772a618fBrian Paul        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
696b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
697b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#if 0
698b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* XXX update/re-enable for dstImageOffsets array */
699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
71217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
714b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   else
715b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   {
716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
72117bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
729b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#endif
730b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
731b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   GLint img, row;
732b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   for (img = 0; img < srcDepth; img++) {
733b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLubyte *srcRow = srcImage;
734b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLubyte *dstRow = (GLubyte *) dstAddr
735b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
736b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstYoffset * dstRowStride
737b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstXoffset * dstFormat->TexelBytes;
738b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      for (row = 0; row < srcHeight; row++) {
739b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
740b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRow += dstRowStride;
741b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         srcRow += srcRowStride;
742b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      }
743b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      srcImage += srcImageStride;
744b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   }
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
760b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba(TEXSTORE_PARAMS)
761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
78317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
78460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
785b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
786b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
796b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
798b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLchan *dstImage = (GLchan *)
799b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            ((GLubyte *) dstAddr
800b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
801b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstYoffset * dstRowStride
802b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstXoffset * dstFormat->TexelBytes);
803b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
80660909388ab136d849d99eab49e782a53772a618fBrian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
80760909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
815edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul            dstRow += dstRowStride / sizeof(GLchan);
816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
8228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
8299c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
8349c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
836b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
837b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
838b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
839b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
854a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul * Store a 32-bit integer depth component texture image.
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
857b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z32(TEXSTORE_PARAMS)
858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
859a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = (GLfloat) 0xffffffff;
860a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
861a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z32);
862a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
866a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
867a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
868a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul       srcType == GL_UNSIGNED_INT) {
869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
87017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
87160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
872b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
873b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
881b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
882b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
883b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
884b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
88660909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
8881ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
889a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
890a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    depthScale, srcType, src, srcPacking);
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
898b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#define STRIDE_3D 0
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
901a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
904b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z16(TEXSTORE_PARAMS)
905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
906a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = 65535.0f;
907a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
908a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z16);
909a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
915a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
91717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
91860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
919b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
920b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
9261ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul      GLint img, row;
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
928b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
929b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
930b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
931b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
93360909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
935a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
9361ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
937a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_SHORT, dst16, depthScale,
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
948defb035b6cf03c555318d9dd48864242ed036f39Brian Paul * Store an rgb565 or rgb565_rev texture image.
949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
951b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb565(TEXSTORE_PARAMS)
952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
953defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
954defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgb565_rev);
955a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 2);
956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
959defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgb565 &&
960a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
961a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
962a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
96417bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
96560909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
966b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
967b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
971a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
972a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
973a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
974a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
975a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
976a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
977a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
978a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
979a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
980a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
98160909388ab136d849d99eab49e782a53772a618fBrian Paul         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
982a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
983a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
984a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstYoffset * dstRowStride
985a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstXoffset * dstFormat->TexelBytes;
986a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint row, col;
987a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (row = 0; row < srcHeight; row++) {
988a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLubyte *srcUB = (const GLubyte *) src;
989a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLushort *dstUS = (GLushort *) dst;
990defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         /* check for byteswapped format */
991f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         if (dstFormat == &_mesa_texformat_rgb565) {
992f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
993f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
994f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
995f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
996f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         }
997f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         else {
998f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
999f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1000f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
1001f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1002defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         }
1003a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dst += dstRowStride;
1004a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         src += srcRowStride;
1005a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1006a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1009a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1010a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1011a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1012a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1013a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1014a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1015a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1017a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1018a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1019a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1021b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1022b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1023b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1024b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1026a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
1027defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
1028f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
1029f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1030f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1031f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
1032f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
1033f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1034f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1035f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1036f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1037f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1038f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1039f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
1040f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
1041f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1042f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1054b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
105671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLuint ui = 1;
105771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLubyte littleEndian = *((const GLubyte *) &ui);
105871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
105971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   (void)littleEndian;
1060defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
1061defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1066defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1068defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1069defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
1070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
107117bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
107260909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1073b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1074b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
107871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell#if 0
1079b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* broken? */
108071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
108171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    !srcPacking->SwapBytes &&
108271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
108371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_rgba8888 &&
108471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    littleEndian &&
1085ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    /* Three texture formats involved: srcFormat,
1086ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * baseInternalFormat and destFormat (GL_RGBA). Only two
1087ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * may differ. _mesa_swizzle_ubyte_image can't handle two
1088ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * propagations at once correctly. */
1089ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    (srcFormat == baseInternalFormat ||
1090ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     baseInternalFormat == GL_RGBA) &&
109171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
109271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
109371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
109471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      /* dstmap - how to swizzle from GL_RGBA to dst format:
109571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       *
109671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       * FIXME - add !litteEndian and _rev varients:
109771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
109871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[3] = 0;
109971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[2] = 1;
110071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[1] = 2;
110171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[0] = 3;
110271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
110371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
110471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
110571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
110671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
110771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstRowStride, dstImageStride,
110871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
110971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
111071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
111171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell#endif
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11148f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1126b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1127b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1128b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1129b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
1132f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
1133f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1134f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1135f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1136f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
1137f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
1138f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1139f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1141f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1142f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1143f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1144f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1145f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
1146f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
1147f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1148f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1149a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1150a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1151a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1152a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1153a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1154a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1155a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1156a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1157a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1158a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1159a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1160b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb8888(TEXSTORE_PARAMS)
1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1165defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
1166defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
1167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1171defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1175defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1176defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
117717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
117860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1179b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1180b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1184defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
1185a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1186defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
1187a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
1188a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
1189a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1190defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1191defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
119217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
119360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1194b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1195b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1196a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1197a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1198a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
119971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
120071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
120171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
120271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGB &&
120371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
120471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
120571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      int img, row, col;
120671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
120771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
120871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
120971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
121071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1211b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1212b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1213b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1214b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
121571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
121671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
121771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
121871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
121971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
122071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = 0xff;
122171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
122271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
122371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
122471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
122571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
122671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
122771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
122871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
122971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
123071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGBA &&
1231ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            (srcType == GL_UNSIGNED_BYTE && littleEndian)) {
1232b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
1233ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      /* For some reason, streaming copies to write-combined regions
1234ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * are extremely sensitive to the characteristics of how the
1235ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * source data is retrieved.  By reordering the source reads to
1236ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * be in-order, the speed of this operation increases by half.
1237ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * Strangely the same isn't required for the RGB path, above.
1238ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       */
1239ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      for (img = 0; img < srcDepth; img++) {
1240ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1241ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                                                 srcWidth, srcFormat, srcType);
1242ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1243ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1244b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1245b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1246b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1247b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1248b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
1249ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         for (row = 0; row < srcHeight; row++) {
1250ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            for (col = 0; col < srcWidth; col++) {
1251ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               *(GLuint *)(dstRow + col * 4)  = (srcRow[col * 4 + RCOMP] << 16 |
1252ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + GCOMP] << 8 |
1253ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + BCOMP] << 0 |
1254ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + ACOMP] << 24);
1255ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            }
1256ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            dstRow += dstRowStride;
1257ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcRow += srcRowStride;
1258ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         }
1259ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      }
1260ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   }
1261ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   else if (!ctx->_ImageTransferState &&
1262ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            !srcPacking->SwapBytes &&
1263ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul	    dstFormat == &_mesa_texformat_argb8888 &&
1264ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcFormat == GL_RGBA &&
126571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
126671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
1267b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
126871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
126971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
127071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
127171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
127271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1273b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1274b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1275b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1276b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
127771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
127871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
127971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
128071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
128171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
128271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
128371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
128471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
128571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
128671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
128771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
128871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
128971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
129071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    !srcPacking->SwapBytes &&
129171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
129271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
129371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    littleEndian &&
1294ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    /* Three texture formats involved: srcFormat,
1295ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * baseInternalFormat and destFormat (GL_RGBA). Only two
1296ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * may differ. _mesa_swizzle_ubyte_image can't handle two
1297ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * propagations at once correctly. */
1298ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    (srcFormat == baseInternalFormat ||
1299ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     baseInternalFormat == GL_RGBA) &&
130071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
130171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
130271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
130371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
130471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      /* dstmap - how to swizzle from GL_RGBA to dst format:
130571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
130671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[3] = 3;		/* alpha */
130771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[2] = 0;		/* red */
130871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[1] = 1;		/* green */
130971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[0] = 2;		/* blue */
131071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
131171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
131271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
131371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
131471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1315b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				dstRowStride,
1316b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                dstImageOffsets,
131771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
131871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
131971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
1320a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1321a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1322a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1323a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1324a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1325a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1326a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1327a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1328a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1329a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1330a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1331a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1332a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1333a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1334b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1335b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1336b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1337b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1338a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1339a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1340f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1341f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1342f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1343f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1344f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1345f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1346f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1347f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1348a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1349f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1350f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1351f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( 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               }
1357defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1358a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1359a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1360a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1361a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1362a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1363a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1364a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1365a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1368b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb888(TEXSTORE_PARAMS)
1369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
138317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
138460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1385b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1386b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1394a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1395b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
139960909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
140060909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1401b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1402b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1403b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1404b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14188f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
14247c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1430b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1431b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1432b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1433b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1470b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_bgr888(TEXSTORE_PARAMS)
1471a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1472a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLuint ui = 1;
1473a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1474a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1475a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1476a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1477a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1478a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1479a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1480a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1481a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1482a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1483a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1484a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
148517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
148660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1487b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1488b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1489a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1490a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1491a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1492a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1493a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1494a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1495a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1496a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1497a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1498a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1499a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1500a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
150160909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
150260909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1503b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1504b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1505b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1506b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1507a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1508a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1509a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1510a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1511a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1512a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1513a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1514a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1515a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1516a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1517a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1518a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1519a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1520a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1521a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1522a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1523a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1524a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1525a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
15267c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1527a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1528a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1529a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1530a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1531a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1532b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1533b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1534b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1535b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1536a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1537a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1538a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1539a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1540a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1541a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1542a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1543a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1544a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1545a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1546a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1547a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1548a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1549a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1550a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1551a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1552a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1553b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb4444(TEXSTORE_PARAMS)
1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1555defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1556defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1561defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1564defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
156617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
156760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1568b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1569b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
15758f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1587b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1588b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1589b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1590b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1593f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1594f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1595f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1596f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1597f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1598f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1599f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1600f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1602f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1603f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1604f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1605f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1606f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1607f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1608f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1609f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1610a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1611a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1612a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1613a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1614a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1615a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1616a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1617a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1618a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1619a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1620defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1621a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1622b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb1555(TEXSTORE_PARAMS)
1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1624defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1625defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1630defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1633defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
163517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
163660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1637b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1638b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
16448f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1656b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1657b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1658b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1659b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1662f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1663f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1664f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1665f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1666f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1667f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1668f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1669f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1671f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1672f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1673f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1674f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1675f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1676f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1677f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1678f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1679a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1680a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1681a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1682a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1683a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1684a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1685a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1686a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1687a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1690b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_al88(TEXSTORE_PARAMS)
1691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1695defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1696defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1701defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
170717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
170860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1709b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1710b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
17168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1728b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1729b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1730b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1731b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1734f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
1735f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1736f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1737f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
1738f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
1739f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1740f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1742f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1743f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1744f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1745f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
1746f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
1747f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1748f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1749a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1750a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1751a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1752a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1753a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1754a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1755a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1756a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1757a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1758a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1759a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1760b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb332(TEXSTORE_PARAMS)
1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
177017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
177160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1772b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1773b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
17798f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1791b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1792b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1793b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1794b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1815b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_a8(TEXSTORE_PARAMS)
1816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
182717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
182860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1829b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1830b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
18368f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1848b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1849b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1850b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1851b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1868b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_ci8(TEXSTORE_PARAMS)
1869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1870a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
1871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
188017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
188160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1882b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1883b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1891b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1892b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1893b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1894b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
189660909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1913b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
1914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1917a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
1918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
192917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell   memcpy_texture(ctx, dims,
193060909388ab136d849d99eab49e782a53772a618fBrian Paul                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1931b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                  dstRowStride,
1932b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                  dstImageOffsets,
1933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
1942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1944b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1945b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1946b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1947b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1949b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            _mesa_swap2((GLushort *) dstRow, srcWidth);
1950b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride;
1951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1959184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul/**
1960184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul * Store a combined depth/stencil texture image.
1961184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul */
1962184a9707227ab024d65d352fe7c09b3e287348e9Brian PaulGLboolean
1963b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
1964184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul{
1965184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z24_s8);
1966184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
1967184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
1968184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1969184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   if (!ctx->_ImageTransferState &&
1970184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul       !srcPacking->SwapBytes) {
1971ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* simple path */
1972184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul      memcpy_texture(ctx, dims,
1973184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1974b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1975b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1976184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1977184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcAddr, srcPacking);
1978184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
1979184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   else {
1980ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* general path */
1981ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      const GLint srcRowStride
1982ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
1983ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         / sizeof(GLuint);
1984ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      GLint img, row;
1985ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
1986ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      for (img = 0; img < srcDepth; img++) {
1987b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLuint *dstRow = (GLuint *) dstAddr
1988b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img]
1989b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride / sizeof(GLuint)
1990b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset;
1991ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         const GLuint *src
1992ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
1993ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcWidth, srcHeight,
1994ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcFormat, srcType,
1995ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   img, 0, 0);
1996ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         for (row = 0; row < srcHeight; row++) {
1997ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLubyte stencil[MAX_WIDTH];
1998ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLint i;
1999ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* the 24 depth bits will be in the high position: */
2000ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
2001ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    GL_UNSIGNED_INT, /* dst type */
2002b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                    dstRow, /* dst addr */
2003ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    (GLfloat) 0xffffff, /* depthScale */
2004ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    srcType, src, srcPacking);
2005ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* get the 8-bit stencil values */
2006ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_stencil_span(ctx, srcWidth,
2007ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      GL_UNSIGNED_BYTE, /* dst type */
2008ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      stencil, /* dst addr */
2009ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      srcType, src, srcPacking,
2010ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      ctx->_ImageTransferState);
2011ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* merge stencil values into depth values */
2012ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            for (i = 0; i < srcWidth; i++)
2013b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               dstRow[i] |= stencil[i];
2014ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
2015ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            src += srcRowStride;
2016b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride / sizeof(GLuint);
2017ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         }
2018ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      }
2019184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
2020184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   return GL_TRUE;
2021184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul}
2022184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2023184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2024f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2026f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
2027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
2028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
2029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
2030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
2031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
2032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
2033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2035b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2037e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
2041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
2057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
205817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
205960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2060b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2061b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2073b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLfloat *srcRow = tempImage;
20749c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
2075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
20799c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
2080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2081b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2082b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2083b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2084b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2086b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
2087b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride;
2088b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            srcRow += srcWidth * components;
2089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2102b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2104e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
2107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
2108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
2109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
2110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
2111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
2112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
2119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
2124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
212517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
212660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2127b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2128b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
2141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2146b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2147b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2148b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2149b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
2153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
2154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
2155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
21678d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul#if FEATURE_EXT_texture_sRGB
21688d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
21698d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_srgb8(TEXSTORE_PARAMS)
21708d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
21718d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   /* XXX to do */
21728d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   _mesa_problem(ctx, "_mesa_texstore_srgb8 not finished");
21738d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   return GL_FALSE;
21748d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
21758d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
21768d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
21778d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_srgba8(TEXSTORE_PARAMS)
21788d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
21798d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   /* XXX to do */
21808d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   _mesa_problem(ctx, "_mesa_texstore_srgb8 not finished");
21818d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   return GL_FALSE;
21828d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
21838d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
21848d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
21858d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_sl8(TEXSTORE_PARAMS)
21868d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
21878d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   /* XXX to do */
21888d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   _mesa_problem(ctx, "_mesa_texstore_srgb8 not finished");
21898d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   return GL_FALSE;
21908d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
21918d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
21928d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
21938d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_sla8(TEXSTORE_PARAMS)
21948d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
21958d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   /* XXX to do */
21968d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   _mesa_problem(ctx, "_mesa_texstore_srgb8 not finished");
21978d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul   return GL_FALSE;
21988d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
21998d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
22008d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
22018d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
2202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
22037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2204c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
2205c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2206c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
220771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
22087a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
220971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
221071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
221171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLsizei width, GLsizei height, GLsizei depth,
221271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLenum format, GLenum type, const GLvoid *pixels,
221371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const struct gl_pixelstore_attrib *unpack,
221471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const char *funcName)
22157a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2216c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2217c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
22187a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
22197a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
22207a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
22217a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
222260909388ab136d849d99eab49e782a53772a618fBrian Paul   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
222360909388ab136d849d99eab49e782a53772a618fBrian Paul                                  format, type, pixels)) {
2224c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2225c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
22267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2227c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2228a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2229a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                          GL_READ_ONLY_ARB, unpack->BufferObj);
2230c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2231c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2232c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2233c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2234c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2235c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
22367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
22377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22387a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2240c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
2241c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
2242c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2243c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
224471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
22457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
224671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
224771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
2248c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
2249c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
2250c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
22517a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2252c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2253c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
22547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
22557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
22567a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
22577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2258c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
2259f285f0d8f60adafdfba5c1f0563b81c68bd398d3Brian Paul       ((const GLubyte *) 0) + packing->BufferObj->Size) {
2260c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
2261c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2262c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2263c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2264c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2265a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2266a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                         GL_READ_ONLY_ARB, packing->BufferObj);
2267c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2268c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2269c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
22707a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2271c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2272c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
22737a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
22747a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22757a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2276c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
2277c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
2278c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
2279c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
228071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellvoid
2281c039af165d5919008c6df599795951f85dea164dBrian Paul_mesa_unmap_teximage_pbo(GLcontext *ctx,
2282c039af165d5919008c6df599795951f85dea164dBrian Paul                         const struct gl_pixelstore_attrib *unpack)
2283c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
2284c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
2285c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2286c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
2287c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2288c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
2289c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
229089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2291da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2292da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2293da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a GLchan texel from a float-valued texture.
2294da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2295da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2296da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelFloatToChan( const struct gl_texture_image *texImage,
2297da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLchan *texelOut )
2298da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2299da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLfloat temp[4];
2300da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2301da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelf(texImage, i, j, k, temp);
23022742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
23032742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2304da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2305da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2306da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2307da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2308da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2309da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2310da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
2311da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
2312da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
2313da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2314da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2315da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2316da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2317da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2318da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a float texel from a GLchan-valued texture.
2319da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2320da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2321da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelChanToFloat( const struct gl_texture_image *texImage,
2322da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLfloat *texelOut )
2323da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2324da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLchan temp[4];
2325da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2326da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelc(texImage, i, j, k, temp);
23272742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
23282742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2329da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2330da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2331da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2332da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2333da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2334da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2335da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
2336da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
2337da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
2338da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2339da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2340da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2341da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2342da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2343da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Initialize the texture image's FetchTexelc and FetchTexelf methods.
2344da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2345da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2346da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulset_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
2347da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2348da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2349da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->TexFormat);
2350da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2351da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   switch (dims) {
2352da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 1:
2353da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
2354da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
2355da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2356da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 2:
2357da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
2358da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
2359da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2360da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 3:
2361da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
2362da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
2363da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2364da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   default:
2365da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      ;
2366da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2367da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2368da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   /* now check if we need to use a float/chan adaptor */
2369da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (!texImage->FetchTexelc) {
2370da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = FetchTexelFloatToChan;
2371da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2372da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else if (!texImage->FetchTexelf) {
2373da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = FetchTexelChanToFloat;
2374da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2375da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2376da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2377da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2378da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2379da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2380da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2381da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
23825999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
23835999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Choose the actual storage format for a new texture image.
23845999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
23855999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Also set some other texImage fields related to texture compression, etc.
23865999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param ctx  rendering context
23875999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param texImage  the gl_texture_image
23885999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param dims  texture dimensions (1, 2 or 3)
23895999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param format  the user-specified format parameter
23905999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param type  the user-specified type parameter
23915999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param internalFormat  the user-specified internal format hint
23925999c5b620236fb6a996cf56759aec31f01c126bBrian Paul */
23935999c5b620236fb6a996cf56759aec31f01c126bBrian Paulstatic void
23945999c5b620236fb6a996cf56759aec31f01c126bBrian Paulchoose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
23955999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLuint dims,
23965999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLenum format, GLenum type, GLint internalFormat)
23975999c5b620236fb6a996cf56759aec31f01c126bBrian Paul{
2398c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2399c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(ctx->Driver.ChooseTextureFormat);
24005999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24015999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   texImage->TexFormat
24025999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
24035999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
2404c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(texImage->TexFormat);
24055999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24065999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   set_fetch_functions(texImage, dims);
24075999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24085999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   if (texImage->TexFormat->TexelBytes == 0) {
24095999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* must be a compressed format */
24105999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_TRUE;
24115999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize =
24125999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
24135999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->Height, texImage->Depth,
24145999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->TexFormat->MesaFormat);
24155999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
24165999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   else {
24175999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* non-compressed format */
24185999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_FALSE;
24195999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize = 0;
24205999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
24215999c5b620236fb6a996cf56759aec31f01c126bBrian Paul}
24225999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24235999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24245999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
242689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
2427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
24286b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
24298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
24308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
24318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
24328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
24338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
24348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
24358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
24368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
24378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
24388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
24398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
2440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
2441a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
24428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
24448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
24458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
24468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24475999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
24488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
245089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
245189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
245289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
2453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
24544cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
24557d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
24567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
24577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
24587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
24598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2460e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2461e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage1D");
24626b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
24636b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
24646b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
24656b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
246689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
24676b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
24686b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2469b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLint dstRowStride = 0;
2470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2472a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2476b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2477b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
2482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2484f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
248589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
248689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
248789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
248889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
248989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
24903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2491c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
249271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
24938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
24948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24966b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
249789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
249889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
24996b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *
2500b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * This function is oriented toward storing images in main memory, rather
2501b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * than VRAM.  Device driver's can easily plug in their own replacement.
2502b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul *
2503b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * Note: width and height may be pre-convolved dimensions, but
2504b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * texImage->Width and texImage->Height will be post-convolved dimensions.
25058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
25068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
25078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
25088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
25098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
25108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
25118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
25128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
25138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
25148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
25158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
2516e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2517a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
25188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
25208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
25218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
25228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
25238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25245999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
25252c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
25262c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
25278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
252989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
253089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
253189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
253289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
25334cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
25347d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
25357d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
25367d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
25377d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
25388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
253971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2540e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage2D");
25416b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
25426b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
25436b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
25446b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
254589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
25466b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
25476b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2548b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
2549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2551a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
25525999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
2553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2555b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
2556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2558a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2562b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2563b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2570f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
257189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
257289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
257389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
257489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
257589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
25763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2577c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
257871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
25798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
25808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25836b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
258489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
258589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
25866b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
25878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
25888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
25898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
25908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
25918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
25928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
25938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
25948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
25958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
25968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2597e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2598a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
25998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26005999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
26012c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2602197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
26038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
260589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
260689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
260789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
260889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
26094cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
26107d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
26117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
26127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
26137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
26148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2615e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2616e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing, "glTexImage3D");
26176b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
26186b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
26196b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
26206b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
262189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
26226b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
26236b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2624b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
2625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2627a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
26285999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
2629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2631b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
2632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2634a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2638b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2639b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2646f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
264789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
264889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
264989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
265089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
265189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
26523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2653c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
265471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
26558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
26568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
266189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
266289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
26638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
26648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
26658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
26668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
26678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
26688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
26698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
26708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
26718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2672b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
2673e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2674e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage1D");
26757a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
26767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
26777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2679b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLint dstRowStride = 0;
2680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2682a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2686b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2687b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
26943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
26963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2697d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2698d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
26993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
27003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2701c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
270271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
27038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
270689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
270889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
270989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
27108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
27118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
27138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
27148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
27158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
27168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
27178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
27188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
27198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2720b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
272171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2722e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage2D");
27237a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
27247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
27257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2727b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride = 0;
2728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
27305999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
2731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2734b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
2735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2737a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2741b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2742b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
27493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
27513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2752d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2753d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
27543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
27553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2756c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
275771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
27588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
27628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
276389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
27648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
27658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
27678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
27688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
27698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
27708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
27718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
27728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
27738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2774b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
2775e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2776e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing,
2777e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        "glTexSubImage3D");
2778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2782b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
2783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
27855999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
2786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2789b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
2790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2792a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2796b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2797b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
28048f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
28053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
28063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2807d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2808d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
28093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
28103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2811c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
281271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
28138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28162aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
28178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
28188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
28218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
28238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
28248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
28258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
28268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
282789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2828a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2829a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2830a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2831a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2832a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2833a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2834a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
28358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2839b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul/**
28408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
28418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
28448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
28468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
28478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
28488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
28498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2850a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2851a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
285289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
285389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
28548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
285589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
285689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
285789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
285889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
285989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
286089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
286189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
28625999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
286389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
286489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
28654cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(imageSize);
286689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
286789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
286889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
286989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
287089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2871e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2872e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2873e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexImage2D");
28747a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
28757a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
28767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
287789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
28784039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
287989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
28808f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
28818f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
28828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
28838f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
28848f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
28858f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
28868f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2887c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
288871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
28898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
28958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
28988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
29008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
29018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
29028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
29038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
29048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
290589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2906a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2907a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2908a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2909a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2910a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2911a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2912a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2913a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
29148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
29158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
291889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
291989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2920e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2921e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
292289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
292389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
292489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
292589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
292689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
292789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
292889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2929e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
29305999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 1D texture formats yet */
2931a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2932a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2933a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2934a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2935a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2936a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2937a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2938e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2939e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2940e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
294189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
294289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
294389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
294489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
294589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
294689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
294789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
294889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
294989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
295089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
295189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
295289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
295389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
295489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
295589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
295689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
295789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
29585999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
29595999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
2960a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
296189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
296289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
296389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
296489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
296589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
296689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
296789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2968b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
2969e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2970e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2971e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexSubImage2D");
29727a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
29737a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
29747a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
29755999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
297689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
297789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
29785999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
297989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
2980a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                         texImage->TexFormat->MesaFormat,
2981f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2982a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                         (GLubyte *) texImage->Data);
298389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
298489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
298589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
298689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
298789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
298889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
298989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
299089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
299189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
29928f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
29938f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
29948f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
29958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
29968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
29978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
29988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2999c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
300071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
300189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
300289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
300389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
300489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
300589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
300689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
300789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
300889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
300989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
301089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
301189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
301289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
301389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
301489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
301589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
301689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
30175999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 3D texture formats yet */
3018a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3019a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3020a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
3021a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
3022a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
3023a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3024a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3025a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
302689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
302789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
302889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
30293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
30303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
30313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
30329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
30339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
30343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
30353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30369228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
30379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
30389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
30393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
30419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
30429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
3043c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
30449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
3045c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
30469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
30483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
30493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
30523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
30533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
30547c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3057f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3059f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3061f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3063f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
30643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
30683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
30713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
30723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
30737c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3076f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3078f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3080f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
30853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
30863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
30903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
30913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
30927c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3094f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
30953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
30993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
31009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
31023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
31033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
31047c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3107f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
31089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3109f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
31103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
31113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
31123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
3113a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z32:
31148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
3116a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowA = (const GLuint *) srcRowA;
3117a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowB = (const GLuint *) srcRowB;
31188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
31197c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3121a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul            dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
31228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3125a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z16:
3126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
3129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
3130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
3131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
3134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
31378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
31388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
3139defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
31408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
3141defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
31428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
31458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
31468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
31477c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3150f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
31519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3152f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
31539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3154f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
31559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3156f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
31578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
3161a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
31628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
31658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
31668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
31677c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3170f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3172f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
31739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3174f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
31758bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
3179defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
31808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
31838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
31848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
31857c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
31889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
31899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
31909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
31919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
31929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
31939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
31949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
31959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
31969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
31979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
31989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
319907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
320007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
320107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
32028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
32038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
3207defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
32088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
32118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
32128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
32137c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
32169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
32179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
32189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
32199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
32209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
32219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
32229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
32239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
32249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
32259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
32269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
32279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
32289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
32299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
32309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
323107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
323207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
323307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
323407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
32358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
32368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
3240defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
32418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
32448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
32458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
32467c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
32499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
32509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
32519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
32529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
32539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
32549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
32559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
32569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
32579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
32589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
32599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
32609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
32619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
32629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
32639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
326407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
326507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
326607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
326707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
32688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
32698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
3273defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
32748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
32778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
32788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
32797c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
32829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
32839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
32849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
32858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
32898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
32928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
32938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
32947c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
32979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
32989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
32999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
33009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
33019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
33029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
33039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
33049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
33059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
33069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
33079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
330807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
330907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
331007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
33118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
33128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
33138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
33148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
33158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
33168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
33178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
33188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
33198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
33209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
33218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
33228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
33238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
33247c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
33259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
33269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
33278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
33288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
33298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
3331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
3334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
3335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
3336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
3346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
3350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
3353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
3354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
3355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
3358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
3369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
3372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
3373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
3374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
3386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
3389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
3390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
3391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
3394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
3405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
3408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
3409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
3410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
3420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
3423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
3424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
3425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
3428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
3439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
3440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
3441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
3444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
3445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
3446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
3449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
3453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
3454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
3455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
3458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
3459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
3460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
3463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
3464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
3465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
3466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
3467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
34723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
34733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
34743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
34753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
34763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
34799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
34809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
34819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
34829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
34833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
34853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
34863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
34873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
34883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
34893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
34903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
34913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
34923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
34943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
34953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
34963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
34989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
34999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
35003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
35023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
35033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
35043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
35053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
35063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
35073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
35083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
35103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3512b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul/**
3513b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * XXX need to use the tex image's row stride!
3514b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul */
35153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
35163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
35173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
35183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
35193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
35203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
35219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
35229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
35239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
35243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
35253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
35263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
35273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
3528462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
35293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
35313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
35323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
35333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
35343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
35353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
35363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
35373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
35399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
35409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
35413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
35423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
35433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
35443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
35473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
35483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
35493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
35503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
35513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
35523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
35533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
35543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
35553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
35563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
35573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
35583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
35593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
35603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
35619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
35629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
35639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
35649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
35653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
35669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
35673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
35683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
35699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
35703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
35713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
35729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
35739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
35749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
35759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
35769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
35779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
35789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
35799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
35809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
35819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
35829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
35839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
35849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
35859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
35869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
35879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
35889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
35899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
35909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
35919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
35929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
35933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
35943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
35963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
35993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
36003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
36013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
36023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
36033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
36043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
36059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
36069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
36079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
36089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
36099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
36109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
36119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
36123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
36139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
36149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
36159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
36163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36175c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
36185c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
36199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
36202dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowA = _mesa_malloc(srcWidth * bpt);
36219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
36229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
36232dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowB = _mesa_malloc(srcWidth * bpt);
36249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
36252dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      _mesa_free(tmpRowA);
36263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
36273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
36283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
36309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
36319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
36339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
36343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
36369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
36373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
36399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
36403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
36429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
36439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
36449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
36459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
36469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
36479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
36483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
36504e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
36519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
36529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
36539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
36559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
36569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
36579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
36589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
36599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
36609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
36619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
36629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
36639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
36649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
36659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
36679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
36689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
36699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
36709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
36719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
36729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
36749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
36759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
36769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
36779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
36789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
36799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
36809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
36819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
36829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
36839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
36849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
36859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
36869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
36879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
36889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
36893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
36903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
36913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36922dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowA);
36932dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowB);
36949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
36969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
36979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
36989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
36999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
37009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
37019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
37029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
37039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
37049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
37059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
37069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
37079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
37089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
37099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
37109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
37119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
37139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
37149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
37159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
37189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
37209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
37229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
37259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
37279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
37299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
37329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
37349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
37369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
37389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
37399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
37409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
37419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
37429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
37439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
37449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
37459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
37479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
37489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
37499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
37529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
37549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
37569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
37599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
37619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
37639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
37669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
37689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
37709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
37729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
37739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
37743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
37753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37775999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
37783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
37793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
37803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
37813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
37823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3783d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
37843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
37853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
37863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
37872ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
37882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3789b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3790b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3791ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
37923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
3794c039af165d5919008c6df599795951f85dea164dBrian Paul   /* XXX choose cube map face here??? */
379518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
37962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
37973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3798ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3799ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
38003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
38012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
38022ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
38032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3804d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3805d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
38062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
38072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
38082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
38092ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
3810a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      if (srcImage->_BaseFormat == GL_RGB) {
38112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
38122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
38132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3814a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      else if (srcImage->_BaseFormat == GL_RGBA) {
38152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
38162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
38172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
3819a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
38202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
38232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
3824a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
38252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
38262ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
38272dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      srcData = (GLubyte *) _mesa_malloc(size);
38282ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
38292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
38302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38322dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */
38332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
38342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
38352dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul         _mesa_free((void *) srcData);
38362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
38392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
38402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
38412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3842d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
38432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
38444f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
38452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
384689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
384789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
384889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
38492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
38502ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
38512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
38522ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
385389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
38548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3855cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
38569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
38573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
38583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
38593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
38603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
38613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
38623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
386389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
38643ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
38653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
38663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
38673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
38683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
38693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
38703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
38713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
38723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
38733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
38743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
38773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
38793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
38803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
38833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
38853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
38863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
38893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
38913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
38923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
38933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
38943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
389589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
38962dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free((void *) srcData);
38972dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free(dstData);
389889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
38993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
39003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
39013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3902d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3903a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3904d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3905a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3906a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3907d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
39083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3909d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3910d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
39114cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         ctx->Driver.FreeTexImageData(ctx, dstImage);
3912d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3913d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3914e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
3915a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                 dstDepth, border, srcImage->InternalFormat);
3916d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3917d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
39184f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
39194f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
39205999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      dstImage->IsCompressed = srcImage->IsCompressed;
39215999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      if (dstImage->IsCompressed) {
39225999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstImage->CompressedSize
39235999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width,
39245999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Height,
39255999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Depth,
39265999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->TexFormat->MesaFormat);
39275999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ASSERT(dstImage->CompressedSize > 0);
39285999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      }
39295999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
3930d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
39314f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
39324f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3933d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
393489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
393589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
393689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
393789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
39384cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
393989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
394089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
394189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
394289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
39432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
394489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
394589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
394689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
394789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
39485999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         bytesPerTexel = dstImage->TexFormat->TexelBytes;
394989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
39504cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
39514cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul                                                * dstDepth * bytesPerTexel);
395289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
395389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
395489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
395589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
395689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
395789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3958d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3959d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3960d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3961d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3962d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3963d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
396489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
39652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
396689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
396789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
396889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
396989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
397089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
397189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
397289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
397389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
397489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
397589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
39762ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
397789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
397889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
397989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
398089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
39812ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
398289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
398389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
398489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
398589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
398689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
398789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
398889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
398989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
399089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3991d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
399289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
399389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
399489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
39952ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
39962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
3997a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         GLint dstRowStride
39985999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth);
39992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
4000a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
40018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
40028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
40038f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
40048f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
40058f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
40068f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
40078f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
40088f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
400989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
401089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
401189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
401289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
401389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
401489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
4015d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
40163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
401780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
401880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
401980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
402080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
402180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
402280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
402380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
402480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
402580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
40261cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
40271cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
40281cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
40291cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
40301cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
40311cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
40321cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
403380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
403480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
403580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
403680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
403780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
403880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
403980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
404080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
40411cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
404280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
404380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
404480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
404580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
404680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
404780fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
404880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
404980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
405080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
40511cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
405280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
40531cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
405480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
405580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
405680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
405780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
405880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
405980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
406080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
406180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
406280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
406380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
40641cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
406580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
406680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
406780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
406880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
406980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
407080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
407180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
407280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
407380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
407480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
407580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
407680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
407780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
407880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
407980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
408080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
408180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
408280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
408380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
408480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
408580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
408680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
408780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
408880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
408980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
409080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
409133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
409233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
409333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
409433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
409533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
409633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
409733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
409833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
409933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
410033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
410133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
410233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
410333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
410433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
410533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
410633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
410733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
410833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
4109701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
411033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
411133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
411233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
411333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
411433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
411533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
411633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
411733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
411833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
411933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
412033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
412133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
412233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
412333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
412433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
412568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
412668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
41270a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#if FEATURE_EXT_texture_sRGB
41280a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
41290a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul/**
41300a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul * Test if given texture image is an sRGB format.
41310a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul */
41320a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulstatic GLboolean
41330a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulis_srgb_teximage(const struct gl_texture_image *texImage)
41340a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul{
41350a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   switch (texImage->TexFormat->MesaFormat) {
41360a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SRGB8:
41370a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SRGBA8:
41380a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SL8:
41390a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SLA8:
41400a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul      return GL_TRUE;
41410a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   default:
41420a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul      return GL_FALSE;
41430a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   }
41440a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul}
41450a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
41460a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
41470a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
414868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
414968d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
415068d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetTexImage().
415168d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
415268d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
415368d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
415468d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
415568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   GLenum format, GLenum type, GLvoid *pixels,
4156ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_object *texObj,
4157ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_image *texImage)
415868d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
4159ad15866ef0e77478508eeb534b28f0136462b644Brian Paul   const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
416068d293b03535ca50daf70650b32db780f1718a3bBrian Paul
416168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
4162ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      /* Packing texture image into a PBO.
4163ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * Map the (potentially) VRAM-based buffer into our process space so
4164ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * we can write into it with the code below.
4165ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * A hardware driver might use a sophisticated blit to move the
4166ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * texture data to the PBO if the PBO is in VRAM along with the texture.
4167ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       */
4168ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      GLubyte *buf = (GLubyte *)
4169ad15866ef0e77478508eeb534b28f0136462b644Brian Paul         ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
4170ad15866ef0e77478508eeb534b28f0136462b644Brian Paul                               GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
417168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
417268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
417368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
417468d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
417568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
4176ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      /* <pixels> was an offset into the PBO.
4177ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * Now make it a real, client-side pointer inside the mapped region.
4178ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       */
417968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      pixels = ADD_POINTERS(buf, pixels);
418068d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
418168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!pixels) {
418268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
418368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
418468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
418568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
418668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   {
418768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint width = texImage->Width;
418868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint height = texImage->Height;
418968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint depth = texImage->Depth;
419068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLint img, row;
419168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      for (img = 0; img < depth; img++) {
419268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         for (row = 0; row < height; row++) {
419368d293b03535ca50daf70650b32db780f1718a3bBrian Paul            /* compute destination address in client memory */
419468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
419568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                width, height, format, type,
419668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                img, row, 0);
419768d293b03535ca50daf70650b32db780f1718a3bBrian Paul            assert(dest);
419868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
419968d293b03535ca50daf70650b32db780f1718a3bBrian Paul            if (format == GL_COLOR_INDEX) {
420068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLuint indexRow[MAX_WIDTH];
420168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
420268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* Can't use FetchTexel here because that returns RGBA */
420368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if (texImage->TexFormat->IndexBits == 8) {
420468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLubyte *src = (const GLubyte *) texImage->Data;
4205184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
420668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4207184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
420868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
420968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
421068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (texImage->TexFormat->IndexBits == 16) {
421168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLushort *src = (const GLushort *) texImage->Data;
4212184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
421368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4214184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
421568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
421668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
421768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else {
421868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_problem(ctx,
421968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                "Color index problem in _mesa_GetTexImage");
422068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
422168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_index_span(ctx, width, type, dest,
422268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     indexRow, &ctx->Pack,
422368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     0 /* no image transfer */);
422468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
422568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_DEPTH_COMPONENT) {
422668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat depthRow[MAX_WIDTH];
422768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
422868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
422968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img,
423068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                           depthRow + col);
423168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
423268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_depth_span(ctx, width, dest, type,
423368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     depthRow, &ctx->Pack);
423468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
4235184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            else if (format == GL_DEPTH_STENCIL_EXT) {
4236184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               /* XXX Note: we're bypassing texImage->FetchTexel()! */
4237184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               const GLuint *src = (const GLuint *) texImage->Data;
4238184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               src += width * row + width * height * img;
4239184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               _mesa_memcpy(dest, src, width * sizeof(GLuint));
4240184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               if (ctx->Pack.SwapBytes) {
4241184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  _mesa_swap4((GLuint *) dest, width);
4242184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               }
4243184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            }
424468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_YCBCR_MESA) {
424568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* No pixel transfer */
424668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               const GLint rowstride = texImage->RowStride;
424768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               MEMCPY(dest,
424868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      (const GLushort *) texImage->Data + row * rowstride,
424968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      width * sizeof(GLushort));
425068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* check for byte swapping */
425168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
425268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
425368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
425468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
425568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  if (!ctx->Pack.SwapBytes)
425668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     _mesa_swap2((GLushort *) dest, width);
425768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
425868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (ctx->Pack.SwapBytes) {
425968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_swap2((GLushort *) dest, width);
426068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
426168d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
42620a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#if FEATURE_EXT_texture_sRGB
42630a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul            else if (is_srgb_teximage(texImage)) {
42640a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               /* no pixel transfer and no non-linear to linear conversion */
42650a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               const GLint comps = texImage->TexFormat->TexelBytes;
42660a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               const GLint rowstride = comps * texImage->RowStride;
42670a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               MEMCPY(dest,
42680a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul                      (const GLubyte *) texImage->Data + row * rowstride,
42690a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul                      comps * width * sizeof(GLubyte));
42700a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul            }
42710a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
427268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else {
427368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* general case:  convert row to RGBA format */
427468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat rgba[MAX_WIDTH][4];
427568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
427668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
427768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
427868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
427968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_rgba_span_float(ctx, width,
428068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          (const GLfloat (*)[4]) rgba,
428168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          format, type, dest, &ctx->Pack,
428268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          0 /* no image transfer */);
428368d293b03535ca50daf70650b32db780f1718a3bBrian Paul            } /* format */
428468d293b03535ca50daf70650b32db780f1718a3bBrian Paul         } /* row */
428568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      } /* img */
428668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
428768d293b03535ca50daf70650b32db780f1718a3bBrian Paul
428868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
428968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
429068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
429168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
429268d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
429368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
429468d293b03535ca50daf70650b32db780f1718a3bBrian Paul
429568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
429668d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
429768d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetCompressedTexImage().
429868d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
429968d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
430068d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
430168d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
430268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              GLvoid *img,
430368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_object *texObj,
430468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_image *texImage)
430568d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
4306a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   GLuint size;
4307a5467697336f201abee19cba1521be80e5c87d3bBrian Paul
430868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
430968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
431068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
431168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if ((const GLubyte *) img + texImage->CompressedSize >
431268d293b03535ca50daf70650b32db780f1718a3bBrian Paul          (const GLubyte *) ctx->Pack.BufferObj->Size) {
431368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
431468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(invalid PBO access)");
431568d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
431668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
431768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
431868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
431968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
432068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
432168d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
432268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
432368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(PBO is mapped)");
432468d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
432568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
432668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      img = ADD_POINTERS(buf, img);
432768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
432868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!img) {
432968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
433068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
433168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
433268d293b03535ca50daf70650b32db780f1718a3bBrian Paul
4333a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   /* don't use texImage->CompressedSize since that may be padded out */
4334a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height,
4335a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                        texImage->Depth,
4336a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                        texImage->TexFormat->MesaFormat);
4337a5467697336f201abee19cba1521be80e5c87d3bBrian Paul
433868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   /* just memcpy, no pixelstore or pixel transfer */
4339a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   _mesa_memcpy(img, texImage->Data, size);
434068d293b03535ca50daf70650b32db780f1718a3bBrian Paul
434168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
434268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
434368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
434468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
434568d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
4346