texstore.c revision a9fc8ba756dd25a07dc19058fe60f65bda82a055
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
3c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Version:  6.3
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
5c039af165d5919008c6df599795951f85dea164dBrian Paul * Copyright (C) 1999-2005  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];
56371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint 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
64071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   compute_component_mapping(srcFormat, GL_RGBA, srcmap);
64171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   for (i = 0; i < 4; i++)
64371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      map[i] = srcmap[dstmap[i]];
64471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
64571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   if (srcRowStride == srcWidth * srcComponents &&
64671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       (srcImageStride == srcWidth * srcHeight * srcComponents ||
64771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell        srcDepth == 1)) {
64871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
64971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell		   srcWidth * srcHeight * srcDepth);
65071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
65171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else {
65271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLint img, row;
65371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
65471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLubyte *srcRow = srcImage;
65571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
65671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
65771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
65871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
65971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
66071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
66171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         srcImage += srcImageStride;
66271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
66371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
66471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
66571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
66671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
66771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
67417bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwellmemcpy_texture(GLcontext *ctx,
67517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell	       GLuint dimensions,
67660909388ab136d849d99eab49e782a53772a618fBrian Paul               const struct gl_texture_format *dstFormat,
677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstRowStride, GLint dstImageStride,
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
68960909388ab136d849d99eab49e782a53772a618fBrian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
69060909388ab136d849d99eab49e782a53772a618fBrian Paul        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
70517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
71317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  either 1 or 2 or 3
735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat  user-specified base internal format
736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat  destination Mesa texture format
737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr  destination image address
738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride  destination image row stride, in bytes
740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride  destination image layer stride, in bytes
741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth  source image size, in pixels
742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  incoming image format
743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  incoming image data type
744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image packing parameters
746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum baseInternalFormat,
750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_texture_format *dstFormat,
751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLvoid *dstAddr,
752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstRowStride, GLint dstImageStride,
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum srcFormat, GLenum srcType,
756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const GLvoid *srcAddr,
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_pixelstore_attrib *srcPacking)
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
78017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
78160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstZoffset * dstImageStride
795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstYoffset * dstRowStride
796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstXoffset * dstFormat->TexelBytes;
797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
80060909388ab136d849d99eab49e782a53772a618fBrian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
80160909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
8178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
8249c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
8339c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
851a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a floating point depth component texture image.
852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
854a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component_float32(STORE_PARAMS)
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
856a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
857a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
858a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
862a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
863a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
864a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_FLOAT) {
865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
86617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
86760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
88260909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
8841ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
8851ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul                                    GL_FLOAT, (GLfloat *) dstRow, 1.0F,
886a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                    srcType, src, srcPacking);
887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
897a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
900a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_depth_component16(STORE_PARAMS)
901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
902a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
903a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component16);
904a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
910a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
91217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
91360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
9241ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul      GLint img, row;
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
92860909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
930a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
9311ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
9321ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul                                    GL_UNSIGNED_SHORT, dst16, 65535.0F,
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
944defb035b6cf03c555318d9dd48864242ed036f39Brian Paul * Store an rgb565 or rgb565_rev texture image.
945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
947a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_rgb565(STORE_PARAMS)
948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
949defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
950defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgb565_rev);
951a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 2);
952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
955defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgb565 &&
956a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
957a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
958a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
96017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
96160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
962f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
964f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
965f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
966a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
967a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
968a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
969a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
970a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
971a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
972a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
973a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
974a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
975a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
97660909388ab136d849d99eab49e782a53772a618fBrian Paul         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
977a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
978a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
979a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstZoffset * dstImageStride
980a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstYoffset * dstRowStride
981a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstXoffset * dstFormat->TexelBytes;
982a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint row, col;
983a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (row = 0; row < srcHeight; row++) {
984a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLubyte *srcUB = (const GLubyte *) src;
985a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLushort *dstUS = (GLushort *) dst;
986defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         /* check for byteswapped format */
987f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         if (dstFormat == &_mesa_texformat_rgb565) {
988f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
989f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
990f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
991f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
992f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         }
993f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         else {
994f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
995f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
996f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
997f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
998defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         }
999a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dst += dstRowStride;
1000a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         src += srcRowStride;
1001a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1002a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1004f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1005a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1006a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1007a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1008a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1009a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1010a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1011a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1015f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1017a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1018a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1019a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1021f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1022f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1023a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
1024defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
1025f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
1026f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1027f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1028f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
1029f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
1030f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1031f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1032f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1033f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1034f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1035f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1036f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
1037f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
1038f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1039f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS)
1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
105471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLuint ui = 1;
105571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   const GLubyte littleEndian = *((const GLubyte *) &ui);
105671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
105771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   (void)littleEndian;
1058defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
1059defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1064defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1066defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1067defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
106917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
107060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
107571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell#if 0
107671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
107771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    !srcPacking->SwapBytes &&
107871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
107971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_rgba8888 &&
108071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    littleEndian &&
1081ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    /* Three texture formats involved: srcFormat,
1082ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * baseInternalFormat and destFormat (GL_RGBA). Only two
1083ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * may differ. _mesa_swizzle_ubyte_image can't handle two
1084ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * propagations at once correctly. */
1085ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    (srcFormat == baseInternalFormat ||
1086ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     baseInternalFormat == GL_RGBA) &&
108771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
108871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
108971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
109071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      /* dstmap - how to swizzle from GL_RGBA to dst format:
109171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       *
109271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       * FIXME - add !litteEndian and _rev varients:
109371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
109471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[3] = 0;
109571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[2] = 1;
109671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[1] = 2;
109771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[0] = 3;
109871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
109971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
110071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
110171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
110271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
110371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstRowStride, dstImageStride,
110471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
110571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
110671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
110771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell#endif
1108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11108f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
1129f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
1130f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1131f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1132f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1133f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
1134f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
1135f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1136f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1138f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1139f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1140f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1141f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1142f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
1143f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
1144f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1145f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1146a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1147a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1148a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1149a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1150a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1151a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1152a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1153a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1154a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1155a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1156a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1157a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS)
1159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1163defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
1164defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
1165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1169defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
1170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1173defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1174defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
117517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
117660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1181defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
1182a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1183defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
1184a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
1185a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
1186a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1187defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1188defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
118917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
119060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1191a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1192a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1193a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1194a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
119571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
119671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
119771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
119871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGB &&
119971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
120071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
120171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      int img, row, col;
120271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte *dstImage = (GLubyte *) dstAddr
120371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstZoffset * dstImageStride
120471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstYoffset * dstRowStride
120571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstXoffset * dstFormat->TexelBytes;
120671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
120771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
120871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
120971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
121071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
121171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
121271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
121371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
121471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
121571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
121671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
121771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = 0xff;
121871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
121971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
122071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
122171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
122271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
122371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
122471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
122571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
122671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
122771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
122871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGBA &&
122971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
123071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
123171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      int img, row, col;
123271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte *dstImage = (GLubyte *) dstAddr
123371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstZoffset * dstImageStride
123471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstYoffset * dstRowStride
123571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                        + dstXoffset * dstFormat->TexelBytes;
123671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
123771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
123871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
123971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
124071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
124171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *dstRow = dstImage;
124271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
124371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
124471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
124571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
124671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
124771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
124871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
124971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
125071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
125171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
125271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         dstImage += dstImageStride;
125371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
125471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
125571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
125671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    !srcPacking->SwapBytes &&
125771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
125871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
125971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    littleEndian &&
1260ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    /* Three texture formats involved: srcFormat,
1261ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * baseInternalFormat and destFormat (GL_RGBA). Only two
1262ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * may differ. _mesa_swizzle_ubyte_image can't handle two
1263ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     * propagations at once correctly. */
1264ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	    (srcFormat == baseInternalFormat ||
1265ffd97d20aaa1cf7fa683d25deb0391f24ff14589Felix Kuehling	     baseInternalFormat == GL_RGBA) &&
126671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
126771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
126871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
126971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
127071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      /* dstmap - how to swizzle from GL_RGBA to dst format:
127171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
127271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[3] = 3;		/* alpha */
127371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[2] = 0;		/* red */
127471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[1] = 1;		/* green */
127571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      dstmap[0] = 2;		/* blue */
127671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
127771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
127871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
127971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
128071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
128171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstRowStride, dstImageStride,
128271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
128371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
128471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
1285a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1286a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1287a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1288a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1289a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1290a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1291a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1292a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1293a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1294a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1295a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1296a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1297a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1298a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1299a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1300a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1301a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1302a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1303a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1304a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1305a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1306f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1307f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1308f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1309f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1310f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1311f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1312f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1313f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1314a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1315f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1316f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1317f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1318f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1319f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1320f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1321f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1322f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1323defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1324a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1325a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1326a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1327a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1328a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1329a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1330a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1331a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1332a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS)
1336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
135017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
135160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1360a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
1362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
136960909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
137060909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13868f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
13927c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1440a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul_mesa_texstore_bgr888(STORE_PARAMS)
1441a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1442a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLuint ui = 1;
1443a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1444a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1445a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1446a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1447a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1448a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1449a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1450a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1451a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1452a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1453a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1454a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
145517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
145660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1457a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     dstRowStride, dstImageStride,
1458a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1459a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1460a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1461a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1462a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1463a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1464a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1465a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1466a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1467a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1468a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1469a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1470a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1471a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1472a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1473a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
147460909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
147560909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1476a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1477a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1478a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1479a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1480a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1481a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1482a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1483a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1484a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1485a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1486a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1487a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1488a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1489a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1490a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1491a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1492a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1493a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1494a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1495a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1496a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
14977c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1498a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1499a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstZoffset * dstImageStride
1500a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstYoffset * dstRowStride
1501a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                        + dstXoffset * dstFormat->TexelBytes;
1502a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1503a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1504a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1505a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1506a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1507a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLubyte *dstRow = dstImage;
1508a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1509a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1510a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1511a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1512a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1513a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1514a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1515a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1516a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1517a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1518a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1519a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1520a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1521a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1522a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1523a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1524a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1525a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS)
1527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1528defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1529defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1534defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1537defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
153917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
154060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
15478f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1566f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1567f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1568f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1569f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1570f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1571f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1572f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1573f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1575f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1576f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1577f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1578f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1579f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1580f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1581f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1582f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1583a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1584a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1585a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1586a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1587a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1588a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1589a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1590a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1591a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1592a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1593a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1594defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1595a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS)
1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1598defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1599defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1604defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1607defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
160917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
161060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
16178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1636f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1637f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1638f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1639f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1640f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1641f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1642f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1643f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1645f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1646f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1647f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1648f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1649f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1650f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1651f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1652f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1653a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1654a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1655a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1656a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1657a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1658a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1659a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1660a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1661a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1662a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS)
1666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1670defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1671defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1676defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
168217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
168360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
16908f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1709f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
1710f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1711f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1712f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
1713f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
1714f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1715f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1717f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1718f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1719f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
1720f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
1721f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
1722f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
1723f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1724a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1725a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1726a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1727a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dstImage += dstImageStride;
1728a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1729a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1730a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1731a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1732a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1733a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1734a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1735a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS)
1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
174617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
174760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
17548f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS)
1793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
180417bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
180560909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
18128f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS)
1847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1848a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
1849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
185817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
185960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
187460909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS)
1893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1896a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
190817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell   memcpy_texture(ctx, dims,
190960909388ab136d849d99eab49e782a53772a618fBrian Paul                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRowStride, dstImageStride,
1911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
1920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLushort *pImage = (GLushort *) ((GLubyte *) dstAddr
1921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstZoffset * dstImageStride
1922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstYoffset * dstRowStride
1923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstXoffset * dstFormat->TexelBytes);
1924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *pRow = pImage;
1927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_swap2(pRow, srcWidth);
1929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            pRow += dstRowStride;
1930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         pImage += dstImageStride;
1932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1939184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul/**
1940184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul * Store a combined depth/stencil texture image.
1941184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul */
1942184a9707227ab024d65d352fe7c09b3e287348e9Brian PaulGLboolean
1943184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul_mesa_texstore_z24_s8(STORE_PARAMS)
1944184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul{
1945184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z24_s8);
1946184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
1947184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
1948184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1949184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   if (!ctx->_ImageTransferState &&
1950184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul       !srcPacking->SwapBytes) {
1951184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul      memcpy_texture(ctx, dims,
1952184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1953184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstRowStride, dstImageStride,
1954184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1955184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcAddr, srcPacking);
1956184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
1957184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   else {
1958184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul      _mesa_problem(ctx, "_mesa_texstore_z24_s8 not finished");
1959184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
1960184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1961184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1962184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   return GL_TRUE;
1963184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul}
1964184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1965184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
1966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
1969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
1970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
1971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
1972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
1973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
1974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
1975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS)
1978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
1982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
1983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
1985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
1986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
1987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
1994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1996f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
1999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
200017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
200160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
2003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2004f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2005f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2006f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2009f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2010f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2011f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
20159c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
2016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
2017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
2018f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
2019f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
2020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2021f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2022f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2023f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
20249c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
2025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2026f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dst = dstImage;
2027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dst, src, bytesPerRow);
2029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += dstRowStride;
2030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
2033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS)
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
2062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
2067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
206817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
206960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
2071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
2083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
2084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
2085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
2086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
2087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
2093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
2103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
21127a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2113c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
2114c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2115c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
211671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
21177a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
211871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
211971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
212071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLsizei width, GLsizei height, GLsizei depth,
212171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLenum format, GLenum type, const GLvoid *pixels,
212271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const struct gl_pixelstore_attrib *unpack,
212371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const char *funcName)
21247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2125c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2126c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
21277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
21287a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
21297a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
21307a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
213160909388ab136d849d99eab49e782a53772a618fBrian Paul   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
213260909388ab136d849d99eab49e782a53772a618fBrian Paul                                  format, type, pixels)) {
2133c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2134c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
21357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2136c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2137a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2138a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                          GL_READ_ONLY_ARB, unpack->BufferObj);
2139c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2140c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2141c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2142c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2143c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2144c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
21457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
21467a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
21477a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
21487a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2149c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
2150c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
2151c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2152c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
215371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
21547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
215571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
215671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
2157c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
2158c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
2159c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
21607a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2161c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2162c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
21637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
21647a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
21657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
21667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2167c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
21686258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz       (const GLubyte *)(uintptr_t) packing->BufferObj->Size) {
2169c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
2170c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2171c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2172c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2173c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2174a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2175a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                         GL_READ_ONLY_ARB, packing->BufferObj);
2176c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2177c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2178c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
21797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2180c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2181c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
21827a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
21837a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
21847a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2185c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
2186c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
2187c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
2188c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
218971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellvoid
2190c039af165d5919008c6df599795951f85dea164dBrian Paul_mesa_unmap_teximage_pbo(GLcontext *ctx,
2191c039af165d5919008c6df599795951f85dea164dBrian Paul                         const struct gl_pixelstore_attrib *unpack)
2192c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
2193c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
2194c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2195c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
2196c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2197c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
2198c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
219989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2200da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2201da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2202da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a GLchan texel from a float-valued texture.
2203da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2204da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2205da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelFloatToChan( const struct gl_texture_image *texImage,
2206da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLchan *texelOut )
2207da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2208da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLfloat temp[4];
2209da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2210da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelf(texImage, i, j, k, temp);
2211da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
2212da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2213da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2214da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2215da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2216da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2217da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2218da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
2219da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
2220da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
2221da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2222da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2223da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2224da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2225da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2226da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a float texel from a GLchan-valued texture.
2227da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2228da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2229da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelChanToFloat( const struct gl_texture_image *texImage,
2230da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLfloat *texelOut )
2231da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2232da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLchan temp[4];
2233da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2234da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelc(texImage, i, j, k, temp);
2235da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
2236da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2237da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2238da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2239da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2240da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2241da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2242da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
2243da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
2244da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
2245da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2246da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2247da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2248da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2249da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2250da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Initialize the texture image's FetchTexelc and FetchTexelf methods.
2251da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2252da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2253da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulset_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
2254da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2255da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2256da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->TexFormat);
2257da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2258da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   switch (dims) {
2259da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 1:
2260da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
2261da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
2262da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2263da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 2:
2264da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
2265da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
2266da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2267da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 3:
2268da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
2269da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
2270da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2271da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   default:
2272da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      ;
2273da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2274da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2275da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   /* now check if we need to use a float/chan adaptor */
2276da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (!texImage->FetchTexelc) {
2277da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = FetchTexelFloatToChan;
2278da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2279da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else if (!texImage->FetchTexelf) {
2280da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = FetchTexelChanToFloat;
2281da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2282da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2283da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2284da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2285da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2286da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2287da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2288da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
22897d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
229089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
2291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
22926b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
22938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
22948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
22958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
22968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
22978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
22988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
22998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
23008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
23018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
23028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
23038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
2304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
2305a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
23068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
23088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
23098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
23108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
23127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
2313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
2314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                         format, type);
23157d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
2316da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   set_fetch_functions(texImage, 1);
23178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
231989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
232089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
232189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
2322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
23234cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
23247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
23257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
23267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
23277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
23288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2329e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2330e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage1D");
23316b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
23326b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
23336b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
23346b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
233589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
23366b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
23376b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2341a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
2350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2352f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
235389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
235489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
235589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
235689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
235789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
23583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2359c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
236071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
23618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
23628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23646b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
236589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
236689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
23676b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * We store the image in heap memory.  We know nothing about on-board
23686b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * VRAM here.  But since most DRI drivers rely on keeping a copy of all
23696b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * textures in main memory, this routine will typically be used by
23706b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * hardware drivers too.
23716b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *
2372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
23736b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Special memory allocation needs (VRAM, AGP, etc)
23746b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Unusual row/image strides or padding
2375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
23766b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *  - Using VRAM-based Pixel Buffer Objects
23778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
23788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
23798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
23808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
23818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
23828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
23838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
23848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
23858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
23868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
23878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
2388e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2389a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
23908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
23928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
23938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
23948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
23958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
23967d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
23977d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
23987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
23997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
24007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
2401da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   set_fetch_functions(texImage, 2);
24022c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
24032c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
24048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
240689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
240789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
240889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
240989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
24104cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
24117d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
24127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
24137d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
24147d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
24158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
241671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2417e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage2D");
24186b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
24196b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
24206b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
24216b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
242289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
24236b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
24246b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
2426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2428a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
2429a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul            = _mesa_compressed_row_stride(texImage->InternalFormat,width);
2430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
24329c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
2433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2435a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2446f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
244789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
244889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
244989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
245089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
245189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
24523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2453c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
245471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
24558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
24568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24596b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
246089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
246189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
24626b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
24638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
24648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
24658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
24668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
24678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
24688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
24698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
24708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
24718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
24728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2473e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2474a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
24758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24767d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
24777d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
24787d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
24797d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
24807d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
2481da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   set_fetch_functions(texImage, 3);
24822c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
2483197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
24848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
24858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
248689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
248789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
248889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
248989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
24904cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
24917d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
24927d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
24937d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
24947d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
24958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2496e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2497e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing, "glTexImage3D");
24986b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
24996b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
25006b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
25016b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
250289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
25036b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
25046b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2508a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
2509a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul            = _mesa_compressed_row_stride(texImage->InternalFormat,width);
2510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
2511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
2514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
2515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2517a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
2526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2528f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
252989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
253089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
253189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
253289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
253389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
25343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2535c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
253671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
25378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
25388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
254389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
254489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
25458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
25468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
25478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
25488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
25498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
25508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
25518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
25528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
25538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2554e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2555e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage1D");
25567a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
25577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
25587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
2561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2563a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
2567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
2572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
25743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
25753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
25763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2577d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2578d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
25793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
25803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2581c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
258271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
25838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
25848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
25858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
258889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
258989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
25908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
25918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
25928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
25938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
25948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
25958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
25968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
25978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
25988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
25998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
260071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2601e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage2D");
26027a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
26037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
26047a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
2607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2609a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
2610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2616a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
2620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
26273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
26293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2630d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2631d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
26323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
26333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2634c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
263571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
26368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
26378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
26398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
26408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
264189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
26428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
26438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
26448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
26458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
26468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
26478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
26488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
26498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
26508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
26518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2652e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
2653e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing,
2654e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        "glTexSubImage3D");
2655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2662a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
2663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2671a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
2672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
26828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian 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
26942aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
26958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
26968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
26978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
26988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
26998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
27008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
27018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
27028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
27038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
27048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
270589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2706a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2707a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2708a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2709a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
2710a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2711a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2712a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
27138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
27188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
27198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
27208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
27228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
27238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
27248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
27258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
27268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
27278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2728a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
2729a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
273089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
273189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
27328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
273389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
273489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
273589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
273689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
273789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
273889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
273989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
274089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
274189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
274289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
274389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
274489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
2745da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   set_fetch_functions(texImage, 2);
274689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
274789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
27484cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(imageSize);
274989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
275089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
275189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
275289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
275389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2754e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2755e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2756e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexImage2D");
27577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
27587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
27597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
276089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
27614039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
276289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
27638f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
27648f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
27658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
27668f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
27678f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
27688f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
27698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2770c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
277171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
27728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
27778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
27788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
27798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
27808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
27818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
27828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
27838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
27848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
27858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
27868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
27878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
278889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2789a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2790a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2791a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
2792a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2793a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
2794a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2795a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2796a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
27978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
27988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
27998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
280189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
280289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2803e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2804e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
280589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
280689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
280789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
280889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
280989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
281089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
281189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2812e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
281389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2814a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2815a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2816a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
2817a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2818a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2819a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2820a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
2821e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2822e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2823e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
282489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
282589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
282689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
282789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
282889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
282989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
283089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
283189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
283289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
283389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
283489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
283589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
283689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
283789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
283889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
283989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
284089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
2841a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
284289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
284389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
284489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
284589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
284689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
284789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
284889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2849e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
2850e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
2851e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexSubImage2D");
28527a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
28537a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
28547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2855a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->InternalFormat, width);
285689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
285789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2858a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,
285989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
286089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
2861a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                         texImage->InternalFormat,
2862f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2863f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
286489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
286589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
286689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
286789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
286889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
286989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
287089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
287189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
287289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
28738f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
28748f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
28758f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
28768f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
28778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
28788f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
28798f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
2880c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
288171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
288289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
288389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
288489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
288589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
288689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
288789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
288889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
288989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
289089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
289189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
289289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
289389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
289489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
289589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
289689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
289789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
289889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2899a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
2900a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
2901a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
2902a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
2903a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
2904a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
2905a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
2906a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
290789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
290889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
290989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
29103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
29113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
29123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
29139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
29149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
29153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
29163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
29179228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
29189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
29199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
29203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
29229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
29239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
2924c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
29259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
2926c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
29279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
29293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
29303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
29319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
29323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
29333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
29343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
29357c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
29369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
29379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2938f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
29399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2940f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
29419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2942f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
29439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2944f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
29453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
29463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
29473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
29483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
29493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
29509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
29513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
29523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
29533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
29547c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
29559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
29569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2957f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
29589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2959f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
29609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2961f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
29623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
29633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
29643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
29653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
29663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
29673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
29683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
29699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
29703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
29713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
29723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
29737c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
29749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
2975f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
29763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
29773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
29783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
29793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
29803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
29819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
29823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
29833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
29843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
29857c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
29869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
29879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2988f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
29899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2990f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
29913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
29923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
29933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
2994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
29958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
29969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
29978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
29988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
29998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
30007c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
30038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
30048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
30058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3006f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT16:
3007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3009f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
3010f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
3011f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
3012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
3015f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
30188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
30198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
3020defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
30218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
3022defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
30238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
30249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
30268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
30278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
30287c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3031f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3033f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3035f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3037f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
30388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
30398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
30408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
30418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
3042a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
30438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
30449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
30468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
30478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
30487c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3051f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
30529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3053f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
30549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3055f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
30568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
30578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
30588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
30598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
3060defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
30618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
30629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
30648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
30658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
30667c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
30699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
30709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
30719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
30729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
30739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
30749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
30759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
30769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
30779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
30789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
30799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
308007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
308107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
308207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
30838bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
30848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
30858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
30868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
30878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
3088defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
30898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
30909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
30918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
30928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
30938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
30947c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
30959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
30969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
30979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
30989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
30999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
31009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
31019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
31029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
31039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
31049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
31059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
31069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
31079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
31089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
31099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
31109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
31119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
311207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
311307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
311407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
311507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
31168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
31178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
3121defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
31228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
31258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
31268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
31277c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
31309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
31319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
31329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
31339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
31349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
31359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
31369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
31379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
31389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
31399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
31409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
31419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
31429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
31439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
31449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
314507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
314607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
314707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
314807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
31498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
31508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
3154defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
31558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
31588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
31598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
31607c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
31639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
31649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
31659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
31668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31688bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31698bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
31708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
31719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
31728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
31738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
31748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
31757c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
31769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
31779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
31789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
31799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
31809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
31819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
31829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
31839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
31849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
31859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
31869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
31879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
31889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
318907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
319007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
319107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
31928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
31938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
31948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
31958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
31968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
31978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
31988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
31998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
32008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
32019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
32028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
32038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
32048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
32057c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
32069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
32079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
32088bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
32098bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
32108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
3212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
3215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
3216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
3217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
3227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
3231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
3234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
3235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
3236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
3239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
3250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
3253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
3254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
3255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
3267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
3270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
3271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
3272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
3275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
3286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
3289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
3290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
3291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
3301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
3304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
3305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
3306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
3309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
3320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
3321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
3322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
3325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
3326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
3327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
3330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
3334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
3335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
3336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
3339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
3340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
3341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
3344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
3345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
3346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
3347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
3348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
33533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
33543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
33553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
33563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
33573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
33609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
33619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
33629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
33639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
33643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
33663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
33673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
33683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
33693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
33703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
33713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
33723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
33733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
33753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
33763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
33773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
33799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
33809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
33813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
33833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
33843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
33853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
33863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
33873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
33883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
33893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
33903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
33913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
33933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
33943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
33953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
33963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
33973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
33983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
33999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
34009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
34019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
34023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
34033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
34043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
34053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
3406462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
34073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
34093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
34103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
34113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
34123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
34133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
34143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
34153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
34179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
34189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
34193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
34203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
34213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
34223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
34233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
34253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
34263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
34273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
34283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
34293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
34303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
34313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
34323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
34333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
34343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
34353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
34363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
34373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
34383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
34399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
34409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
34419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
34429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
34433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
34449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
34453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
34463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
34479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
34483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
34493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
34509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
34519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
34529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
34539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
34549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
34559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
34569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
34579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
34589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
34599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
34609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
34619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
34629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
34639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
34649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
34659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
34669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
34679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
34689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
34699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
34709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
34713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
34723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
34733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
34743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
34773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
34783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
34793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
34803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
34813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
34823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
34839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
34849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
34859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
34869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
34879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
34889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
34899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
34903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
34919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
34929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
34939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
34943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
34955c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
34965c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
34979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
34982dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowA = _mesa_malloc(srcWidth * bpt);
34999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
35009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
35012dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowB = _mesa_malloc(srcWidth * bpt);
35029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
35032dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      _mesa_free(tmpRowA);
35043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
35053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
35089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
35099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
35119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
35123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
35149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
35153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
35179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
35183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
35209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
35219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
35229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
35239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
35249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
35259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
35263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
35284e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
35299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
35309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
35319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
35339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
35349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
35359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
35369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
35379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
35389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
35399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
35409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
35419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
35429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
35439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
35459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
35469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
35479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
35489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
35499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
35509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
35529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
35539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
35549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
35559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
35569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
35579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
35589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
35599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
35609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
35619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
35629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
35639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
35649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
35659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
35669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
35673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
35683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
35693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
35702dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowA);
35712dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowB);
35729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
35749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
35759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
35769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
35779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
35789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
35799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
35809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
35819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
35829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
35839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
35849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
35859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
35869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
35879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
35889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
35899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
35919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
35929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
35939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
35949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
35959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
35969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
35979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
35989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
35999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
36009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
36019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
36039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
36049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
36059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
36069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
36079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
36089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
36109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
36119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
36129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
36139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
36149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
36159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
36169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
36179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
36189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
36199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
36209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
36219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
36229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
36239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
36259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
36269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
36279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
36289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
36309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
36319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
36329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
36339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
36349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
36359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
36379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
36389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
36399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
36409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
36419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
36429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
36439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
36449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
36459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
36469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
36479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
36489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
36499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
36509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
36519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
36523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
36533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
36563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
36573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
36583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
36593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
36603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
3661d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
36623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
36633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
36643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
36652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
36662ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
3667b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
3668b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
3669ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
36703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
3672c039af165d5919008c6df599795951f85dea164dBrian Paul   /* XXX choose cube map face here??? */
367318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
36742ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
36753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3676ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3677ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
36783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
36792ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
36802ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
36812ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3682d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3683d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
36842ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
36852ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
36862ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
36872ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
3688a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      if (srcImage->_BaseFormat == GL_RGB) {
36892ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
36902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
36912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3692a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      else if (srcImage->_BaseFormat == GL_RGBA) {
36932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
36942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
36952ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
36962ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
3697a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
36982ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
36992ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
37002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
37012ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
3702a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
37032ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
37042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
37052dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      srcData = (GLubyte *) _mesa_malloc(size);
37062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
37072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
37082ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
37092ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
37102dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */
37112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
37122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
37132dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul         _mesa_free((void *) srcData);
37142ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
37152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
37162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
37172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
37182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
37192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3720d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
37212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
37224f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
37232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
372489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
372589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
372689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
37272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
37282ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
37292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
37302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
373189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
37328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3733cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
37349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
37353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
37363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
37373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
37383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
37393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
37403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
374189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
37423ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
37433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
37443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
37453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
37463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
37473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
37483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
37503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
37513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
37523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
37543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
37553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
37573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
37583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
37603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
37613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
37633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
37643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
37663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
37673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
37693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
37703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
37713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
37723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
377389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
37742dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free((void *) srcData);
37752dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free(dstData);
377689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
37773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
37783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
37793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3780d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3781a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3782d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3783a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3784a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3785d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
37863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3787d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3788d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
37894cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         ctx->Driver.FreeTexImageData(ctx, dstImage);
3790d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3791d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3792e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
3793a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                 dstDepth, border, srcImage->InternalFormat);
3794d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3795d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
37964f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
37974f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
3798d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
37994f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
38004f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3801d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
380289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
380389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
380489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
380589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
380689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
38074cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
380889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
380989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
381089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
381189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
38122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
381389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
381489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
381589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
381689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
381789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
381889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
38194cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
38204cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul                                                * dstDepth * bytesPerTexel);
382189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
382289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
382389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
382489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
382589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
382689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3827d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3828d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3829d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3830d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3831d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3832d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
383389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
38342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
383589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
383689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
383789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
383889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
383989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
384089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
384189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
384289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
384389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
384489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
38452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
384689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
384789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
384889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
384989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
38502ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
385189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
385289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
385389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
385489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
385589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
385689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
385789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
385889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
385989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3860d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
386189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
386289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
386389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
38642ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
38652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
3866a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         GLint dstRowStride
3867a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul            = _mesa_compressed_row_stride(srcImage->InternalFormat, dstWidth);
38682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
3869a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
38708f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
38718f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
38728f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
38738f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
38748f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
38758f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
38768f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
38778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
387889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
387989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
388089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
388189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
388289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
388389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3884d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
38853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
388680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
388780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
388880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
388980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
389080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
389180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
389280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
389380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
389480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
38951cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
38961cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
38971cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
38981cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
38991cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
39001cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
39011cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
390280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
390380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
390480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
390580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
390680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
390780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
390880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
390980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
39101cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
391180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
391280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
391380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
391480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
391580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
391680fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
391780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
391880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
391980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
39201cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
392180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
39221cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
392380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
392480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
392580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
392680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
392780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
392880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
392980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
393080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
393180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
393280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
39331cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
393480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
393580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
393680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
393780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
393880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
393980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
394080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
394180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
394280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
394380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
394480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
394580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
394680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
394780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
394880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
394980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
395080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
395180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
395280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
395380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
395480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
395580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
395680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
395780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
395880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
395980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
396033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
396133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
396233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
396333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
396433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
396533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
396633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
396733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
396833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
396933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
397033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
397133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
397233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
397333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
397433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
397533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
397633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
397733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
3978701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
397933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
398033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
398133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
398233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
398333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
398433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
398533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
398633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
398733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
398833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
398933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
399033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
399133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
399233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
399333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
399468d293b03535ca50daf70650b32db780f1718a3bBrian Paul
399568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
399668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
399768d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
399868d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetTexImage().
399968d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
400068d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
400168d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
400268d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
400368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   GLenum format, GLenum type, GLvoid *pixels,
400468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   const struct gl_texture_object *texObj,
400568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   const struct gl_texture_image *texImage)
400668d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
400768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
400868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
400968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
401068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
401168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
401268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
401368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     texImage->Height, texImage->Depth,
401468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     format, type, pixels)) {
401568d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
401668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetTexImage(invalid PBO access)");
401768d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
401868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
401968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
402068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
402168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
402268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
402368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
402468d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
402568d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
402668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
402768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      pixels = ADD_POINTERS(buf, pixels);
402868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
402968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!pixels) {
403068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
403168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
403268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
403368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
403468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   {
403568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint width = texImage->Width;
403668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint height = texImage->Height;
403768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint depth = texImage->Depth;
403868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLint img, row;
403968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      for (img = 0; img < depth; img++) {
404068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         for (row = 0; row < height; row++) {
404168d293b03535ca50daf70650b32db780f1718a3bBrian Paul            /* compute destination address in client memory */
404268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
404368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                width, height, format, type,
404468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                img, row, 0);
404568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            assert(dest);
404668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
404768d293b03535ca50daf70650b32db780f1718a3bBrian Paul            if (format == GL_COLOR_INDEX) {
404868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLuint indexRow[MAX_WIDTH];
404968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
405068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* Can't use FetchTexel here because that returns RGBA */
405168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if (texImage->TexFormat->IndexBits == 8) {
405268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLubyte *src = (const GLubyte *) texImage->Data;
4053184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
405468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4055184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
405668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
405768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
405868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (texImage->TexFormat->IndexBits == 16) {
405968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLushort *src = (const GLushort *) texImage->Data;
4060184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
406168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4062184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
406368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
406468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
406568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else {
406668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_problem(ctx,
406768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                "Color index problem in _mesa_GetTexImage");
406868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
406968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_index_span(ctx, width, type, dest,
407068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     indexRow, &ctx->Pack,
407168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     0 /* no image transfer */);
407268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
407368d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_DEPTH_COMPONENT) {
407468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat depthRow[MAX_WIDTH];
407568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
407668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
407768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img,
407868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                           depthRow + col);
407968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
408068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_depth_span(ctx, width, dest, type,
408168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     depthRow, &ctx->Pack);
408268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
4083184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            else if (format == GL_DEPTH_STENCIL_EXT) {
4084184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               /* XXX Note: we're bypassing texImage->FetchTexel()! */
4085184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               const GLuint *src = (const GLuint *) texImage->Data;
4086184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               src += width * row + width * height * img;
4087184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               _mesa_memcpy(dest, src, width * sizeof(GLuint));
4088184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               if (ctx->Pack.SwapBytes) {
4089184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  _mesa_swap4((GLuint *) dest, width);
4090184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               }
4091184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            }
409268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_YCBCR_MESA) {
409368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* No pixel transfer */
409468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               const GLint rowstride = texImage->RowStride;
409568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               MEMCPY(dest,
409668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      (const GLushort *) texImage->Data + row * rowstride,
409768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      width * sizeof(GLushort));
409868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* check for byte swapping */
409968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
410068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
410168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
410268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
410368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  if (!ctx->Pack.SwapBytes)
410468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     _mesa_swap2((GLushort *) dest, width);
410568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
410668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (ctx->Pack.SwapBytes) {
410768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_swap2((GLushort *) dest, width);
410868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
410968d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
411068d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else {
411168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* general case:  convert row to RGBA format */
411268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat rgba[MAX_WIDTH][4];
411368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
411468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
411568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
411668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
411768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_rgba_span_float(ctx, width,
411868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          (const GLfloat (*)[4]) rgba,
411968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          format, type, dest, &ctx->Pack,
412068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          0 /* no image transfer */);
412168d293b03535ca50daf70650b32db780f1718a3bBrian Paul            } /* format */
412268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         } /* row */
412368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      } /* img */
412468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
412568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
412668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
412768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
412868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
412968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
413068d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
413168d293b03535ca50daf70650b32db780f1718a3bBrian Paul
413268d293b03535ca50daf70650b32db780f1718a3bBrian Paul
413368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
413468d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
413568d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetCompressedTexImage().
413668d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
413768d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
413868d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
413968d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
414068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              GLvoid *img,
414168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_object *texObj,
414268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_image *texImage)
414368d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
414468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
414568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
414668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
414768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if ((const GLubyte *) img + texImage->CompressedSize >
414868d293b03535ca50daf70650b32db780f1718a3bBrian Paul          (const GLubyte *) ctx->Pack.BufferObj->Size) {
414968d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
415068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(invalid PBO access)");
415168d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
415268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
415368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
415468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
415568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
415668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
415768d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
415868d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
415968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(PBO is mapped)");
416068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
416168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
416268d293b03535ca50daf70650b32db780f1718a3bBrian Paul      img = ADD_POINTERS(buf, img);
416368d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
416468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!img) {
416568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
416668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
416768d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
416868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
416968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   /* just memcpy, no pixelstore or pixel transfer */
417068d293b03535ca50daf70650b32db780f1718a3bBrian Paul   MEMCPY(img, texImage->Data, texImage->CompressedSize);
417168d293b03535ca50daf70650b32db780f1718a3bBrian Paul
417268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
417368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
417468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
417568d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
417668d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
4177