texstore.c revision 2b012578ee519561365640e23272b71898378c45
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
34f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Version:  6.1
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
54f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul#include "bufferobj.h"
56e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
6289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h"
63371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
68f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic const GLint ZERO = 1000, ONE = 1001;
69f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
70f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
71f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the
72f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components.
73f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that.
74f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  the logical format of the texture
75f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the final texture format
76f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return map[4]  the four mapping values
77f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
78f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
79f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
80f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                          GLint map[4])
81f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
82f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* compute mapping from dest components back to src components */
83f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   switch (logicalBaseFormat) {
84f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_LUMINANCE:
85f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = map[1] = map[2] = 0;
86f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (textureBaseFormat == GL_RGBA)
87f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         map[3] = ONE;
88f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
89f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_ALPHA:
90f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(textureBaseFormat == GL_RGBA);
91f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = map[1] = map[2] = ZERO;
92f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[3] = 0;
93f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
94f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_INTENSITY:
95f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = map[1] = map[2] = 0;
96f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (textureBaseFormat == GL_RGBA)
97f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         map[3] = 0;
98f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
99f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_LUMINANCE_ALPHA:
100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(textureBaseFormat == GL_RGBA);
101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = map[1] = map[2] = 0;
102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[3] = 1;
103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case GL_RGB:
105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(textureBaseFormat == GL_RGBA);
106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = 0;
107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[1] = 1;
108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[2] = 2;
109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[3] = ONE;
110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      break;
111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   default:
112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_problem(NULL, "Unexpected logicalBaseFormat");
113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      map[0] = map[1] = map[2] = map[3] = 0;
114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components.
120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat.
140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat *
142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims,
143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum logicalBaseFormat,
144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum textureBaseFormat,
145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum srcFormat, GLenum srcType,
147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const GLvoid *srcAddr,
148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const struct gl_pixelstore_attrib *srcPacking)
149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLfloat *tempImage;
152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY ||
161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_COLOR_INDEX ||
162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_DEPTH_COMPONENT);
163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY ||
170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_COLOR_INDEX ||
171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_DEPTH_COMPONENT);
172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* conventional color image */
174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* need image convolution */
179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint preConvTransferOps
180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint postConvTransferOps
182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint convWidth, convHeight;
185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage;
186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* pre-convolution image buffer (3D) */
188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* post-convolution image buffer (2D) */
194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage) {
197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* loop over 3D image slices */
202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* unpack and do transfer ops up to convolution */
206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcAddr, srcWidth, srcHeight,
209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcFormat, srcType, img, row, 0);
210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcFormat, srcType, src,
212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking,
213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          preConvTransferOps);
214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * 4;
215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do convolution */
218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convWidth = srcWidth;
221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convHeight = srcHeight;
222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (dims == 1) {
223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          src, convImage);
230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               else {
232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           src, convImage);
235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do post-convolution transfer and pack into tempImage */
240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
2412b012578ee519561365640e23272b71898378c45Brian Paul            const GLint logComponents
2422b012578ee519561365640e23272b71898378c45Brian Paul               = _mesa_components_in_format(logicalBaseFormat);
243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLfloat *src = convImage;
244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (row = 0; row < convHeight; row++) {
246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_pack_rgba_span_float(ctx, convWidth,
247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          (const GLfloat (*)[4]) src,
248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          logicalBaseFormat, GL_FLOAT,
249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, &ctx->DefaultPacking,
250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          postConvTransferOps);
251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += convWidth * 4;
2522b012578ee519561365640e23272b71898378c45Brian Paul               dst += convWidth * logComponents;
253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      } /* loop over 3D image slices */
256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(convImage);
258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* might need these below */
260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcWidth = convWidth;
261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcHeight = convHeight;
262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* no convolution */
265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint components = _mesa_components_in_format(logicalBaseFormat);
266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *dst;
269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * components * sizeof(GLfloat));
273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      dst = tempImage;
277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *src
279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr,
280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcWidth, srcHeight,
281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcFormat, srcType,
282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    img, 0, 0);
283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, srcFormat, srcType, src,
286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking, transferOps);
287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * components;
288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcStride;
289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* more work */
295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *newImage;
298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint map[4];
300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* we only promote up to RGB and RGBA formats for now */
302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA);
303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLfloat));
311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0.0F;
325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 1.0F;
327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLchan components.
342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLchan.
362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
3638f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian PaulGLchan *
3648f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
3658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum logicalBaseFormat,
3668f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum textureBaseFormat,
3678f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
3688f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum srcFormat, GLenum srcType,
3698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const GLvoid *srcAddr,
3708f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const struct gl_pixelstore_attrib *srcPacking)
371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(logicalBaseFormat);
374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLboolean freeSrcImage = GL_FALSE;
375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint img, row;
376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLchan *tempImage, *dst;
377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY);
386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY);
393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* get convolved image */
398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage = make_temp_float_image(ctx, dims,
399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcAddr, srcPacking);
404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage)
405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* the convolved image is our new source image */
407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcAddr = convImage;
408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcFormat = logicalBaseFormat;
409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcType = GL_FLOAT;
410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcPacking = &ctx->DefaultPacking;
411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      transferOps = 0;
413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      freeSrcImage = GL_TRUE;
414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* unpack and transfer the source image */
417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       * components * sizeof(GLchan));
419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!tempImage)
420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return NULL;
421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   dst = tempImage;
423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   for (img = 0; img < srcDepth; img++) {
424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcWidth, srcFormat,
426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcType);
427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLubyte *src
428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr,
429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight,
430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 img, 0, 0);
432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (row = 0; row < srcHeight; row++) {
433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat,
434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      dst, srcFormat, srcType, src,
435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcPacking, transferOps);
436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dst += srcWidth * components;
437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         src += srcStride;
438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* If we made a temporary image for convolution, free it here */
442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (freeSrcImage) {
443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) srcAddr);
444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one more conversion step */
448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *newImage;
451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint map[4];
453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* we only promote up to RGB and RGBA formats for now */
455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA);
456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLchan));
464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0;
478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = CHAN_MAX;
480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmemcpy_texture(const struct gl_texture_format *dstFormat,
501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstRowStride, GLint dstImageStride,
504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(srcPacking,
514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_memcpy(dstImage, srcImage, bytesPerTexture);
530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  either 1 or 2 or 3
559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param baseInternalFormat  user-specified base internal format
560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstFormat  destination Mesa texture format
561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstAddr  destination image address
562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstX/Y/Zoffset  destination x/y/z offset (ala TexSubImage), in texels
563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstRowStride  destination image row stride, in bytes
564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dstImageStride  destination image layer stride, in bytes
565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth/Height/Depth  source image size, in pixels
566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  incoming image format
567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  incoming image data type
568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image packing parameters
570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba(GLcontext *ctx, GLuint dims,
573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum baseInternalFormat,
574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_texture_format *dstFormat,
575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLvoid *dstAddr,
576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint dstRowStride, GLint dstImageStride,
578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLint srcWidth, GLint srcHeight, GLint srcDepth,
579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    GLenum srcFormat, GLenum srcType,
580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const GLvoid *srcAddr,
581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                    const struct gl_pixelstore_attrib *srcPacking)
582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *dstImage = (GLchan *) (GLubyte *) dstAddr
617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstZoffset * dstImageStride
618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstYoffset * dstRowStride
619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                       + dstXoffset * dstFormat->TexelBytes;
620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
623bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(srcPacking, srcAddr,
624bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul                           srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
6408f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint bytesPerRow = srcWidth * components * sizeof(GLchan);
648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a color index texture image
674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_color_index(STORE_PARAMS)
677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_color_index);
679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1 * sizeof(GLchan));
680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
682f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_COLOR_INDEX &&
684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
688f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
694f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
695f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
696f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
697f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, CHAN_TYPE, dstRow,
705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a floating point depth component texture image.
718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_depth_component_float32(STORE_PARAMS)
721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
747f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
748f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow,
749f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
750f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
751f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
752f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
753f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
754f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
755f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
756f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
757f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store a 16-bit integer depth component texture image.
761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_depth_component16(STORE_PARAMS)
764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_depth_component16);
766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_SHORT) {
773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat depthTemp[MAX_WIDTH];
790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dst16 = (GLushort *) dstRow;
793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth, depthTemp,
794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst16[col] = (GLushort) (depthTemp[col] * 65535.0F);
797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an rgb565 texture image.
811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb565(STORE_PARAMS)
814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565);
816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB &&
822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            baseInternalFormat == GL_RGB &&
832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGB &&
833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE &&
834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dims == 2) {
835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* do optimized tex store */
836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                        srcFormat, srcType);
838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLubyte *src = (const GLubyte *)
839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_image_address(srcPacking, srcAddr, srcWidth, srcHeight,
840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                             srcFormat, srcType, 0, 0, 0);
841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dst = (GLubyte *) dstAddr
842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                   + dstZoffset * dstImageStride
843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                   + dstYoffset * dstRowStride
844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                   + dstXoffset * dstFormat->TexelBytes;
845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint row, col;
846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (row = 0; row < srcHeight; row++) {
847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcUB = (const GLubyte *) src;
848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dstUS = (GLushort *) dst;
849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (col = 0; col < srcWidth; col++) {
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcUB += 3;
852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dst += dstRowStride;
854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         src += srcRowStride;
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
8598f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                            CHAN_TO_UBYTE(src[GCOMP]),
881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                            CHAN_TO_UBYTE(src[BCOMP]) );
882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba8888(STORE_PARAMS)
896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888);
901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGBA &&
907f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) ||
908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) {
909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
9178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
923f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]),
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[ACOMP]) );
941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 4;
942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb8888(STORE_PARAMS)
955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
959f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888);
960f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
961f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
962f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
964f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
965f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) ||
968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) {
969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
9778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
996f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[RCOMP]),
999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1000f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1001f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 4;
1002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1004f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1005f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1006f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1007f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1008f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1009f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1010f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1011f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1012f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1013f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1014f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1015f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb888(STORE_PARAMS)
1016f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1017f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1018f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1019f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1020f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1021f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1022f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1023f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1024f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1025f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1026f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract BGR from RGBA */
1040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      int img, row, col;
1041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
1048bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(srcPacking, srcAddr,
1049bdd15b5749b45929fa642c3e47997f52eb07fbe5Brian Paul                           srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
10658f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1070f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = (const GLubyte *) tempImage;
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1073f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1075f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1076f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1086f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1087f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1088f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1089f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb4444(STORE_PARAMS)
1120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444);
1125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1131f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV && littleEndian) ||
1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcType == GL_UNSIGNED_SHORT_4_4_4_4 && !littleEndian))) {
1133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11418f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1146f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1153f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[RCOMP]),
1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 4;
1166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1167f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1169f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1170f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1171f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1175f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1176f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1177f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1178f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_argb1555(STORE_PARAMS)
1179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555);
1184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV && littleEndian) ||
1191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcType == GL_UNSIGNED_SHORT_5_5_5_1 && !littleEndian))) {
1192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
12008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1213f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[RCOMP]),
1222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 4;
1225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_al88(STORE_PARAMS)
1238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88);
1243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
12598f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[ACOMP]),
1280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           CHAN_TO_UBYTE(src[RCOMP]) );
1281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 2;
1282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgb332(STORE_PARAMS)
1295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
1297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
1303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
1331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
1332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
1333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_a8(STORE_PARAMS)
1351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
1353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
1354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
1355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13698f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
1389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
1392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ci8(STORE_PARAMS)
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
1406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
1407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
1408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLvoid *src = _mesa_image_address(srcPacking,
1430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
1432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
1433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
1434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
1445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1446f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_ycbcr(STORE_PARAMS)
1448f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLuint ui = 1;
1450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLubyte littleEndian = *((const GLubyte *) &ui);
1451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
1453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
1454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
1457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
1458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
1459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
1460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
1462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRowStride, dstImageStride,
1464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
1466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
1468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
1469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
1470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
1471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
1472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
1473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLushort *pImage = (GLushort *) ((GLubyte *) dstAddr
1474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstZoffset * dstImageStride
1475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstYoffset * dstRowStride
1476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       + dstXoffset * dstFormat->TexelBytes);
1477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *pRow = pImage;
1480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_swap2(pRow, srcWidth);
1482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            pRow += dstRowStride;
1483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         pImage += dstImageStride;
1485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
1495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
1496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
1497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
1498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
1499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
1500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
1501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float32(STORE_PARAMS)
1504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
1508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
1509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
1510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
1511f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
1512f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
1513f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1514f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1515f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1516f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
1520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
1525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
1540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint bytesPerRow = srcWidth * components * sizeof(GLfloat);
1541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dst = dstImage;
1551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dst, src, bytesPerRow);
1553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += dstRowStride;
1554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
1567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_texstore_rgba_float16(STORE_PARAMS)
1570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
1572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
1574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
1575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
1576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
1577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
1578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
1579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
1580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
1581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
1582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
1583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
1584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
1585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
1586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
1590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
1591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
1592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     dstRowStride, dstImageStride,
1594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
1600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
1606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
1607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstZoffset * dstImageStride
1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstYoffset * dstRowStride
1609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                        + dstXoffset * dstFormat->TexelBytes;
1610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
1621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
1626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
16357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
16367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate acces to a PBO for texture data.
16377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul *
16387a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the
16397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing.
16407a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
16417a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
16427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth,
16437a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
16447a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                       const struct gl_pixelstore_attrib *unpack )
16457a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
16467a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
16477a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
16487a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
16497a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
16507a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
16517a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                      type, pixels)) {
16527a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return ADD_POINTERS(unpack->BufferObj->Data, pixels);
16537a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
16547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   /* bad access! */
16557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   return NULL;
16567a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
16577a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
16587a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
16597a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
16607a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * Validate that unpacking compressed texture image data from a PBO
16617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * won't go out of bounds.
16627a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul *
16637a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * \todo If the PBO is really resident in VRAM, this won't work; the
16647a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul * device driver should check for that and do the right thing.
16657a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
16667a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulstatic const GLvoid *
16677a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paulvalidate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels,
16687a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                               const struct gl_pixelstore_attrib *packing)
16697a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
16707a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
16717a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
16727a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
16737a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
16747a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   else {
16757a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* using a PBO */
16767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      if ((const GLubyte *) pixels + imageSize >
16777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul          (const GLubyte *) packing->BufferObj->Size) {
16787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul         /* out of bounds read! */
16797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul         return NULL;
16807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      }
16817a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* OK! */
16827a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return ADD_POINTERS(packing->BufferObj->Data, pixels);
16837a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
16847a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
16857a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
16867a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
168789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
16887d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
168989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
1690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
16918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
16928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
16938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
16948e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
16958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
16968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
16978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
16988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
16998e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
17008e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
17018e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
17038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
17058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
17068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
17078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17087d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
17097d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                         format, type);
17127d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
17134f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
17144f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
17158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
171789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
171889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
171989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
1721aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
17227d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
17237d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
17247d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
17257d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
17268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17277a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing);
172889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
172989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
173089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1734f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1735f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
1736f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1737f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1738f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1739f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1740f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
1741f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1742f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1743f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
1744f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1745f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1746f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1747f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
174889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
174989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
175089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
175189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
175289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
17533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
17548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
17558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
175889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
175989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
1760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Reasons why a driver might override this function:
1761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special memory allocation needs
1762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Unusual row/image strides
1763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *  - Special housekeeping
17648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
17658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
17668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
17678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
17688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
17698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
17708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
17718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
17728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
17738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
17748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
1775e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
17768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
17788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
17798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
17808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
17818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17827d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
17837d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
17847d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
17857d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
17867d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
17874f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
17884f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
17892c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
17902c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
17918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
17928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
179389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
179489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
179589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
179689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
1797aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
17987d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
17997d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
18007d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
18017d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
18028e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18037a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, 1,
18047a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
180589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
180689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
180789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride = 0;
1810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
1812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
1813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
1815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
1816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
1824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1830f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
183189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
183289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
183389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
183489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
183589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
18363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
18378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
18388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
184289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
184389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
18448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
18458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
18468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
18478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
18488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
18498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
18508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
18518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
18528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
18538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
1854e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
18558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18567d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   /* choose the texture format */
18577d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
18587d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
18597d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul                                          internalFormat, format, type);
18607d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   assert(texImage->TexFormat);
18614f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
18624f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
18632c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
1864197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
18658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
186789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
186889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
186989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
187089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
1871aeb4434563c4014a662ea334878b60d3031bb3c1Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(sizeInBytes);
18727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
18737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
18747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
18757d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
18768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
18777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, depth,
18787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
187989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!pixels)
188089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
188189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
188289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* unpack image, apply transfer ops and store in texImage->Data */
1883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
1885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
1887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0;
1889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
1891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = width * texImage->TexFormat->TexelBytes;
1892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * height;
1893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
1896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
1899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1900f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
1901f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1902f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1903f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
1904f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1905f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1906f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1907f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
190889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
190989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
191089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
191189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
191289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
19133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
19148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
192089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
192189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
19228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
19258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
19268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
19278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
19288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
19298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
19308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, 1, 1,
19327a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
19337a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
19347a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
19357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint dstRowStride = 0, dstImageStride = 0;
1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->Format,
1941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
1944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
1946f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
1949f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
1950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
19523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
19533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
19543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1955d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
1956d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
19573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
19583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
19598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
19608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
19618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
196289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
1963f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
196489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
196589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
19668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
19678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
19688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
19698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
19708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
19718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
19728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
19738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
19748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
19758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
19767a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   pixels = validate_pbo_teximage(width, height, 1,
19777a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul                                  format, type, pixels, packing);
19787a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
19797a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
19807a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
1981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
1982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride = 0, dstImageStride = 0;
1983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
1985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
1986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
1987f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
1989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
1990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
1992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1993f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
1994f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
1995f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
1996f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
1997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
1998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
1999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2000f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
2001f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2002f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2003f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
20043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
20053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
20063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2007d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2008d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
20093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
20103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
20118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
20158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
201689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
20178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
20208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
20218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
20228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
20238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
20248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
20258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
20268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
2027f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   pixels = validate_pbo_teximage(width, height, depth,
2028f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                  format, type, pixels, packing);
2029f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
2030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2032f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
2033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint dstRowStride, dstImageStride;
2034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
2037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = 0; /* XXX fix */
2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride = dstRowStride * texImage->Height;
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->Format,
2046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                dstRowStride, dstImageStride,
2050f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
2051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
2054f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return;
2055f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
20578f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
20583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
20593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
2060d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
2061d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
20623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
20633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
20648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20672aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
20688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
20698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
20728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
20738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
20748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
20758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
20768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
20778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
207889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
20798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
20808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
20838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
20848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
20858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
20868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
20878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
20888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
20898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
20908e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
20918e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
20928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
20938e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
209489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
209589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
20968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
209789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
209889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
209989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
210089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
210189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
210289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
210389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
210489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* choose the texture format */
210589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(ctx->Driver.ChooseTextureFormat);
210689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
210789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                          internalFormat, 0, 0);
210889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   assert(texImage->TexFormat);
21094f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
21104f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul   texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
211189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
211289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
211389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   texImage->Data = MESA_PBUFFER_ALLOC(imageSize);
211489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
211589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
211689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
211789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
211889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
21197a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
21207a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
21217a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21227a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
212389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
21244039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
212589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
21268f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
21278f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
21288f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
21298f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
21308f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
21318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
21328f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
21338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
21388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
21398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
21408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
21418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
21428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
21438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
21448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
21458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
21468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
21478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
21488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
214989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
21508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
21518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
21538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
215489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
215589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
2156e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
2157e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
215889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
215989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
216089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
216189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
216289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
216389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
216489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
2165e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
216689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
2167e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
2168e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
2169e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
217089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
217189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
217289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
217389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
217489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
217589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
217689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
217789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
217889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
217989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
218089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
218189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
218289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
218389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
218489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
218589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
218689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
218789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
218889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
218989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
219089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
219189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
219289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
219389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
21947a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
21957a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
21967a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
21977a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
219889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width);
219989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
220089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
220189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   destRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
220289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                               texImage->Width);
220389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
220489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                         texImage->IntFormat,
2205f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
2206f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                              (GLubyte*) texImage->Data);
220789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
220889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
220989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
221089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
221189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
221289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
221389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
221489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
221589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
22168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
22178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
22188f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
22198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
22208f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
22218f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
22228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
222389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
222489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
222589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
222689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
222789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
222889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
222989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
223089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
223189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
223289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
223389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
223489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
223589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
223689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
223789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
223889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
223989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
224089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
224189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
224289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
22433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
22443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
22453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
22469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
22479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
22483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
22493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
22509228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
22519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
22529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
22533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
22549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
22559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
22569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
2257c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
22589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
2259c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
22609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
22613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
22623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
22633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
22649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
22653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
22663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
22673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
22687c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
22699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
22709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2271f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
22729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2273f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
22749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2275f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
22769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2277f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
22783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
22793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
22803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
22813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
22823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
22839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
22843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
22853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
22863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
22877c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
22889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
22899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2290f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
22919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2292f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
22939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2294f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
22953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
22963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
22973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
22983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
22993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
23003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
23013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_COLOR_INDEX:
23023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
23039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
23053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
23063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
23077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
2309f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
23103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
23113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
23123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
23133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
23143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
23159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
23173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
23183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
23197c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
23219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2322f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
23239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2324f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
23253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
23263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
23273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
2328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT_FLOAT32:
23298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
23309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
23328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
23338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
23347c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
23369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
23378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
23388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
23398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_DEPTH_COMPONENT16:
2341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
2344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
2345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
2346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
2349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
23528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
23538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
23548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
23558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
23569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
23588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
23598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
23607c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
23629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2363f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
23649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2365f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
23669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2367f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
23689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2369f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
23708bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
23718bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
23728bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
23738bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
23748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
23759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
23778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
23788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
23797c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
23819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2382f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
23839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2384f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
23859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2386f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
23878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
23888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
23898bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
23908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
23918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
23929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
23938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
23948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
23958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
23967c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
23979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
23989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
23999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
24009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
24019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
24029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
24039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
24049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
24059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
24069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
24079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
24089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
24099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
241007d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
241107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
241207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
24138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
24148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
24158bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
24168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
24178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
24188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
24199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
24218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
24228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
24237c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
24259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
24269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
24279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
24289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
24299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
24309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
24319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
24329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
24339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
24349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
24359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
24369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
24379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
24389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
24399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
24409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
244107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
244207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
244307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
244407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
24458bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
24468bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
24478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
24488bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
24498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
24508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
24519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24528bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
24538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
24548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
24557c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
24579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
24589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
24599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
24609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
24619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
24629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
24639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
24649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
24659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
24669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
24679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
24689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
24699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
24709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
24719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
24729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
247307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
247407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
247507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
247607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
24778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
24788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
24798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
24808bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
24818bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
24828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
24839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
24858bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
24868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
24877c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
24889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
24899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
24909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
24919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
24929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
24938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
24948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
24958bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
24968bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
24978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
24989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
24998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
25008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
25018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
25027c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
25059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
25069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
25079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
25089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
25099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
25109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
25119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
25129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
25139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
25149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
25159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
251607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
251707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
251807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
25198bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
25208bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25218bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25228bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
25238bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
25248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
25258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
25268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
25278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
25289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
25298bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
25308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
25318bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
25327c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
25339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
25349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
25358bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
25368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
25378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
2538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
2539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
2542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
2543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
2544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
2553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
2554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
2558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
2561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
2562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
2563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
2566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2574f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
2577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2579f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
2580f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
2581f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
2582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
2589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
2590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
2594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
2597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
2598f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
2599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2600f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2601f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
2602f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
2613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
2616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
2617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
2621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
2622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
2623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
2624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
2628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
2630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
2631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
2632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
2633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
2636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
2637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
2638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
2639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
2640f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
2641f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2642f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2643f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2644f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
2647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
2648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
2649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
2652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
2653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
2654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2656f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
2657f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2658f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2659f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2660f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
2661f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
2662f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
2663f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
2664f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
2665f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
2666f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
2667f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
2668f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
2669f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
2670f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
2671f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
2672f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
2673f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
2674f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
2675f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
2676f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2677f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2678f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
2679f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
26803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
26813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
26823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
26833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
26843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
26879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
26889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
26899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
26909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
26913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
26923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
26933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
26943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
26953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
26963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
26973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
26983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
26993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
27003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
27023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
27033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
27043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
27069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
27079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
27083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
27103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
27113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
27123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
27133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
27143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
27153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
27163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
27173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
27183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
27213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
27223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
27233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
27243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
27253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
27269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
27279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
27289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
27293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
27303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
27313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
27323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
2733462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
27343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
27363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
27373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
27383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
27393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
27403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
27413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
27423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
27449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
27459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
27463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
27473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
27483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
27493893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
27503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
27518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
27523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
27533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
27543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
27553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
27563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
27573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
27583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
27593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
27603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
27613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
27623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
27633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
27643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
27653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
27669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
27679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
27689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
27699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
27703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
27719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
27723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
27733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
27749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
27753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
27763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
27779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
27789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
27799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
27809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
27819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
27829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
27839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
27849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
27859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
27869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
27879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
27889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
27899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
27909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
27919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
27929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
27939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
27949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
27959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
27969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
27979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
27983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
27993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
28003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
28013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
28043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
28053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
28063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
28073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
28083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
28093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
28109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
28119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
28129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
28139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
28149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
28159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
28169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
28173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
28189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
28199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
28209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
28213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28225c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
28235c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
28249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
28259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowA = MALLOC(srcWidth * bpt);
28269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
28279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
28289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   tmpRowB = MALLOC(srcWidth * bpt);
28299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
28309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      FREE(tmpRowA);
28313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
28323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
28333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
28359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
28369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
28379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
28389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
28393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
28419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
28423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
28449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
28453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
28479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
28489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
28499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
28509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
28519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
28529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
28533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
28554e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
28569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
28579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
28589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
28599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
28609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
28619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
28629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
28639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
28649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
28659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
28669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
28679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
28689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
28699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
28709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
28719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
28729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
28739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
28749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
28759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
28769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
28779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
28789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
28799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
28809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
28819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
28829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
28839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
28849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
28859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
28869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
28879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
28889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
28899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
28909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
28919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
28929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
28939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
28943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
28953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
28963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
28973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowA);
28983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   FREE(tmpRowB);
28999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
29019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
29029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
29039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
29049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
29059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
29069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
29079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
29089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
29099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
29109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
29119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
29129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
29139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
29149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
29159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
29169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
29189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
29199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
29209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
29219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
29239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
29259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
29279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
29289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
29309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
29329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
29349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
29359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
29379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
29399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
29419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
29429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
29439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
29449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
29459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
29469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
29479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
29489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
29499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
29509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
29529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
29539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
29549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
29559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
29579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
29599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
29619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
29629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
29649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
29669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
29689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
29699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
29709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
29719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
29729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
29739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
29749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
29759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
29769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
29779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
29789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
29793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
29803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
29833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
29843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
29853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
29863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
29873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
2988d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
29893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
29903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
29913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
29922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
29932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
2994b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
2995b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
2996ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
29973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
29983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
299918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
30002ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
30013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3002ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
3003ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
30043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30052ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
30062ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
30072ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
3008d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
3009d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
30102ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
30112ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
30122ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
30132ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
30142ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (srcImage->Format == GL_RGB) {
30152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
30162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
30172ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
30182ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else if (srcImage->Format == GL_RGBA) {
30192ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
30202ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
30212ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
30222ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
30232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_problem(ctx, "bad srcImage->Format in _mesa_generate_mipmaps");
30242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
30252ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
30262ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
30272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
30282ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      size = _mesa_bytes_per_pixel(srcImage->Format, CHAN_TYPE)
30292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
30302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
3031f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      srcData = (GLubyte *) MALLOC(size);
30322ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
30332ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
30342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
30352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
3036f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul      dstData = (GLubyte *) MALLOC(size / 2);  /* 1/4 would probably be OK */
30372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
30382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
30392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         FREE((void *) srcData);
30402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
30412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
30422ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
30432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
30442ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
30452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
3046d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
30472ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
30484f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
30492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
305089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
305189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
305289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
30532ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
30542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
30552ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
30562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
305789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
30588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
3059cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
30609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
30613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
30623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
30633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
30643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
30653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
30663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
306789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
30683ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
30693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
30703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
30713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
30723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
30733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
30743893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
30763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
30773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
30783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
30803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
30813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
30833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
30843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
30863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
30873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
30893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
30903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30913893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
30923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
30933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
30943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
30953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
30963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
30973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
30983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
309989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
310089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE((void *) srcData);
310189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            FREE(dstData);
310289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
31033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
31043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
31053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3106d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
3107a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
3108d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
3109a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
3110a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
3111d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
31123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3113d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
3114d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
3115d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul         MESA_PBUFFER_FREE(dstImage->Data);
3116d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3117d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
3118e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
311989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                 dstDepth, border, srcImage->IntFormat);
3120d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
3121d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
31224f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
31234f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
3124d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
31254f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
31264f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
3127d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
312889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
312989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
313089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
313189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
313289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstImage->CompressedSize > 0); /* set by init_teximage_fields*/
313389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstImage->CompressedSize);
313489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
313589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
313689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
313789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
31382ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
313989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
314089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
314189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
314289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
314389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         bytesPerTexel = srcImage->TexFormat->TexelBytes;
314489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
314589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstImage->Data = MESA_PBUFFER_ALLOC(dstWidth * dstHeight * dstDepth
314689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                             * bytesPerTexel);
314789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
314889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
314989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
315089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
315189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
315289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
3153d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
3154d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
3155d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
3156d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
3157d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
3158d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
315989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
31602ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
316189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
316289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
316389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
316489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
316589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
316689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
316789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
316889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
316989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
317089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
31712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
317289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
317389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
317489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
317589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
31762ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
317789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
317889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
317989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
318089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
318189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
318289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
318389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
318489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
318589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
3186d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
318789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
318889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
318989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
31902ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
31912ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
31922ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
31932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul                                                          dstWidth);
31942ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
31958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format,
31968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
31978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
31988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
31998f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
32008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
32018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
32028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
32038f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
320489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
320589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
320689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
320789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
320889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
320989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3210d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
32113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
321280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
321380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
321480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
321580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
321680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
321780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
321880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
321980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
322080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
322180fc5ea53e0f1dac9df529965687c159acae057fBrian Paulvoid _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride,
322280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul			       GLint srcWidth, GLint srcHeight,
322380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul			       GLint dstWidth, GLint dstHeight,
322480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul			       const GLvoid *srcImage, GLvoid *dstImage )
322580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
322680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
322780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
322880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
322980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
323080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
323180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
323280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
323380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 dst[col] = src[srcRow * srcWidth + srcCol];			\
323480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
323580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
323680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
323780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
323880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
323980fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
324080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
324180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
324280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
324380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   if ( srcHeight <= dstHeight ) {					\
324480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
324580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      if ( srcWidth <= dstWidth ) {					\
324680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
324780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
324880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
324980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
325080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
325180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
325280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
325380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
325480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
325580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
325680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      if ( srcWidth <= dstWidth ) {					\
325780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
325880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
325980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
326080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
326180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
326280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
326380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
326480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
326580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
326680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
326780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
326880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
326980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
327080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
327180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
327280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
327380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
327480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
327580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
327680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
327780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
327880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
327980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
328080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
328180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
328280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
328333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
328433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
328533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
328633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
328733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
328833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
328933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
329033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
329133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
329233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
329333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
329433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
329533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
329633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
329733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
329833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
329933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
330033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
330133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
330233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
330333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
330433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
330533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
330633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
330733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
330833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
330933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
331033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
331133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
331233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
331333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
331433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
331533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
331633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
3317