texstore.c revision 5999c5b620236fb6a996cf56759aec31f01c126b
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,
61471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint dstRowStride, GLint dstImageStride,
61571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
61671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint srcWidth, GLint srcHeight, GLint srcDepth,
61771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const GLvoid *srcAddr,
61871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const struct gl_pixelstore_attrib *srcPacking )
61971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
62071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint srcComponents = _mesa_components_in_format(srcFormat);
62171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLubyte srcmap[6], map[4];
62271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint i;
62371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
624c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcRowStride =
625c039af165d5919008c6df599795951f85dea164dBrian Paul      _mesa_image_row_stride(srcPacking, srcWidth,
626c039af165d5919008c6df599795951f85dea164dBrian Paul                             srcFormat, GL_UNSIGNED_BYTE);
627c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcImageStride
628c039af165d5919008c6df599795951f85dea164dBrian Paul      = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
629c039af165d5919008c6df599795951f85dea164dBrian Paul                                 GL_UNSIGNED_BYTE);
630c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLubyte *srcImage
631c039af165d5919008c6df599795951f85dea164dBrian Paul      = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
632c039af165d5919008c6df599795951f85dea164dBrian Paul                                              srcWidth, srcHeight, srcFormat,
633c039af165d5919008c6df599795951f85dea164dBrian Paul                                              GL_UNSIGNED_BYTE, 0, 0, 0);
63471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
63571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLubyte *dstImage = (GLubyte *) dstAddr
63671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                     + dstZoffset * dstImageStride
63771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                     + dstYoffset * dstRowStride
63871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                     + dstXoffset * dstComponents;
63971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
640edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul   (void) ctx;
641edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul
64271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   compute_component_mapping(srcFormat, GL_RGBA, srcmap);
64371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   for (i = 0; i < 4; i++)
64571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      map[i] = srcmap[dstmap[i]];
64671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   if (srcRowStride == srcWidth * srcComponents &&
64871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       (srcImageStride == srcWidth * srcHeight * srcComponents ||
64971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell        srcDepth == 1)) {
65071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
65171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell		   srcWidth * srcHeight * srcDepth);
65271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
65371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else {
65471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLint img, row;
65571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
65671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLubyte *srcRow = srcImage;
65771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
65871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
65971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
66071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
66171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
66271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
66371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         srcImage += srcImageStride;
66471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
66571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
66671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
66771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
66871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
66971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
67617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwellmemcpy_texture(GLcontext *ctx,
67717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell	       GLuint dimensions,
67860909388ab136d849d99eab49e782a53772a618fBrian Paul               const struct gl_texture_format *dstFormat,
679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstRowStride, GLint dstImageStride,
682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
69160909388ab136d849d99eab49e782a53772a618fBrian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
69260909388ab136d849d99eab49e782a53772a618fBrian Paul        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
70717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
71517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  either 1 or 2 or 3
737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat  user-specified base internal format
738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat  destination Mesa texture format
739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr  destination image address
740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride  destination image row stride, in bytes
742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride  destination image layer stride, in bytes
743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth  source image size, in pixels
744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  incoming image format
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  incoming image data type
746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image packing parameters
748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum baseInternalFormat,
752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_texture_format *dstFormat,
753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLvoid *dstAddr,
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstRowStride, GLint dstImageStride,
756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum srcFormat, GLenum srcType,
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const GLvoid *srcAddr,
759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_pixelstore_attrib *srcPacking)
760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
78217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
78360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
795edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul      GLchan *dstImage = (GLchan *) ((GLubyte *) dstAddr
796edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul                                     + dstZoffset * dstImageStride
797edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul                                     + dstYoffset * dstRowStride
798edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul                                     + dstXoffset * dstFormat->TexelBytes);
799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
80260909388ab136d849d99eab49e782a53772a618fBrian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
80360909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
811edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul            dstRow += dstRowStride / sizeof(GLchan);
812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
814edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul         dstImage += dstImageStride / sizeof(GLchan);
815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
8198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
8269c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
8359c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
853a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul * Store a 32-bit integer depth component texture image.
854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
856a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul_mesa_texstore_z32(STORE_PARAMS)
857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
858a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = (GLfloat) 0xffffffff;
859a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
860a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z32);
861a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
865a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
866a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
867a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul       srcType == GL_UNSIGNED_INT) {
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
86917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
87060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
88560909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
8871ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
888a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
889a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    depthScale, srcType, src, srcPacking);
890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
900a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
903a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul_mesa_texstore_z16(STORE_PARAMS)
904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
905a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = 65535.0f;
906a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
907a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z16);
908a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
914a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
91617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
91760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
9281ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul      GLint img, row;
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
93260909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
934a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
9351ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
936a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_SHORT, dst16, depthScale,
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
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
951a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_rgb565(STORE_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,
966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
970a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
971a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
972a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
973a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
974a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
975a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
976a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
977a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
978a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
979a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
98060909388ab136d849d99eab49e782a53772a618fBrian Paul         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
981a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
982a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
983a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstZoffset * dstImageStride
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      GLubyte *dstImage = (GLubyte *) dstAddr
1017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1018f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1019f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1021a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1022a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1023a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1024f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1026f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1027a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
1028defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
1029f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
1030f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1031f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1032f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
1033f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
1034f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1035f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1036f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1037f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1038f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1039f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1040f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
1041f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
1042f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1043f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS)
1057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
105871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLuint ui = 1;
105971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLubyte littleEndian = *((const GLubyte *) &ui);
106071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
106171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   (void)littleEndian;
1062defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
1063defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1068defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1070defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1071defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
107317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
107460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
107971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell#if 0
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      GLubyte *dstImage = (GLubyte *) dstAddr
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
1133f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
1134f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1135f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1136f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1137f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
1138f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
1139f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1140f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1142f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1143f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1144f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1145f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1146f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
1147f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
1148f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1149f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1150a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1151a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1152a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1153a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1154a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1155a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1156a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1157a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1158a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1159a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1160a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1161a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS)
1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1167defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
1168defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
1169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1173defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
1174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1177defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1178defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
117917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
118060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1185defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
1186a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1187defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
1188a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
1189a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
1190a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1191defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1192defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
119317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
119460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1195a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
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      GLubyte *dstImage = (GLubyte *) dstAddr
120771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstZoffset * dstImageStride
120871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstYoffset * dstRowStride
120971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstXoffset * dstFormat->TexelBytes;
121071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
121171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
121271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
121371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
121471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
121571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
121671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
121771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
121871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
121971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
122071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
122171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = 0xff;
122271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
122371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
122471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
122571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
122671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
122771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
122871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
122971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
123071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
123171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
123271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGBA &&
1233ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            (srcType == GL_UNSIGNED_BYTE && littleEndian)) {
1234ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
1235ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      int img, row, col;
1236ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1237ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                        + dstZoffset * dstImageStride
1238ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                        + dstYoffset * dstRowStride
1239ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1240ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
1241ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      /* For some reason, streaming copies to write-combined regions
1242ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * are extremely sensitive to the characteristics of how the
1243ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * source data is retrieved.  By reordering the source reads to
1244ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * be in-order, the speed of this operation increases by half.
1245ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * Strangely the same isn't required for the RGB path, above.
1246ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       */
1247ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      for (img = 0; img < srcDepth; img++) {
1248ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1249ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                                                 srcWidth, srcFormat, srcType);
1250ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1251ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1252ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         GLubyte *dstRow = dstImage;
1253ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         for (row = 0; row < srcHeight; row++) {
1254ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            for (col = 0; col < srcWidth; col++) {
1255ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               *(GLuint *)(dstRow + col * 4)  = (srcRow[col * 4 + RCOMP] << 16 |
1256ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + GCOMP] << 8 |
1257ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + BCOMP] << 0 |
1258ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + ACOMP] << 24);
1259ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            }
1260ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            dstRow += dstRowStride;
1261ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcRow += srcRowStride;
1262ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         }
1263ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         dstImage += dstImageStride;
1264ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      }
1265ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   }
1266ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   else if (!ctx->_ImageTransferState &&
1267ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            !srcPacking->SwapBytes &&
1268ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul	    dstFormat == &_mesa_texformat_argb8888 &&
1269ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcFormat == GL_RGBA &&
127071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
127171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
127271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      int img, row, col;
127371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte *dstImage = (GLubyte *) dstAddr
127471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstZoffset * dstImageStride
127571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstYoffset * dstRowStride
127671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstXoffset * dstFormat->TexelBytes;
127771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
127871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
127971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
128071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
128171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
128271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
128371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
128471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
128571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
128671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
128771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
128871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
128971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
129071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
129171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
129271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
129371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
129471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
129571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
129671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
129771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    !srcPacking->SwapBytes &&
129871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
129971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
130071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    littleEndian &&
1301ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    /* Three texture formats involved: srcFormat,
1302ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * baseInternalFormat and destFormat (GL_RGBA). Only two
1303ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * may differ. _mesa_swizzle_ubyte_image can't handle two
1304ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * propagations at once correctly. */
1305ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    (srcFormat == baseInternalFormat ||
1306ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     baseInternalFormat == GL_RGBA) &&
130771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
130871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
130971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
131071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
131171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      /* dstmap - how to swizzle from GL_RGBA to dst format:
131271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
131371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[3] = 3;		/* alpha */
131471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[2] = 0;		/* red */
131571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[1] = 1;		/* green */
131671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[0] = 2;		/* blue */
131771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
131871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
131971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
132071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
132171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
132271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstRowStride, dstImageStride,
132371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
132471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
132571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
1326a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1327a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1328a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1329a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1330a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1331a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1332a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1333a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1334a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1335a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1336a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1337a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1338a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1339a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1340a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1341a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1342a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1343a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1344a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1345a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1346a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1347f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1348f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1349f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1350f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1351f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1352f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1353f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1354f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1355a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1356f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1357f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1358f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1359f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1360f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1361f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1362f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1363f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1364defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1365a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1366a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1367a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1368a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1369a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1370a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1371a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1372a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1373a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS)
1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
139117bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
139260909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1401a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
141060909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
141160909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
14278f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
14337c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1481a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_bgr888(STORE_PARAMS)
1482a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1483a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLuint ui = 1;
1484a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1485a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1486a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1487a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1488a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1489a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1490a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1491a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1492a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1493a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1494a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1495a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
149617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
149760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1498a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1499a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1500a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1501a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1502a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1503a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1504a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1505a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1506a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1507a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1508a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1509a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1510a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1511a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1512a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1513a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1514a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
151560909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
151660909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1517a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1518a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1519a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1520a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1521a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1522a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1523a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1524a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1525a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1526a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1527a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1528a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1529a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1530a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1531a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1532a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1533a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1534a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1535a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1536a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1537a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
15387c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1539a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1540a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1541a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1542a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1543a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1544a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1545a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1546a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1547a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1548a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1549a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1550a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1551a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1552a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1553a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1554a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1555a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1556a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1557a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1558a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1559a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1560a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1561a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1562a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1563a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1564a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1565a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1566a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS)
1568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1569defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1570defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1575defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1578defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
158017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
158160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
15888f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1607f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1608f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1609f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1610f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1611f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1612f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1613f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1614f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1616f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1617f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1618f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1619f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1620f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1621f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1622f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1623f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1624a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1625a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1626a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1627a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1628a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1629a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1630a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1631a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1632a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1633a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1634a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1635defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1636a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS)
1638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1639defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1640defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1645defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1648defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
165017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
165160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
16588f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1677f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1678f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1679f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1680f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1681f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1682f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1683f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1684f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1686f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1687f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1688f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1689f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1690f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1691f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1692f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1693f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1694a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1695a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1696a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1697a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1698a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1699a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1700a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1701a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1702a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1703a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS)
1707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1711defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1712defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1717defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
172317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
172460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
17318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1750f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
1751f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1752f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1753f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
1754f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
1755f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1756f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1758f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1759f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1760f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1761f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
1762f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
1763f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1764f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1765a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1766a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1767a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1768a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1769a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1770a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1771a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1772a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1773a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1774a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1775a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1776a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS)
1778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
178717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
178860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
17958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS)
1834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
184517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
184660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
18538f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS)
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1889a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
189917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
190060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
191560909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS)
1934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1937a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
194917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell   memcpy_texture(ctx, dims,
195060909388ab136d849d99eab49e782a53772a618fBrian Paul                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRowStride, dstImageStride,
1952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1960f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
196126f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul      GLubyte *pImage = (GLubyte *) dstAddr
196226f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul                      + dstZoffset * dstImageStride
196326f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul                      + dstYoffset * dstRowStride
196426f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul                      + dstXoffset * dstFormat->TexelBytes;
1965f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
196726f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul         GLubyte *pRow = pImage;
1968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
196926f69d87a4e6f4d39ce10864e9e70689646155edBrian Paul            _mesa_swap2((GLushort *) pRow, srcWidth);
1970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            pRow += dstRowStride;
1971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         pImage += dstImageStride;
1973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1980184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul/**
1981184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul * Store a combined depth/stencil texture image.
1982184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul */
1983184a9707227ab024d65d352fe7c09b3e287348e9Brian PaulGLboolean
1984184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul_mesa_texstore_z24_s8(STORE_PARAMS)
1985184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul{
1986184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z24_s8);
1987184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
1988184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
1989184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1990184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   if (!ctx->_ImageTransferState &&
1991184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul       !srcPacking->SwapBytes) {
1992ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* simple path */
1993184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul      memcpy_texture(ctx, dims,
1994184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1995184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstRowStride, dstImageStride,
1996184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1997184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcAddr, srcPacking);
1998184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
1999184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   else {
2000ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* general path */
2001ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      const GLint srcRowStride
2002ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2003ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         / sizeof(GLuint);
2004ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      GLuint *dstImage = (GLuint *) dstAddr;
2005ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      GLint img, row;
2006ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
2007ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      for (img = 0; img < srcDepth; img++) {
2008ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         GLuint *dst = dstImage;
2009ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         const GLuint *src
2010ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2011ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcWidth, srcHeight,
2012ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcFormat, srcType,
2013ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   img, 0, 0);
2014ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         for (row = 0; row < srcHeight; row++) {
2015ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLubyte stencil[MAX_WIDTH];
2016ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLint i;
2017ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* the 24 depth bits will be in the high position: */
2018ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
2019ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    GL_UNSIGNED_INT, /* dst type */
2020ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    dst, /* dst addr */
2021ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    (GLfloat) 0xffffff, /* depthScale */
2022ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    srcType, src, srcPacking);
2023ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* get the 8-bit stencil values */
2024ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_stencil_span(ctx, srcWidth,
2025ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      GL_UNSIGNED_BYTE, /* dst type */
2026ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      stencil, /* dst addr */
2027ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      srcType, src, srcPacking,
2028ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      ctx->_ImageTransferState);
2029ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* merge stencil values into depth values */
2030ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            for (i = 0; i < srcWidth; i++)
2031ef8653a83800bc4b8e116e03ad52604097224378Brian Paul               dst[i] |= stencil[i];
2032ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
2033ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            src += srcRowStride;
2034ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            dst += dstRowStride / sizeof(GLuint);
2035ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         }
2036ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         dstImage += dstImageStride / sizeof(GLuint);
2037ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      }
2038184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
2039184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2040184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2041184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   return GL_TRUE;
2042184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul}
2043184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2044184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS)
2057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2058e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
2061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
2062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
2063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
2064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
2065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
2066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
2073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
2078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
207917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
208060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
2082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
20949c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
2095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
21039c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
2104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dst = dstImage;
2106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dst, src, bytesPerRow);
2108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += dstRowStride;
2109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
2112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
2122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS)
2125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2126e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
2129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
2130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
2131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
2132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
2133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
2134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
2141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
2146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
214717bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
214860909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
2150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
2162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
2163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
2164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
2165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
2166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
2172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
2175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
2176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
2177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
2182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
21917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2192c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
2193c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2194c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
219571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
21967a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
219771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
219871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
219971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLsizei width, GLsizei height, GLsizei depth,
220071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLenum format, GLenum type, const GLvoid *pixels,
220171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const struct gl_pixelstore_attrib *unpack,
220271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const char *funcName)
22037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2204c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2205c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
22067a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
22077a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
22087a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
22097a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
221060909388ab136d849d99eab49e782a53772a618fBrian Paul   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
221160909388ab136d849d99eab49e782a53772a618fBrian Paul                                  format, type, pixels)) {
2212c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2213c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
22147a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2215c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2216a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2217a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                          GL_READ_ONLY_ARB, unpack->BufferObj);
2218c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2219c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2220c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2221c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2222c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2223c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
22247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
22257a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22267a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2228c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
2229c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
2230c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2231c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
223271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
22337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
223471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
223571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
2236c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
2237c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
2238c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
22397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2240c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2241c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
22427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
22437a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
22447a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
22457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2246c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
2247f285f0d8f60adafdfba5c1f0563b81c68bd398d3Brian Paul       ((const GLubyte *) 0) + packing->BufferObj->Size) {
2248c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
2249c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2250c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2251c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2252c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2253a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2254a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                         GL_READ_ONLY_ARB, packing->BufferObj);
2255c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2256c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2257c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
22587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2259c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2260c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
22617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
22627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
22637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2264c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
2265c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
2266c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
2267c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
226871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellvoid
2269c039af165d5919008c6df599795951f85dea164dBrian Paul_mesa_unmap_teximage_pbo(GLcontext *ctx,
2270c039af165d5919008c6df599795951f85dea164dBrian Paul                         const struct gl_pixelstore_attrib *unpack)
2271c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
2272c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
2273c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2274c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
2275c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2276c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
2277c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
227889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2279da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2280da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2281da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a GLchan texel from a float-valued texture.
2282da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2283da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2284da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelFloatToChan( const struct gl_texture_image *texImage,
2285da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLchan *texelOut )
2286da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2287da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLfloat temp[4];
2288da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2289da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelf(texImage, i, j, k, temp);
22902742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
22912742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2292da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2293da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2294da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2295da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2296da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2297da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2298da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
2299da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
2300da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
2301da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2302da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2303da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2304da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2305da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2306da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a float texel from a GLchan-valued texture.
2307da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2308da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2309da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelChanToFloat( const struct gl_texture_image *texImage,
2310da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLfloat *texelOut )
2311da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2312da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLchan temp[4];
2313da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2314da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelc(texImage, i, j, k, temp);
23152742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
23162742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2317da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2318da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2319da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2320da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2321da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2322da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2323da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
2324da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
2325da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
2326da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2327da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2328da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2329da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2330da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2331da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Initialize the texture image's FetchTexelc and FetchTexelf methods.
2332da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2333da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2334da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulset_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
2335da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2336da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2337da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->TexFormat);
2338da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2339da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   switch (dims) {
2340da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 1:
2341da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
2342da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
2343da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2344da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 2:
2345da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
2346da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
2347da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2348da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 3:
2349da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
2350da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
2351da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2352da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   default:
2353da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      ;
2354da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2355da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2356da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   /* now check if we need to use a float/chan adaptor */
2357da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (!texImage->FetchTexelc) {
2358da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = FetchTexelFloatToChan;
2359da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2360da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else if (!texImage->FetchTexelf) {
2361da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = FetchTexelChanToFloat;
2362da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2363da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2364da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2365da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2366da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2367da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2368da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2369da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
23705999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
23715999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Choose the actual storage format for a new texture image.
23725999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
23735999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Also set some other texImage fields related to texture compression, etc.
23745999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param ctx  rendering context
23755999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param texImage  the gl_texture_image
23765999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param dims  texture dimensions (1, 2 or 3)
23775999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param format  the user-specified format parameter
23785999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param type  the user-specified type parameter
23795999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param internalFormat  the user-specified internal format hint
23805999c5b620236fb6a996cf56759aec31f01c126bBrian Paul */
23815999c5b620236fb6a996cf56759aec31f01c126bBrian Paulstatic void
23825999c5b620236fb6a996cf56759aec31f01c126bBrian Paulchoose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
23835999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLuint dims,
23845999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLenum format, GLenum type, GLint internalFormat)
23855999c5b620236fb6a996cf56759aec31f01c126bBrian Paul{
23865999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   assert(ctx->Driver.ChooseTextureFormat);
23875999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
23885999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   texImage->TexFormat
23895999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
23905999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
23915999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   assert(texImage->TexFormat);
23925999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
23935999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   set_fetch_functions(texImage, dims);
23945999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
23955999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   if (texImage->TexFormat->TexelBytes == 0) {
23965999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* must be a compressed format */
23975999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_TRUE;
23985999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize =
23995999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
24005999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->Height, texImage->Depth,
24015999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->TexFormat->MesaFormat);
24025999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
24035999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   else {
24045999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* non-compressed format */
24055999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_FALSE;
24065999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize = 0;
24075999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
24085999c5b620236fb6a996cf56759aec31f01c126bBrian Paul}
24095999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24105999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24115999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
24127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
241389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
2414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
24156b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
24168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
24178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
24188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
24198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
24208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
24218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
24228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
24238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
24248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
24258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
24268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
2427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
2428a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
24298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
24318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
24328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
24338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24345999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
24358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
243789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
243889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
243989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
2440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
24414cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
24427d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
24437d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
24447d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
24457d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
24468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2447e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2448e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage1D");
24496b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
24506b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
24516b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
24526b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
245389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
24546b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
24556b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2459a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
2468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2470f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
247189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
247289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
247389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
247489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
247589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
24763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2477c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
247871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
24798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
24808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24826b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
248389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
248489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
24856b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * We store the image in heap memory.  We know nothing about on-board
24866b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * VRAM here.  But since most DRI drivers rely on keeping a copy of all
24876b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * textures in main memory, this routine will typically be used by
24886b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * hardware drivers too.
24896b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *
2490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
24916b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Special memory allocation needs (VRAM, AGP, etc)
24926b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Unusual row/image strides or padding
2493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
24946b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Using VRAM-based Pixel Buffer Objects
24958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
24968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
24978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
24988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
24998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
25008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
25018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
25028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
25038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
25048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
25058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
2506e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2507a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
25088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
25108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
25118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
25128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
25138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25145999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
25152c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
25162c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
25178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
251989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
252089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
252189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
252289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
25234cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
25247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
25257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
25267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
25277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
25288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
252971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2530e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage2D");
25316b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
25326b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
25336b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
25346b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
253589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
25366b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
25376b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
2539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2541a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
25425999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
2543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
25459c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
2546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2548a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2559f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
256089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
256189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
256289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
256389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
256489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
25653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2566c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
256771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
25688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
25698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25726b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
257389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
257489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
25756b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
25768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
25778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
25788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
25798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
25808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
25818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
25828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
25838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
25848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
25858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2586e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2587a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
25888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25895999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
25902c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2591197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
25928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
259489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
259589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
259689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
259789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
25984cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
25997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
26007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
26017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
26027d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
26038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2604e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2605e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing, "glTexImage3D");
26066b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
26076b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
26086b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
26096b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
261089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
26116b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
26126b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2616a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
26175999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
2619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
2622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
2623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2625a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2636f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
263789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
263889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
263989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
264089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
264189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
26423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2643c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
264471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
26458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
26468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
265189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
265289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
26538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
26548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
26558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
26568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
26578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
26588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
26598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
26608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
26618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2662e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2663e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage1D");
26647a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
26657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
26667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2671a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
26823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
26843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2685d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2686d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
26873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
26883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2689c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
269071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
26918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
26928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
269489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
269689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
269789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
26988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
26998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
27018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
27028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
27038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
27048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
27058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
27068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
27078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
270871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2709e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage2D");
27107a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
27117a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
27127a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
2715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
27175999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
2718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2724a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
27353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
27373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2738d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2739d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
27403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
27413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2742c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
274371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
27448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
27488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
274989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
27508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
27518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
27538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
27548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
27558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
27568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
27578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
27588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
27598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2760e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2761e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing,
2762e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        "glTexSubImage3D");
2763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
27705999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
2771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2779a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
27908f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
27913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
27923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2793d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2794d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
27953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
27963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2797c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
279871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
27998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28022aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
28038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
28048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
28078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
28098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
28108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
28118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
28128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
281389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2814a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2815a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2816a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2817a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2818a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2819a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2820a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
28218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
28278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
28308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
28328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
28338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
28348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
28358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2836a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2837a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
283889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
283989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
28408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
284189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
284289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
284389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
284489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
284589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
284689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
284789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
28485999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
284989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
285089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
28514cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(imageSize);
285289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
285389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
285489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
285589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
285689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2857e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2858e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2859e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexImage2D");
28607a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
28617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
28627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
286389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
28644039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
286589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
28668f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
28678f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
28688f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
28698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
28708f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
28718f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
28728f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2873c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
287471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
28758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
28768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
28818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
28848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
28858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
28868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
28878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
28888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
28898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
28908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
289189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2892a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2893a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2894a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2895a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2896a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2897a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2898a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2899a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
29008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
29018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
290489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
290589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2906e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2907e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
290889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
290989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
291089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
291189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
291289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
291389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
291489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2915e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
29165999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 1D texture formats yet */
2917a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2918a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2919a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2920a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2921a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2922a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2923a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2924e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2925e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2926e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
292789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
292889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
292989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
293089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
293189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
293289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
293389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
293489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
293589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
293689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
293789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
293889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
293989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
294089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
294189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
294289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
294389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
29445999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
29455999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
2946a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
294789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
294889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
294989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
295089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
295189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
295289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
295389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2954e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2955e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2956e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexSubImage2D");
29577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
29587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
29597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
29605999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
296189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
296289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
29635999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
296489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
2965a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                         texImage->InternalFormat,
2966f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2967f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
296889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
296989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
297089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
297189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
297289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
297389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
297489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
297589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
297689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
29778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
29788f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
29798f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
29808f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
29818f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
29828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
29838f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2984c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
298571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
298689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
298789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
298889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
298989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
299089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
299189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
299289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
299389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
299489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
299589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
299689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
299789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
299889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
299989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
300089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
300189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
30025999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 3D texture formats yet */
3003a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3004a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3005a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
3006a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
3007a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
3008a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3009a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3010a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
301189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
301289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
301389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
30143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
30153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
30163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
30179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
30189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
30193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
30203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
30219228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
30229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
30239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
30243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
30259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
30269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
30279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
3028c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
30299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
3030c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
30319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
30323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
30333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
30343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
30373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
30383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
30397c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3042f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3044f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3046f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3048f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
30493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
30533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
30563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
30573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
30587c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3061f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3063f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3065f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
30703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
30713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
30723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
30753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
30763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
30777c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3079f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
30803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
30833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
30859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
30883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
30897c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3092f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3094f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
30963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
3098a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z32:
30998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
3101a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowA = (const GLuint *) srcRowA;
3102a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowB = (const GLuint *) srcRowB;
31038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
31047c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3106a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul            dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
31078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3110a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z16:
3111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
3114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
3115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
3116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
3119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
31228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
31238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
3124defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
31258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
3126defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
31278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
31308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
31318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
31327c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3135f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
31369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3137f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
31389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3139f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
31409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3141f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
31428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31448bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
3146a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
31478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
31508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
31518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
31527c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3155f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
31569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3157f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
31589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3159f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
31608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
3164defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
31658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
31688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
31698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
31707c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
31739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
31749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
31759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
31769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
31779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
31789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
31799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
31809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
31819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
31829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
31839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
318407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
318507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
318607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
31878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
31888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
3192defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
31938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
31968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
31978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
31987c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
32019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
32029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
32039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
32049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
32059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
32069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
32079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
32089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
32099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
32109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
32119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
32129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
32139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
32149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
32159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
321607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
321707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
321807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
321907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
32208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
32218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
3225defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
32268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
32298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
32308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
32317c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
32349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
32359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
32369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
32379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
32389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
32399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
32409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
32419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
32429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
32439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
32449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
32459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
32469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
32479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
32489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
324907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
325007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
325107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
325207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
32538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
32548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
3258defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
32598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
32628bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
32638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
32647c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
32679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
32689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
32699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
32708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
32738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
32748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
32778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
32788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
32797c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
32829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
32839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
32849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
32859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
32869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
32879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
32889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
32899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
32909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
32919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
32929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
329307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
329407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
329507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
32968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
32978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
33008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
33018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
33028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
33038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
33048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
33059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
33068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
33078bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
33088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
33097c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
33109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
33119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
33128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
33138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
33148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
3316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
3319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
3320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
3321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
3331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
3335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
3338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
3339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
3340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
3343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
3354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
3357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
3358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
3359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
3371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
3374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
3375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
3376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
3379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
3390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
3393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
3394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
3395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
3405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
3408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
3409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
3410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
3413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
3424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
3425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
3426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
3429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
3430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
3431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
3434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
3438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
3439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
3440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
3443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
3444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
3445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
3448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
3449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
3450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
3451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
3452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
34573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
34583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
34593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
34603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
34613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
34649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
34659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
34669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
34679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
34683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
34703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
34713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
34723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
34733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
34743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
34753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
34763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
34773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
34793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
34803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
34813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
34839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
34849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
34853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
34873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
34883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
34893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
34903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
34913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
34923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
34933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
34943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
34953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
34983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
34993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
35003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
35013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
35023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
35039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
35049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
35059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
35063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
35073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
35083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
35093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
3510462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
35113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
35133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
35143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
35153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
35163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
35173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
35183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
35193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
35219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
35229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
35233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
35243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
35253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
35263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
35293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
35303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
35313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
35323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
35333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
35343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
35353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
35363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
35373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
35383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
35393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
35403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
35413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
35423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
35439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
35449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
35459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
35469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
35473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
35489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
35493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
35503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
35519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
35523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
35533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
35549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
35559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
35569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
35579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
35589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
35599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
35609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
35619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
35629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
35639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
35649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
35659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
35669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
35679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
35689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
35699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
35709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
35719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
35729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
35739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
35749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
35753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
35763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
35783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
35813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
35823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
35833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
35843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
35853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
35863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
35879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
35889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
35899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
35909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
35919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
35929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
35939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
35943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
35959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
35969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
35979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
35983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35995c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
36005c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
36019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
36022dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowA = _mesa_malloc(srcWidth * bpt);
36039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
36049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
36052dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowB = _mesa_malloc(srcWidth * bpt);
36069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
36072dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      _mesa_free(tmpRowA);
36083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
36093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
36103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
36129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
36139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
36159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
36163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
36189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
36193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
36219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
36223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
36249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
36259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
36269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
36279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
36289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
36299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
36303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
36324e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
36339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
36349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
36359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
36379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
36389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
36399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
36409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
36419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
36429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
36439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
36449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
36459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
36469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
36479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
36499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
36509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
36519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
36529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
36539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
36549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
36569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
36579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
36589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
36599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
36609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
36619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
36629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
36639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
36649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
36659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
36669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
36679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
36689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
36699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
36709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
36713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
36723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
36733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36742dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowA);
36752dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowB);
36769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
36789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
36799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
36809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
36819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
36829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
36839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
36849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
36859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
36869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
36879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
36889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
36899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
36909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
36919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
36929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
36939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
36959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
36969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
36979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
36989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
37009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
37029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
37049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
37079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
37099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
37119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
37149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
37169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
37189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
37199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
37209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
37219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
37229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
37239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
37249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
37259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
37269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
37279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
37299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
37309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
37319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
37349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
37369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
37389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
37419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
37439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
37459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
37479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
37489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
37499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
37509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
37519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
37529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
37539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
37549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
37559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
37563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
37573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37595999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
37603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
37613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
37623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
37633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
37643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3765d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
37663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
37673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
37683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
37692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
37702ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3771b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3772b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3773ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
37743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
3776c039af165d5919008c6df599795951f85dea164dBrian Paul   /* XXX choose cube map face here??? */
377718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
37782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
37793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3780ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3781ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
37823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37832ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
37842ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
37852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3786d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3787d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
37882ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
37892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
37902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
37912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
3792a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      if (srcImage->_BaseFormat == GL_RGB) {
37932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
37942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
37952ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3796a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      else if (srcImage->_BaseFormat == GL_RGBA) {
37972ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
37982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
37992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
3801a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
38022ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
38052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
3806a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
38072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
38082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
38092dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      srcData = (GLubyte *) _mesa_malloc(size);
38102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
38112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
38122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38142dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */
38152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
38162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
38172dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul         _mesa_free((void *) srcData);
38182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
38192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
38202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
38212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
38222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
38232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3824d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
38252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
38264f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
38272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
382889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
382989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
383089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
38312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
38322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
38332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
38342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
383589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
38368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3837cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
38389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
38393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
38403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
38413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
38423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
38433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
38443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
384589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
38463ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
38473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
38483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
38493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
38503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
38513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
38523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
38533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
38543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
38553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
38563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
38593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
38613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
38623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
38653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
38673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
38683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
38703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
38713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
38733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
38743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
38753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
38763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
387789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
38782dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free((void *) srcData);
38792dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free(dstData);
388089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
38813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
38823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
38833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3884d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3885a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3886d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3887a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3888a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3889d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
38903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3891d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3892d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
38934cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         ctx->Driver.FreeTexImageData(ctx, dstImage);
3894d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3895d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3896e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
3897a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                 dstDepth, border, srcImage->InternalFormat);
3898d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3899d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
39004f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
39014f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
39025999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      dstImage->IsCompressed = srcImage->IsCompressed;
39035999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      if (dstImage->IsCompressed) {
39045999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstImage->CompressedSize
39055999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width,
39065999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Height,
39075999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Depth,
39085999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->TexFormat->MesaFormat);
39095999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ASSERT(dstImage->CompressedSize > 0);
39105999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      }
39115999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
3912d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
39134f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
39144f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3915d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
391689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
391789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
391889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
391989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
39204cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
392189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
392289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
392389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
392489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
39252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
392689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
392789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
392889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
392989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
39305999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         bytesPerTexel = dstImage->TexFormat->TexelBytes;
393189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
39324cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
39334cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul                                                * dstDepth * bytesPerTexel);
393489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
393589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
393689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
393789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
393889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
393989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3940d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3941d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3942d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3943d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3944d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3945d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
394689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
39472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
394889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
394989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
395089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
395189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
395289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
395389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
395489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
395589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
395689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
395789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
39582ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
395989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
396089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
396189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
396289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
39632ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
396489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
396589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
396689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
396789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
396889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
396989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
397089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
397189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
397289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3973d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
397489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
397589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
397689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
39772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
39782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
3979a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         GLint dstRowStride
39805999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth);
39812ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
3982a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
39838f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
39848f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
39858f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
39868f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
39878f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
39888f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
39898f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
39908f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
399189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
399289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
399389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
399489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
399589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
399689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3997d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
39983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
399980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
400080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
400180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
400280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
400380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
400480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
400580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
400680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
400780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
40081cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
40091cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
40101cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
40111cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
40121cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
40131cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
40141cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
401580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
401680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
401780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
401880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
401980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
402080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
402180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
402280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
40231cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
402480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
402580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
402680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
402780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
402880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
402980fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
403080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
403180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
403280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
40331cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
403480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
40351cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
403680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
403780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
403880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
403980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
404080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
404180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
404280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
404380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
404480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
404580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
40461cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
404780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
404880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
404980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
405080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
405180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
405280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
405380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
405480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
405580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
405680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
405780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
405880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
405980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
406080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
406180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
406280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
406380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
406480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
406580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
406680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
406780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
406880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
406980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
407080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
407180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
407280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
407333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
407433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
407533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
407633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
407733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
407833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
407933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
408033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
408133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
408233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
408333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
408433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
408533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
408633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
408733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
408833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
408933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
409033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
4091701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
409233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
409333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
409433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
409533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
409633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
409733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
409833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
409933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
410033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
410133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
410233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
410333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
410433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
410533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
410633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
410768d293b03535ca50daf70650b32db780f1718a3bBrian Paul
410868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
410968d293b03535ca50daf70650b32db780f1718a3bBrian Paul
411068d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
411168d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetTexImage().
411268d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
411368d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
411468d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
411568d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
411668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   GLenum format, GLenum type, GLvoid *pixels,
4117ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_object *texObj,
4118ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_image *texImage)
411968d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
412068d293b03535ca50daf70650b32db780f1718a3bBrian Paul   GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
412168d293b03535ca50daf70650b32db780f1718a3bBrian Paul
412268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
412368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
412468d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
412568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
412668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     texImage->Height, texImage->Depth,
412768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     format, type, pixels)) {
412868d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
412968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetTexImage(invalid PBO access)");
413068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
413168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
413268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
413368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
413468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
413568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
413668d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
413768d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
413868d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
413968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
414068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      pixels = ADD_POINTERS(buf, pixels);
414168d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
414268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!pixels) {
414368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
414468d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
414568d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
414668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
414768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   {
414868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint width = texImage->Width;
414968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint height = texImage->Height;
415068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint depth = texImage->Depth;
415168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLint img, row;
415268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      for (img = 0; img < depth; img++) {
415368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         for (row = 0; row < height; row++) {
415468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            /* compute destination address in client memory */
415568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
415668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                width, height, format, type,
415768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                img, row, 0);
415868d293b03535ca50daf70650b32db780f1718a3bBrian Paul            assert(dest);
415968d293b03535ca50daf70650b32db780f1718a3bBrian Paul
416068d293b03535ca50daf70650b32db780f1718a3bBrian Paul            if (format == GL_COLOR_INDEX) {
416168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLuint indexRow[MAX_WIDTH];
416268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
416368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* Can't use FetchTexel here because that returns RGBA */
416468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if (texImage->TexFormat->IndexBits == 8) {
416568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLubyte *src = (const GLubyte *) texImage->Data;
4166184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
416768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4168184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
416968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
417068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
417168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (texImage->TexFormat->IndexBits == 16) {
417268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLushort *src = (const GLushort *) texImage->Data;
4173184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
417468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4175184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
417668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
417768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
417868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else {
417968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_problem(ctx,
418068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                "Color index problem in _mesa_GetTexImage");
418168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
418268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_index_span(ctx, width, type, dest,
418368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     indexRow, &ctx->Pack,
418468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     0 /* no image transfer */);
418568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
418668d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_DEPTH_COMPONENT) {
418768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat depthRow[MAX_WIDTH];
418868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
418968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
419068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img,
419168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                           depthRow + col);
419268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
419368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_depth_span(ctx, width, dest, type,
419468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     depthRow, &ctx->Pack);
419568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
4196184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            else if (format == GL_DEPTH_STENCIL_EXT) {
4197184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               /* XXX Note: we're bypassing texImage->FetchTexel()! */
4198184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               const GLuint *src = (const GLuint *) texImage->Data;
4199184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               src += width * row + width * height * img;
4200184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               _mesa_memcpy(dest, src, width * sizeof(GLuint));
4201184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               if (ctx->Pack.SwapBytes) {
4202184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  _mesa_swap4((GLuint *) dest, width);
4203184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               }
4204184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            }
420568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_YCBCR_MESA) {
420668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* No pixel transfer */
420768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               const GLint rowstride = texImage->RowStride;
420868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               MEMCPY(dest,
420968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      (const GLushort *) texImage->Data + row * rowstride,
421068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      width * sizeof(GLushort));
421168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* check for byte swapping */
421268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
421368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
421468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
421568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
421668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  if (!ctx->Pack.SwapBytes)
421768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     _mesa_swap2((GLushort *) dest, width);
421868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
421968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (ctx->Pack.SwapBytes) {
422068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_swap2((GLushort *) dest, width);
422168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
422268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
422368d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else {
422468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* general case:  convert row to RGBA format */
422568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat rgba[MAX_WIDTH][4];
422668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
422768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
422868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
422968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
423068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_rgba_span_float(ctx, width,
423168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          (const GLfloat (*)[4]) rgba,
423268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          format, type, dest, &ctx->Pack,
423368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          0 /* no image transfer */);
423468d293b03535ca50daf70650b32db780f1718a3bBrian Paul            } /* format */
423568d293b03535ca50daf70650b32db780f1718a3bBrian Paul         } /* row */
423668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      } /* img */
423768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
423868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
423968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
424068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
424168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
424268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
424368d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
424468d293b03535ca50daf70650b32db780f1718a3bBrian Paul
424568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
424668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
424768d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
424868d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetCompressedTexImage().
424968d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
425068d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
425168d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
425268d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
425368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              GLvoid *img,
425468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_object *texObj,
425568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_image *texImage)
425668d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
425768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
425868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
425968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
426068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if ((const GLubyte *) img + texImage->CompressedSize >
426168d293b03535ca50daf70650b32db780f1718a3bBrian Paul          (const GLubyte *) ctx->Pack.BufferObj->Size) {
426268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
426368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(invalid PBO access)");
426468d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
426568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
426668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
426768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
426868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
426968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
427068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
427168d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
427268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(PBO is mapped)");
427368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
427468d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
427568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      img = ADD_POINTERS(buf, img);
427668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
427768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!img) {
427868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
427968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
428068d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
428168d293b03535ca50daf70650b32db780f1718a3bBrian Paul
428268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   /* just memcpy, no pixelstore or pixel transfer */
428368d293b03535ca50daf70650b32db780f1718a3bBrian Paul   MEMCPY(img, texImage->Data, texImage->CompressedSize);
428468d293b03535ca50daf70650b32db780f1718a3bBrian Paul
428568d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
428668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
428768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
428868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
428968d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
4290