124edd9015951dd41898902b6c3973fe605e5871aBrian Paul/*
224edd9015951dd41898902b6c3973fe605e5871aBrian Paul * Mesa 3-D graphics library
353cf87be1b93c760228e6a9af8115d2a9ff99337Brian * Version:  7.1
424edd9015951dd41898902b6c3973fe605e5871aBrian Paul *
553cf87be1b93c760228e6a9af8115d2a9ff99337Brian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
624edd9015951dd41898902b6c3973fe605e5871aBrian Paul *
724edd9015951dd41898902b6c3973fe605e5871aBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
824edd9015951dd41898902b6c3973fe605e5871aBrian Paul * copy of this software and associated documentation files (the "Software"),
924edd9015951dd41898902b6c3973fe605e5871aBrian Paul * to deal in the Software without restriction, including without limitation
1024edd9015951dd41898902b6c3973fe605e5871aBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1124edd9015951dd41898902b6c3973fe605e5871aBrian Paul * and/or sell copies of the Software, and to permit persons to whom the
1224edd9015951dd41898902b6c3973fe605e5871aBrian Paul * Software is furnished to do so, subject to the following conditions:
1324edd9015951dd41898902b6c3973fe605e5871aBrian Paul *
1424edd9015951dd41898902b6c3973fe605e5871aBrian Paul * The above copyright notice and this permission notice shall be included
1524edd9015951dd41898902b6c3973fe605e5871aBrian Paul * in all copies or substantial portions of the Software.
1624edd9015951dd41898902b6c3973fe605e5871aBrian Paul *
1724edd9015951dd41898902b6c3973fe605e5871aBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1824edd9015951dd41898902b6c3973fe605e5871aBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1924edd9015951dd41898902b6c3973fe605e5871aBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2024edd9015951dd41898902b6c3973fe605e5871aBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2124edd9015951dd41898902b6c3973fe605e5871aBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2224edd9015951dd41898902b6c3973fe605e5871aBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2324edd9015951dd41898902b6c3973fe605e5871aBrian Paul */
2424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2524edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2624edd9015951dd41898902b6c3973fe605e5871aBrian Paul/**
2724edd9015951dd41898902b6c3973fe605e5871aBrian Paul * \file mipmap.c  mipmap generation and teximage resizing functions.
2824edd9015951dd41898902b6c3973fe605e5871aBrian Paul */
2924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
3024edd9015951dd41898902b6c3973fe605e5871aBrian Paul#include "imports.h"
31db8aca3a398e16f7dc23d3321787274d07d13138Brian Paul#include "formats.h"
32a1287f549a3e6527b8cf3bf5b5f563ba63c6f48cBrian Paul#include "glformats.h"
3324edd9015951dd41898902b6c3973fe605e5871aBrian Paul#include "mipmap.h"
340117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h"
3524edd9015951dd41898902b6c3973fe605e5871aBrian Paul#include "teximage.h"
3646751edca9a95baff81771aa69986fa6e2422ed6Brian Paul#include "texobj.h"
37f76cbac04abf26617bd65b50e923db8728a4f33fBrian Paul#include "texstore.h"
3824edd9015951dd41898902b6c3973fe605e5871aBrian Paul#include "image.h"
399d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák#include "macros.h"
401271424615b62544662a606bb23f6d7117a8b0e7Marek Olšák#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
41631d23daa91c569bf268a2191bd466df73a64263Marek Olšák#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
4224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
4324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
4424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
45b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellstatic GLint
46b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellbytes_per_pixel(GLenum datatype, GLuint comps)
4724edd9015951dd41898902b6c3973fe605e5871aBrian Paul{
4823c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   GLint b;
4923c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul
5023c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   if (datatype == GL_UNSIGNED_INT_8_24_REV_MESA ||
5123c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul       datatype == GL_UNSIGNED_INT_24_8_MESA)
5223c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      return 4;
5323c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul
5423c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   b = _mesa_sizeof_packed_type(datatype);
55b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   assert(b >= 0);
56f1f022dbb103947b0edf5ae984fcff00f6a8e539Xiang, Haihao
57f1f022dbb103947b0edf5ae984fcff00f6a8e539Xiang, Haihao   if (_mesa_type_is_packed(datatype))
584c84fbea9d496567d706468113d63cd8f0faeb7fBrian Paul      return b;
59f1f022dbb103947b0edf5ae984fcff00f6a8e539Xiang, Haihao   else
604c84fbea9d496567d706468113d63cd8f0faeb7fBrian Paul      return b * comps;
61b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell}
6224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
6324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
64b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell/**
65f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \name Support macros for do_row and do_row_3d
66f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick *
67f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * The macro madness is here for two reasons.  First, it compacts the code
68f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * slightly.  Second, it makes it much easier to adjust the specifics of the
69f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * filter to tune the rounding characteristics.
70f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick */
71f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick/*@{*/
72f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define DECLARE_ROW_POINTERS(t, e) \
73f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t(*rowA)[e] = (const t(*)[e]) srcRowA; \
74f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t(*rowB)[e] = (const t(*)[e]) srcRowB; \
75f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t(*rowC)[e] = (const t(*)[e]) srcRowC; \
76f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t(*rowD)[e] = (const t(*)[e]) srcRowD; \
77f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      t(*dst)[e] = (t(*)[e]) dstRow
78f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
79f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define DECLARE_ROW_POINTERS0(t) \
80f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t *rowA = (const t *) srcRowA; \
81f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t *rowB = (const t *) srcRowB; \
82f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t *rowC = (const t *) srcRowC; \
83f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const t *rowD = (const t *) srcRowD; \
84f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      t *dst = (t *) dstRow
85f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
86f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
87f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   ((unsigned) Aj + (unsigned) Ak \
88f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick    + (unsigned) Bj + (unsigned) Bk \
89f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick    + (unsigned) Cj + (unsigned) Ck \
90f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick    + (unsigned) Dj + (unsigned) Dk \
91f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick    + 4) >> 3
92f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
93f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define FILTER_3D(e) \
94f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   do { \
95f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \
96f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                rowB[j][e], rowB[k][e], \
97f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                rowC[j][e], rowC[k][e], \
98f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                rowD[j][e], rowD[k][e]); \
99f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   } while(0)
100114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
101c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
102c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   (Aj + Ak \
103c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger    + Bj + Bk \
104c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger    + Cj + Ck \
105c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger    + Dj + Dk \
106c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger    + 4) / 8
107c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
108c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger#define FILTER_3D_SIGNED(e) \
109c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   do { \
110c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \
111c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger                                       rowB[j][e], rowB[k][e], \
112c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger                                       rowC[j][e], rowC[k][e], \
113c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger                                       rowD[j][e], rowD[k][e]); \
114c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   } while(0)
115c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
116f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define FILTER_F_3D(e) \
117f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   do { \
118f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      dst[i][e] = (rowA[j][e] + rowA[k][e] \
119f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   + rowB[j][e] + rowB[k][e] \
120f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   + rowC[j][e] + rowC[k][e] \
121f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   + rowD[j][e] + rowD[k][e]) * 0.125F; \
122f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   } while(0)
123f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
124f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick#define FILTER_HF_3D(e) \
125f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   do { \
126f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat aj = _mesa_half_to_float(rowA[j][e]); \
127f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat ak = _mesa_half_to_float(rowA[k][e]); \
128f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat bj = _mesa_half_to_float(rowB[j][e]); \
129f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat bk = _mesa_half_to_float(rowB[k][e]); \
130f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat cj = _mesa_half_to_float(rowC[j][e]); \
131f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat ck = _mesa_half_to_float(rowC[k][e]); \
132f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat dj = _mesa_half_to_float(rowD[j][e]); \
133f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLfloat dk = _mesa_half_to_float(rowD[k][e]); \
134f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      dst[i][e] = _mesa_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
135f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                      * 0.125F); \
136f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   } while(0)
137f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick/*@}*/
138f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
139f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
140f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick/**
141b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * Average together two rows of a source image to produce a single new
142b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * row in the dest image.  It's legal for the two source rows to point
143b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * to the same data.  The source width must be equal to either the
144b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * dest width or two times the dest width.
145b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * \param datatype  GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
146b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell * \param comps  number of components per pixel (1..4)
147b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell */
148b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellstatic void
149b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwelldo_row(GLenum datatype, GLuint comps, GLint srcWidth,
150b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell       const GLvoid *srcRowA, const GLvoid *srcRowB,
151b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell       GLint dstWidth, GLvoid *dstRow)
152b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell{
153b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
154b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
155b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
156b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   ASSERT(comps >= 1);
157b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   ASSERT(comps <= 4);
158b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
159b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   /* This assertion is no longer valid with non-power-of-2 textures
160b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
161b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   */
162b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
163b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   if (datatype == GL_UNSIGNED_BYTE && comps == 4) {
164b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
165b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowA)[4] = (const GLubyte(*)[4]) srcRowA;
166b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowB)[4] = (const GLubyte(*)[4]) srcRowB;
167b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLubyte(*dst)[4] = (GLubyte(*)[4]) dstRow;
168b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
169b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
170b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
171b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
172b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
173b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
174b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
175b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
176b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_BYTE && comps == 3) {
177b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
178b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowA)[3] = (const GLubyte(*)[3]) srcRowA;
179b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowB)[3] = (const GLubyte(*)[3]) srcRowB;
180b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLubyte(*dst)[3] = (GLubyte(*)[3]) dstRow;
181b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
182b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
183b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
184b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
185b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
186b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
187b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
188b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_BYTE && comps == 2) {
189b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
190b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowA)[2] = (const GLubyte(*)[2]) srcRowA;
191b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte(*rowB)[2] = (const GLubyte(*)[2]) srcRowB;
192b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLubyte(*dst)[2] = (GLubyte(*)[2]) dstRow;
193b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
194b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
195b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
196b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
197b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
198b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
199b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_BYTE && comps == 1) {
200b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
201b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte *rowA = (const GLubyte *) srcRowA;
202b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte *rowB = (const GLubyte *) srcRowB;
203b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLubyte *dst = (GLubyte *) dstRow;
204b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
205b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
206b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
207b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
208b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
209b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
2104d89eff0b6fd6902a2fccb87c474d6a8f6d61526Roland Scheidegger   else if (datatype == GL_BYTE && comps == 4) {
211c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLuint i, j, k;
212c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowA)[4] = (const GLbyte(*)[4]) srcRowA;
213c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowB)[4] = (const GLbyte(*)[4]) srcRowB;
214c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLbyte(*dst)[4] = (GLbyte(*)[4]) dstRow;
215c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
216c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
217c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
218c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
219c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
220c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
221c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
222c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
223c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if (datatype == GL_BYTE && comps == 3) {
224c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLuint i, j, k;
225c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowA)[3] = (const GLbyte(*)[3]) srcRowA;
226c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowB)[3] = (const GLbyte(*)[3]) srcRowB;
227c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLbyte(*dst)[3] = (GLbyte(*)[3]) dstRow;
228c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
229c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
230c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
231c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
232c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
233c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
234c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
235c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if (datatype == GL_BYTE && comps == 2) {
236c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLuint i, j, k;
237c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA;
238c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB;
239c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow;
240c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
241c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
242c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
243c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
244c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
245c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
246c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if (datatype == GL_BYTE && comps == 1) {
247c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLuint i, j, k;
248c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte *rowA = (const GLbyte *) srcRowA;
249c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      const GLbyte *rowB = (const GLbyte *) srcRowB;
250c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      GLbyte *dst = (GLbyte *) dstRow;
251c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
252c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
253c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
254c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
255c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
256c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
257b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT && comps == 4) {
258b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
259b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA;
260b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowB)[4] = (const GLushort(*)[4]) srcRowB;
261b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort(*dst)[4] = (GLushort(*)[4]) dstRow;
262b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
263b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
264b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
265b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
266b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
267b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
268b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
269b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
270b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT && comps == 3) {
271b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
272b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowA)[3] = (const GLushort(*)[3]) srcRowA;
273b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowB)[3] = (const GLushort(*)[3]) srcRowB;
274b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort(*dst)[3] = (GLushort(*)[3]) dstRow;
275b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
276b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
277b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
278b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
279b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
280b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
281b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
282b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT && comps == 2) {
283b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
284b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowA)[2] = (const GLushort(*)[2]) srcRowA;
285b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort(*rowB)[2] = (const GLushort(*)[2]) srcRowB;
286b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort(*dst)[2] = (GLushort(*)[2]) dstRow;
287b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
288b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
289b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
290b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
291b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
292b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
293b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT && comps == 1) {
294b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
295b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowA = (const GLushort *) srcRowA;
296b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowB = (const GLushort *) srcRowB;
297b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort *dst = (GLushort *) dstRow;
298b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
299b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
300b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
301b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
302b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
303b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
304b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if (datatype == GL_SHORT && comps == 4) {
305b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLuint i, j, k;
306b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowA)[4] = (const GLshort(*)[4]) srcRowA;
307b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowB)[4] = (const GLshort(*)[4]) srcRowB;
308b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLshort(*dst)[4] = (GLshort(*)[4]) dstRow;
309b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
310b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
311b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
312b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
313b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
314b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
315b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
316b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
317b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if (datatype == GL_SHORT && comps == 3) {
318b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLuint i, j, k;
319b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowA)[3] = (const GLshort(*)[3]) srcRowA;
320b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowB)[3] = (const GLshort(*)[3]) srcRowB;
321b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLshort(*dst)[3] = (GLshort(*)[3]) dstRow;
322b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
323b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
324b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
325b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
326b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
327b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
328b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
329b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if (datatype == GL_SHORT && comps == 2) {
330b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLuint i, j, k;
331b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowA)[2] = (const GLshort(*)[2]) srcRowA;
332b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort(*rowB)[2] = (const GLshort(*)[2]) srcRowB;
333b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLshort(*dst)[2] = (GLshort(*)[2]) dstRow;
334b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
335b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
336b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
337b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
338b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
339b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
340b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if (datatype == GL_SHORT && comps == 1) {
341b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLuint i, j, k;
342b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort *rowA = (const GLshort *) srcRowA;
343b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLshort *rowB = (const GLshort *) srcRowB;
344b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLshort *dst = (GLshort *) dstRow;
345b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
346b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
347b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
348b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
349b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
350b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
351b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_FLOAT && comps == 4) {
352b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
353b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA;
354b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowB)[4] = (const GLfloat(*)[4]) srcRowB;
355b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLfloat(*dst)[4] = (GLfloat(*)[4]) dstRow;
356b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
357b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
358b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] +
359b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][0] + rowB[k][0]) * 0.25F;
360b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] +
361b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][1] + rowB[k][1]) * 0.25F;
362b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] +
363b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][2] + rowB[k][2]) * 0.25F;
364b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][3] = (rowA[j][3] + rowA[k][3] +
365b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][3] + rowB[k][3]) * 0.25F;
366b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
367b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
368b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_FLOAT && comps == 3) {
369b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
370b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowA)[3] = (const GLfloat(*)[3]) srcRowA;
371b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowB)[3] = (const GLfloat(*)[3]) srcRowB;
372b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLfloat(*dst)[3] = (GLfloat(*)[3]) dstRow;
373b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
374b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
375b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] +
376b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][0] + rowB[k][0]) * 0.25F;
377b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] +
378b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][1] + rowB[k][1]) * 0.25F;
379b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][2] = (rowA[j][2] + rowA[k][2] +
380b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][2] + rowB[k][2]) * 0.25F;
381b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
382b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
383b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_FLOAT && comps == 2) {
384b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
385b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowA)[2] = (const GLfloat(*)[2]) srcRowA;
386b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat(*rowB)[2] = (const GLfloat(*)[2]) srcRowB;
387b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLfloat(*dst)[2] = (GLfloat(*)[2]) dstRow;
388b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
389b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
390b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][0] = (rowA[j][0] + rowA[k][0] +
391b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][0] + rowB[k][0]) * 0.25F;
392b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i][1] = (rowA[j][1] + rowA[k][1] +
393b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell                      rowB[j][1] + rowB[k][1]) * 0.25F;
394b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
395b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
396b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_FLOAT && comps == 1) {
397b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
398b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat *rowA = (const GLfloat *) srcRowA;
399b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLfloat *rowB = (const GLfloat *) srcRowB;
400b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLfloat *dst = (GLfloat *) dstRow;
401b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
402b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
403b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
404b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
405b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
406b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
407b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_HALF_FLOAT_ARB && comps == 4) {
408b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k, comp;
409b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowA)[4] = (const GLhalfARB(*)[4]) srcRowA;
410b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowB)[4] = (const GLhalfARB(*)[4]) srcRowB;
411b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLhalfARB(*dst)[4] = (GLhalfARB(*)[4]) dstRow;
412b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
413b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
414b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         for (comp = 0; comp < 4; comp++) {
41524edd9015951dd41898902b6c3973fe605e5871aBrian Paul            GLfloat aj, ak, bj, bk;
416b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            aj = _mesa_half_to_float(rowA[j][comp]);
417b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            ak = _mesa_half_to_float(rowA[k][comp]);
418b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bj = _mesa_half_to_float(rowB[j][comp]);
419b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bk = _mesa_half_to_float(rowB[k][comp]);
420b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
42124edd9015951dd41898902b6c3973fe605e5871aBrian Paul         }
42224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
423b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
424b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_HALF_FLOAT_ARB && comps == 3) {
425b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k, comp;
426b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowA)[3] = (const GLhalfARB(*)[3]) srcRowA;
427b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowB)[3] = (const GLhalfARB(*)[3]) srcRowB;
428b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLhalfARB(*dst)[3] = (GLhalfARB(*)[3]) dstRow;
429b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
430b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
431b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         for (comp = 0; comp < 3; comp++) {
432b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            GLfloat aj, ak, bj, bk;
433b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            aj = _mesa_half_to_float(rowA[j][comp]);
434b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            ak = _mesa_half_to_float(rowA[k][comp]);
435b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bj = _mesa_half_to_float(rowB[j][comp]);
436b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bk = _mesa_half_to_float(rowB[k][comp]);
437b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
438b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         }
439b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
440b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
441b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_HALF_FLOAT_ARB && comps == 2) {
442b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k, comp;
443b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowA)[2] = (const GLhalfARB(*)[2]) srcRowA;
444b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB(*rowB)[2] = (const GLhalfARB(*)[2]) srcRowB;
445b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLhalfARB(*dst)[2] = (GLhalfARB(*)[2]) dstRow;
446b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
447b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
448b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         for (comp = 0; comp < 2; comp++) {
449b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            GLfloat aj, ak, bj, bk;
450b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            aj = _mesa_half_to_float(rowA[j][comp]);
451b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            ak = _mesa_half_to_float(rowA[k][comp]);
452b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bj = _mesa_half_to_float(rowB[j][comp]);
453b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            bk = _mesa_half_to_float(rowB[k][comp]);
454b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
455b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         }
456b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
457b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
458b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_HALF_FLOAT_ARB && comps == 1) {
459b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
460b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
461b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
462b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLhalfARB *dst = (GLhalfARB *) dstRow;
463b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
464b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
465b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         GLfloat aj, ak, bj, bk;
466b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         aj = _mesa_half_to_float(rowA[j]);
467b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         ak = _mesa_half_to_float(rowA[k]);
468b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         bj = _mesa_half_to_float(rowB[j]);
469b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         bk = _mesa_half_to_float(rowB[k]);
470b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
471b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
472b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
47324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
474b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_INT && comps == 1) {
475b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
476b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLuint *rowA = (const GLuint *) srcRowA;
477b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLuint *rowB = (const GLuint *) srcRowB;
478865cf775030beac3147547537a1a5372485127deDave Airlie      GLuint *dst = (GLuint *) dstRow;
479b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
480b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
481003dd8adf39c964d8c7beb86955a61ceb3706ebcBrian Paul         dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
482b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
483b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
484b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
485b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT_5_6_5 && comps == 3) {
486b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
487b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowA = (const GLushort *) srcRowA;
488b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowB = (const GLushort *) srcRowB;
489b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort *dst = (GLushort *) dstRow;
490b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
491b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
492b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr0 = rowA[j] & 0x1f;
493b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr1 = rowA[k] & 0x1f;
494b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr0 = rowB[j] & 0x1f;
495b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr1 = rowB[k] & 0x1f;
496b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
497b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
498b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
499b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
500b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
501b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
502b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
503b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
504b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
505b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
506b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
507b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (blue << 11) | (green << 5) | red;
508b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
509b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
510b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT_4_4_4_4 && comps == 4) {
511b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
512b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowA = (const GLushort *) srcRowA;
513b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowB = (const GLushort *) srcRowB;
514b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort *dst = (GLushort *) dstRow;
515b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
516b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
517b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr0 = rowA[j] & 0xf;
518b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr1 = rowA[k] & 0xf;
519b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr0 = rowB[j] & 0xf;
520b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr1 = rowB[k] & 0xf;
521b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
522b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
523b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
524b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
525b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
526b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
527b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
528b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
529b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
530b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
531b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
532b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
533b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
534b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
535b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
536b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
537b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
538b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
539b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
540b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV && comps == 4) {
541b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
542b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowA = (const GLushort *) srcRowA;
543b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLushort *rowB = (const GLushort *) srcRowB;
544b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLushort *dst = (GLushort *) dstRow;
545b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
546b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
547b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr0 = rowA[j] & 0x1f;
548b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr1 = rowA[k] & 0x1f;
549b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr0 = rowB[j] & 0x1f;
550a330933bb75c38148668637cd22b90d75d39506fIan Romanick         const GLint rowBr1 = rowB[k] & 0x1f;
551b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
552b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
553b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
554b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
555b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
556b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
557b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
558b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
559b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
560b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
561b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
562b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
563b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
564b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
565b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
566b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
567b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
568b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
569b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
570b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if (datatype == GL_UNSIGNED_SHORT_5_5_5_1 && comps == 4) {
571b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLuint i, j, k;
572b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLushort *rowA = (const GLushort *) srcRowA;
573b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      const GLushort *rowB = (const GLushort *) srcRowB;
574b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      GLushort *dst = (GLushort *) dstRow;
575b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
576b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
577b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAr0 = (rowA[j] >> 11) & 0x1f;
578b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAr1 = (rowA[k] >> 11) & 0x1f;
579b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBr0 = (rowB[j] >> 11) & 0x1f;
580b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBr1 = (rowB[k] >> 11) & 0x1f;
581b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAg0 = (rowA[j] >> 6) & 0x1f;
582b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAg1 = (rowA[k] >> 6) & 0x1f;
583b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBg0 = (rowB[j] >> 6) & 0x1f;
584b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBg1 = (rowB[k] >> 6) & 0x1f;
585b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAb0 = (rowA[j] >> 1) & 0x1f;
586b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAb1 = (rowA[k] >> 1) & 0x1f;
587b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBb0 = (rowB[j] >> 1) & 0x1f;
588b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBb1 = (rowB[k] >> 1) & 0x1f;
589b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAa0 = (rowA[j] & 0x1);
590b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAa1 = (rowA[k] & 0x1);
591b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBa0 = (rowB[j] & 0x1);
592b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBa1 = (rowB[k] & 0x1);
593b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
594b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
595b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
596b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
597b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i] = (red << 11) | (green << 6) | (blue << 1) | alpha;
598b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
599b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
600b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
601b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else if (datatype == GL_UNSIGNED_BYTE_3_3_2 && comps == 3) {
602b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLuint i, j, k;
603b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte *rowA = (const GLubyte *) srcRowA;
604b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      const GLubyte *rowB = (const GLubyte *) srcRowB;
605b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      GLubyte *dst = (GLubyte *) dstRow;
606b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
607b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell           i++, j += colStride, k += colStride) {
608b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr0 = rowA[j] & 0x3;
609b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAr1 = rowA[k] & 0x3;
610b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr0 = rowB[j] & 0x3;
611b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBr1 = rowB[k] & 0x3;
612b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
613b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
614b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
615b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
616b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
617b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
618b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
619b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
620b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
621b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
622b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
623b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell         dst[i] = (blue << 5) | (green << 2) | red;
624b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      }
625b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   }
6264d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák
6274d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák   else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) {
6284d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      GLuint i, j, k;
6294d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      const GLubyte *rowA = (const GLubyte *) srcRowA;
6304d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      const GLubyte *rowB = (const GLubyte *) srcRowB;
6314d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      GLubyte *dst = (GLubyte *) dstRow;
6324d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
6334d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák           i++, j += colStride, k += colStride) {
6344d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAr0 = rowA[j] & 0xf;
6354d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAr1 = rowA[k] & 0xf;
6364d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBr0 = rowB[j] & 0xf;
6374d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBr1 = rowB[k] & 0xf;
6384d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
6394d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
6404d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
6414d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
6424d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint r = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
6434d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint g = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
6444d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         dst[i] = (g << 4) | r;
6454d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      }
6464d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák   }
6474d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák
648628544421d243e0ca8679c5d245728260d9e010dMarek Olšák   else if (datatype == GL_UNSIGNED_INT_2_10_10_10_REV && comps == 4) {
649628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      GLuint i, j, k;
650628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      const GLuint *rowA = (const GLuint *) srcRowA;
651628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      const GLuint *rowB = (const GLuint *) srcRowB;
652628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      GLuint *dst = (GLuint *) dstRow;
653628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
654628544421d243e0ca8679c5d245728260d9e010dMarek Olšák           i++, j += colStride, k += colStride) {
655628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAr0 = rowA[j] & 0x3ff;
656628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAr1 = rowA[k] & 0x3ff;
657628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBr0 = rowB[j] & 0x3ff;
658628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBr1 = rowB[k] & 0x3ff;
659628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAg0 = (rowA[j] >> 10) & 0x3ff;
660628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAg1 = (rowA[k] >> 10) & 0x3ff;
661628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBg0 = (rowB[j] >> 10) & 0x3ff;
662628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBg1 = (rowB[k] >> 10) & 0x3ff;
663628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAb0 = (rowA[j] >> 20) & 0x3ff;
664628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAb1 = (rowA[k] >> 20) & 0x3ff;
665628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBb0 = (rowB[j] >> 20) & 0x3ff;
666628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBb1 = (rowB[k] >> 20) & 0x3ff;
667628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAa0 = (rowA[j] >> 30) & 0x3;
668628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAa1 = (rowA[k] >> 30) & 0x3;
669628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBa0 = (rowB[j] >> 30) & 0x3;
670628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBa1 = (rowB[k] >> 30) & 0x3;
671628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
672628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
673628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
674628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
675628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         dst[i] = (alpha << 30) | (blue << 20) | (green << 10) | red;
676628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      }
677628544421d243e0ca8679c5d245728260d9e010dMarek Olšák   }
678628544421d243e0ca8679c5d245728260d9e010dMarek Olšák
6799d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák   else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) {
6809d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLuint i, j, k;
6819d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      const GLuint *rowA = (const GLuint*) srcRowA;
6829d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      const GLuint *rowB = (const GLuint*) srcRowB;
6839d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLuint *dst = (GLuint*)dstRow;
6849d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3];
6859d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
6869d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák           i++, j += colStride, k += colStride) {
6879d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowA[j], rowAj);
6889d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowB[j], rowBj);
6899d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowA[k], rowAk);
6909d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowB[k], rowBk);
6919d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F;
6929d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F;
6939d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F;
6949d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         dst[i] = float3_to_rgb9e5(res);
6959d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      }
6969d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák   }
6979d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák
698631d23daa91c569bf268a2191bd466df73a64263Marek Olšák   else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) {
699631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLuint i, j, k;
700631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      const GLuint *rowA = (const GLuint*) srcRowA;
701631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      const GLuint *rowB = (const GLuint*) srcRowB;
702631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLuint *dst = (GLuint*)dstRow;
703631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3];
704631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
705631d23daa91c569bf268a2191bd466df73a64263Marek Olšák           i++, j += colStride, k += colStride) {
706631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowA[j], rowAj);
707631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowB[j], rowBj);
708631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowA[k], rowAk);
709631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowB[k], rowBk);
710631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F;
711631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F;
712631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F;
713631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         dst[i] = float3_to_r11g11b10f(res);
714631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      }
715631d23daa91c569bf268a2191bd466df73a64263Marek Olšák   }
716631d23daa91c569bf268a2191bd466df73a64263Marek Olšák
717bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák   else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && comps == 1) {
718bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      GLuint i, j, k;
719bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      const GLfloat *rowA = (const GLfloat *) srcRowA;
720bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      const GLfloat *rowB = (const GLfloat *) srcRowB;
721bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      GLfloat *dst = (GLfloat *) dstRow;
722bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
723bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák           i++, j += colStride, k += colStride) {
724bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák         dst[i*2] = (rowA[j*2] + rowA[k*2] + rowB[j*2] + rowB[k*2]) * 0.25F;
725bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      }
726bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák   }
727bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák
72823c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   else if (datatype == GL_UNSIGNED_INT_24_8_MESA && comps == 2) {
72923c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      GLuint i, j, k;
73023c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      const GLuint *rowA = (const GLuint *) srcRowA;
73123c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      const GLuint *rowB = (const GLuint *) srcRowB;
73223c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      GLuint *dst = (GLuint *) dstRow;
73323c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      /* note: averaging stencil values seems weird, but what else? */
73423c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
73523c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul           i++, j += colStride, k += colStride) {
73623c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         GLuint z = (((rowA[j] >> 8) + (rowA[k] >> 8) +
73723c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul                      (rowB[j] >> 8) + (rowB[k] >> 8)) / 4) << 8;
73823c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         GLuint s = ((rowA[j] & 0xff) + (rowA[k] & 0xff) +
73923c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul                     (rowB[j] & 0xff) + (rowB[k] & 0xff)) / 4;
74023c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         dst[i] = z | s;
74123c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      }
74223c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   }
74323c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   else if (datatype == GL_UNSIGNED_INT_8_24_REV_MESA && comps == 2) {
74423c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      GLuint i, j, k;
74523c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      const GLuint *rowA = (const GLuint *) srcRowA;
74623c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      const GLuint *rowB = (const GLuint *) srcRowB;
74723c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      GLuint *dst = (GLuint *) dstRow;
74823c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
74923c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul           i++, j += colStride, k += colStride) {
75023c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         GLuint z = ((rowA[j] & 0xffffff) + (rowA[k] & 0xffffff) +
75123c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul                     (rowB[j] & 0xffffff) + (rowB[k] & 0xffffff)) / 4;
75223c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         GLuint s = (((rowA[j] >> 24) + (rowA[k] >> 24) +
75323c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul                      (rowB[j] >> 24) + (rowB[k] >> 24)) / 4) << 24;
75423c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul         dst[i] = z | s;
75523c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul      }
75623c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul   }
75723c6eb035ba63d39652a10107f323d47b86b90f1Brian Paul
758b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   else {
75924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      _mesa_problem(NULL, "bad format in do_row()");
76024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
76124edd9015951dd41898902b6c3973fe605e5871aBrian Paul}
76224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
76324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
764f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick/**
765f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * Average together four rows of a source image to produce a single new
766f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * row in the dest image.  It's legal for the two source rows to point
767f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * to the same data.  The source width must be equal to either the
768f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * dest width or two times the dest width.
769f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick *
770f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param datatype  GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT,
771f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick *                  \c GL_FLOAT, etc.
772f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param comps     number of components per pixel (1..4)
773f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcWidth  Width of a row in the source data
774f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcRowA   Pointer to one of the rows of source data
775f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcRowB   Pointer to one of the rows of source data
776f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcRowC   Pointer to one of the rows of source data
777f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcRowD   Pointer to one of the rows of source data
778f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param dstWidth  Width of a row in the destination data
779f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick * \param srcRowA   Pointer to the row of destination data
780f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick */
781f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanickstatic void
782f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanickdo_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
783f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick          const GLvoid *srcRowA, const GLvoid *srcRowB,
784f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick          const GLvoid *srcRowC, const GLvoid *srcRowD,
785f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick          GLint dstWidth, GLvoid *dstRow)
786f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick{
787f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
788f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
789f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   GLuint i, j, k;
790f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
791f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   ASSERT(comps >= 1);
792f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   ASSERT(comps <= 4);
793f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
794f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   if ((datatype == GL_UNSIGNED_BYTE) && (comps == 4)) {
795f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLubyte, 4);
796f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
797f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
798f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
799f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
800f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
801f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(2);
802f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(3);
803f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
804f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
805f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 3)) {
806f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLubyte, 3);
807f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
808f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
809f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
810f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
811f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
812f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(2);
813f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
814f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
815f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 2)) {
816f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLubyte, 2);
817f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
818f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
819f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
820f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
821f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
822f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
823f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
824f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 1)) {
825f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLubyte, 1);
826f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
827f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
828f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
829f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
830f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
831f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
832746b602fbdd6e7955e076c0c0d39e86b01bd3dfdBrian Rogers   else if ((datatype == GL_BYTE) && (comps == 4)) {
833c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      DECLARE_ROW_POINTERS(GLbyte, 4);
834c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
835c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
836c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
837c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(0);
838c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(1);
839c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(2);
840c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(3);
841c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
842c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
843c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if ((datatype == GL_BYTE) && (comps == 3)) {
844c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      DECLARE_ROW_POINTERS(GLbyte, 3);
845c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
846c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
847c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
848c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(0);
849c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(1);
850c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(2);
851c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
852c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
853c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if ((datatype == GL_BYTE) && (comps == 2)) {
854c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      DECLARE_ROW_POINTERS(GLbyte, 2);
855c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
856c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
857c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
858c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(0);
859c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(1);
860c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger       }
861c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
862c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   else if ((datatype == GL_BYTE) && (comps == 1)) {
863c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      DECLARE_ROW_POINTERS(GLbyte, 1);
864c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
865c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
866c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger           i++, j += colStride, k += colStride) {
867c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger         FILTER_3D_SIGNED(0);
868c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger      }
869c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger   }
870f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) {
871f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLushort, 4);
872f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
873f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
874f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
875f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
876f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
877f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(2);
878f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(3);
879f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
880f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
881f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 3)) {
882f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLushort, 3);
883f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
884f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
885f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
886f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
887f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
888f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(2);
889f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
890f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
891f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 2)) {
892f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLushort, 2);
893f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
894f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
895f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
896f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
897f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(1);
898f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
899f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
900f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 1)) {
901f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLushort, 1);
902f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
903f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
904f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
905f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_3D(0);
906f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
907f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
908b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if ((datatype == GL_SHORT) && (comps == 4)) {
909b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      DECLARE_ROW_POINTERS(GLshort, 4);
910b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
911b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
912b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
913b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(0);
914b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(1);
915b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(2);
916b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(3);
917b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
918b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
919b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if ((datatype == GL_SHORT) && (comps == 3)) {
920b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      DECLARE_ROW_POINTERS(GLshort, 3);
921b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
922b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
923b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
924b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(0);
925b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(1);
926b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(2);
927b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
928b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
929b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if ((datatype == GL_SHORT) && (comps == 2)) {
930b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      DECLARE_ROW_POINTERS(GLshort, 2);
931b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
932b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
933b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
934b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(0);
935b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(1);
936b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
937b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
938b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if ((datatype == GL_SHORT) && (comps == 1)) {
939b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      DECLARE_ROW_POINTERS(GLshort, 1);
940b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
941b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
942b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
943b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         FILTER_3D(0);
944b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
945b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
946f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_FLOAT) && (comps == 4)) {
947f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLfloat, 4);
948f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
949f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
950f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
951f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(0);
952f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(1);
953f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(2);
954f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(3);
955f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
956f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
957f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_FLOAT) && (comps == 3)) {
958f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLfloat, 3);
959f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
960f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
961f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
962f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(0);
963f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(1);
964f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(2);
965f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
966f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
967f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_FLOAT) && (comps == 2)) {
968f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLfloat, 2);
969f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
970f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
971f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
972f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(0);
973f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(1);
974f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
975f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
976f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_FLOAT) && (comps == 1)) {
977f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLfloat, 1);
978f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
979f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
980f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
981f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_F_3D(0);
982f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
983f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
984f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 4)) {
985f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS(GLhalfARB, 4);
986f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
987f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
988f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
989f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(0);
990f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(1);
991f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(2);
992f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(3);
993f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
994f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
995f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 3)) {
9965c341b7df3c1058d586629394e53e9e26ae2cc01Ian Romanick      DECLARE_ROW_POINTERS(GLhalfARB, 3);
997f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
998f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
999f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1000f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(0);
1001f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(1);
1002f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(2);
1003f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1004f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1005f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 2)) {
10065c341b7df3c1058d586629394e53e9e26ae2cc01Ian Romanick      DECLARE_ROW_POINTERS(GLhalfARB, 2);
1007f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1008f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1009f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1010f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(0);
1011f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(1);
1012f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1013f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1014f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 1)) {
10155c341b7df3c1058d586629394e53e9e26ae2cc01Ian Romanick      DECLARE_ROW_POINTERS(GLhalfARB, 1);
1016f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1017f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1018f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1019f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         FILTER_HF_3D(0);
1020f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1021f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1022f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_INT) && (comps == 1)) {
1023f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLuint *rowA = (const GLuint *) srcRowA;
1024f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLuint *rowB = (const GLuint *) srcRowB;
1025f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLuint *rowC = (const GLuint *) srcRowC;
1026f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      const GLuint *rowD = (const GLuint *) srcRowD;
1027f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      GLfloat *dst = (GLfloat *) dstRow;
1028f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1029f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1030f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1031f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k])
1032f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                               + ((uint64_t) rowB[j] + (uint64_t) rowB[k])
1033f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                               + ((uint64_t) rowC[j] + (uint64_t) rowC[k])
1034f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                               + ((uint64_t) rowD[j] + (uint64_t) rowD[k]));
1035f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         dst[i] = (GLfloat)((double) tmp * 0.125);
1036f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1037f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1038f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT_5_6_5) && (comps == 3)) {
1039f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS0(GLushort);
1040f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1041f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1042f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1043f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr0 = rowA[j] & 0x1f;
1044f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr1 = rowA[k] & 0x1f;
1045f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr0 = rowB[j] & 0x1f;
1046f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr1 = rowB[k] & 0x1f;
1047f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr0 = rowC[j] & 0x1f;
1048f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr1 = rowC[k] & 0x1f;
1049f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr0 = rowD[j] & 0x1f;
1050f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr1 = rowD[k] & 0x1f;
1051f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
1052f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
1053f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
1054f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
1055f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg0 = (rowC[j] >> 5) & 0x3f;
1056f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg1 = (rowC[k] >> 5) & 0x3f;
1057f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg0 = (rowD[j] >> 5) & 0x3f;
1058f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg1 = (rowD[k] >> 5) & 0x3f;
1059f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
1060f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
1061f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
1062f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
1063f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb0 = (rowC[j] >> 11) & 0x1f;
1064f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb1 = (rowC[k] >> 11) & 0x1f;
1065f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb0 = (rowD[j] >> 11) & 0x1f;
1066f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb1 = (rowD[k] >> 11) & 0x1f;
1067f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1068f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCr0, rowCr1, rowDr0, rowDr1);
1069f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1070f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCg0, rowCg1, rowDg0, rowDg1);
1071f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1072f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCb0, rowCb1, rowDb0, rowDb1);
1073f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         dst[i] = (b << 11) | (g << 5) | r;
1074f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1075f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1076f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT_4_4_4_4) && (comps == 4)) {
1077f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS0(GLushort);
1078f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1079f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1080f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1081f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr0 = rowA[j] & 0xf;
1082f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr1 = rowA[k] & 0xf;
1083f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr0 = rowB[j] & 0xf;
1084f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr1 = rowB[k] & 0xf;
1085f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr0 = rowC[j] & 0xf;
1086f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr1 = rowC[k] & 0xf;
1087f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr0 = rowD[j] & 0xf;
1088f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr1 = rowD[k] & 0xf;
1089f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
1090f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
1091f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
1092f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
1093f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg0 = (rowC[j] >> 4) & 0xf;
1094f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg1 = (rowC[k] >> 4) & 0xf;
1095f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg0 = (rowD[j] >> 4) & 0xf;
1096f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg1 = (rowD[k] >> 4) & 0xf;
1097f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
1098f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
1099f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
1100f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
1101f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb0 = (rowC[j] >> 8) & 0xf;
1102f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb1 = (rowC[k] >> 8) & 0xf;
1103f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb0 = (rowD[j] >> 8) & 0xf;
1104f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb1 = (rowD[k] >> 8) & 0xf;
1105f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
1106f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
1107f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
1108f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
1109f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCa0 = (rowC[j] >> 12) & 0xf;
1110f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCa1 = (rowC[k] >> 12) & 0xf;
1111f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDa0 = (rowD[j] >> 12) & 0xf;
1112f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDa1 = (rowD[k] >> 12) & 0xf;
1113f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1114f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCr0, rowCr1, rowDr0, rowDr1);
1115f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1116f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCg0, rowCg1, rowDg0, rowDg1);
1117f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1118f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCb0, rowCb1, rowDb0, rowDb1);
1119f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
1120f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCa0, rowCa1, rowDa0, rowDa1);
1121f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1122f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         dst[i] = (a << 12) | (b << 8) | (g << 4) | r;
1123f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1124f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1125f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV) && (comps == 4)) {
1126f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      DECLARE_ROW_POINTERS0(GLushort);
1127f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1128f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1129f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1130f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr0 = rowA[j] & 0x1f;
1131f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr1 = rowA[k] & 0x1f;
1132f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr0 = rowB[j] & 0x1f;
1133f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr1 = rowB[k] & 0x1f;
1134f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr0 = rowC[j] & 0x1f;
1135f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr1 = rowC[k] & 0x1f;
1136f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr0 = rowD[j] & 0x1f;
1137f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr1 = rowD[k] & 0x1f;
1138f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
1139f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
1140f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
1141f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
1142f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg0 = (rowC[j] >> 5) & 0x1f;
1143f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg1 = (rowC[k] >> 5) & 0x1f;
1144f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg0 = (rowD[j] >> 5) & 0x1f;
1145f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg1 = (rowD[k] >> 5) & 0x1f;
1146f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
1147f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
1148f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
1149f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
1150f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb0 = (rowC[j] >> 10) & 0x1f;
1151f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb1 = (rowC[k] >> 10) & 0x1f;
1152f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb0 = (rowD[j] >> 10) & 0x1f;
1153f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb1 = (rowD[k] >> 10) & 0x1f;
1154f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
1155f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
1156f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
1157f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
1158f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCa0 = (rowC[j] >> 15) & 0x1;
1159f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCa1 = (rowC[k] >> 15) & 0x1;
1160f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDa0 = (rowD[j] >> 15) & 0x1;
1161f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDa1 = (rowD[k] >> 15) & 0x1;
1162f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1163f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCr0, rowCr1, rowDr0, rowDr1);
1164f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1165f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCg0, rowCg1, rowDg0, rowDg1);
1166f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1167f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCb0, rowCb1, rowDb0, rowDb1);
1168f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
1169f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCa0, rowCa1, rowDa0, rowDa1);
1170f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1171f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         dst[i] = (a << 15) | (b << 10) | (g << 5) | r;
1172f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1173f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1174b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   else if ((datatype == GL_UNSIGNED_SHORT_5_5_5_1) && (comps == 4)) {
1175b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      DECLARE_ROW_POINTERS0(GLushort);
1176b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
1177b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1178b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul           i++, j += colStride, k += colStride) {
1179b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAr0 = (rowA[j] >> 11) & 0x1f;
1180b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAr1 = (rowA[k] >> 11) & 0x1f;
1181b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBr0 = (rowB[j] >> 11) & 0x1f;
1182b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBr1 = (rowB[k] >> 11) & 0x1f;
1183b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCr0 = (rowC[j] >> 11) & 0x1f;
1184b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCr1 = (rowC[k] >> 11) & 0x1f;
1185b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDr0 = (rowD[j] >> 11) & 0x1f;
1186b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDr1 = (rowD[k] >> 11) & 0x1f;
1187b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAg0 = (rowA[j] >> 6) & 0x1f;
1188b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAg1 = (rowA[k] >> 6) & 0x1f;
1189b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBg0 = (rowB[j] >> 6) & 0x1f;
1190b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBg1 = (rowB[k] >> 6) & 0x1f;
1191b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCg0 = (rowC[j] >> 6) & 0x1f;
1192b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCg1 = (rowC[k] >> 6) & 0x1f;
1193b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDg0 = (rowD[j] >> 6) & 0x1f;
1194b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDg1 = (rowD[k] >> 6) & 0x1f;
1195b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAb0 = (rowA[j] >> 1) & 0x1f;
1196b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAb1 = (rowA[k] >> 1) & 0x1f;
1197b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBb0 = (rowB[j] >> 1) & 0x1f;
1198b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBb1 = (rowB[k] >> 1) & 0x1f;
1199b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCb0 = (rowC[j] >> 1) & 0x1f;
1200b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCb1 = (rowC[k] >> 1) & 0x1f;
1201b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDb0 = (rowD[j] >> 1) & 0x1f;
1202b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDb1 = (rowD[k] >> 1) & 0x1f;
1203b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAa0 = (rowA[j] & 0x1);
1204b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowAa1 = (rowA[k] & 0x1);
1205b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBa0 = (rowB[j] & 0x1);
1206b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowBa1 = (rowB[k] & 0x1);
1207b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCa0 = (rowC[j] & 0x1);
1208b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowCa1 = (rowC[k] & 0x1);
1209b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDa0 = (rowD[j] & 0x1);
1210b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint rowDa1 = (rowD[k] & 0x1);
1211b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1212b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul                                       rowCr0, rowCr1, rowDr0, rowDr1);
1213b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1214b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul                                       rowCg0, rowCg1, rowDg0, rowDg1);
1215b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1216b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul                                       rowCb0, rowCb1, rowDb0, rowDb1);
1217b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
1218b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul                                       rowCa0, rowCa1, rowDa0, rowDa1);
1219b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul
1220b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul         dst[i] = (r << 11) | (g << 6) | (b << 1) | a;
1221b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul      }
1222b3b6476695a8bb12b873d2e7d8556b7432723b5aBrian Paul   }
1223f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) {
12248513d3405bd5cd633579b16af1ab04253a8b37d9Marek Olšák      DECLARE_ROW_POINTERS0(GLubyte);
1225f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1226f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1227f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick           i++, j += colStride, k += colStride) {
1228f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr0 = rowA[j] & 0x3;
1229f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAr1 = rowA[k] & 0x3;
1230f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr0 = rowB[j] & 0x3;
1231f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBr1 = rowB[k] & 0x3;
1232f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr0 = rowC[j] & 0x3;
1233f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCr1 = rowC[k] & 0x3;
1234f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr0 = rowD[j] & 0x3;
1235f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDr1 = rowD[k] & 0x3;
1236f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
1237f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
1238f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
1239f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
1240f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg0 = (rowC[j] >> 2) & 0x7;
1241f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCg1 = (rowC[k] >> 2) & 0x7;
1242f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg0 = (rowD[j] >> 2) & 0x7;
1243f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDg1 = (rowD[k] >> 2) & 0x7;
1244f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
1245f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
1246f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
1247f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
1248f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb0 = (rowC[j] >> 5) & 0x7;
1249f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowCb1 = (rowC[k] >> 5) & 0x7;
1250f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb0 = (rowD[j] >> 5) & 0x7;
1251f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint rowDb1 = (rowD[k] >> 5) & 0x7;
1252f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1253f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCr0, rowCr1, rowDr0, rowDr1);
1254f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1255f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCg0, rowCg1, rowDg0, rowDg1);
1256f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1257f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                                       rowCb0, rowCb1, rowDb0, rowDb1);
1258f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         dst[i] = (b << 5) | (g << 2) | r;
1259f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      }
1260f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
12614d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák   else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) {
12628513d3405bd5cd633579b16af1ab04253a8b37d9Marek Olšák      DECLARE_ROW_POINTERS0(GLubyte);
12634d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák
12644d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
12654d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák           i++, j += colStride, k += colStride) {
12664d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAr0 = rowA[j] & 0xf;
12674d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAr1 = rowA[k] & 0xf;
12684d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBr0 = rowB[j] & 0xf;
12694d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBr1 = rowB[k] & 0xf;
12704d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowCr0 = rowC[j] & 0xf;
12714d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowCr1 = rowC[k] & 0xf;
12724d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowDr0 = rowD[j] & 0xf;
12734d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowDr1 = rowD[k] & 0xf;
12744d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
12754d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
12764d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
12774d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
12784d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowCg0 = (rowC[j] >> 4) & 0xf;
12794d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowCg1 = (rowC[k] >> 4) & 0xf;
12804d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowDg0 = (rowD[j] >> 4) & 0xf;
12814d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint rowDg1 = (rowD[k] >> 4) & 0xf;
12824d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
12834d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák                                       rowCr0, rowCr1, rowDr0, rowDr1);
12844d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
12854d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák                                       rowCg0, rowCg1, rowDg0, rowDg1);
12864d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák         dst[i] = (g << 4) | r;
12874d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák      }
12884d6994e40ebccf9428fc757d845e25c0e0c12cefMarek Olšák   }
1289628544421d243e0ca8679c5d245728260d9e010dMarek Olšák   else if ((datatype == GL_UNSIGNED_INT_2_10_10_10_REV) && (comps == 4)) {
1290628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      DECLARE_ROW_POINTERS0(GLuint);
1291628544421d243e0ca8679c5d245728260d9e010dMarek Olšák
1292628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1293628544421d243e0ca8679c5d245728260d9e010dMarek Olšák           i++, j += colStride, k += colStride) {
1294628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAr0 = rowA[j] & 0x3ff;
1295628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAr1 = rowA[k] & 0x3ff;
1296628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBr0 = rowB[j] & 0x3ff;
1297628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBr1 = rowB[k] & 0x3ff;
1298628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCr0 = rowC[j] & 0x3ff;
1299628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCr1 = rowC[k] & 0x3ff;
1300628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDr0 = rowD[j] & 0x3ff;
1301628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDr1 = rowD[k] & 0x3ff;
1302628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAg0 = (rowA[j] >> 10) & 0x3ff;
1303628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAg1 = (rowA[k] >> 10) & 0x3ff;
1304628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBg0 = (rowB[j] >> 10) & 0x3ff;
1305628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBg1 = (rowB[k] >> 10) & 0x3ff;
1306628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCg0 = (rowC[j] >> 10) & 0x3ff;
1307628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCg1 = (rowC[k] >> 10) & 0x3ff;
1308628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDg0 = (rowD[j] >> 10) & 0x3ff;
1309628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDg1 = (rowD[k] >> 10) & 0x3ff;
1310628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAb0 = (rowA[j] >> 20) & 0x3ff;
1311628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAb1 = (rowA[k] >> 20) & 0x3ff;
1312628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBb0 = (rowB[j] >> 20) & 0x3ff;
1313628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBb1 = (rowB[k] >> 20) & 0x3ff;
1314628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCb0 = (rowC[j] >> 20) & 0x3ff;
1315628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCb1 = (rowC[k] >> 20) & 0x3ff;
1316628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDb0 = (rowD[j] >> 20) & 0x3ff;
1317628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDb1 = (rowD[k] >> 20) & 0x3ff;
1318628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAa0 = (rowA[j] >> 30) & 0x3;
1319628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowAa1 = (rowA[k] >> 30) & 0x3;
1320628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBa0 = (rowB[j] >> 30) & 0x3;
1321628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowBa1 = (rowB[k] >> 30) & 0x3;
1322628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCa0 = (rowC[j] >> 30) & 0x3;
1323628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowCa1 = (rowC[k] >> 30) & 0x3;
1324628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDa0 = (rowD[j] >> 30) & 0x3;
1325628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint rowDa1 = (rowD[k] >> 30) & 0x3;
1326628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
1327628544421d243e0ca8679c5d245728260d9e010dMarek Olšák                                       rowCr0, rowCr1, rowDr0, rowDr1);
1328628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
1329628544421d243e0ca8679c5d245728260d9e010dMarek Olšák                                       rowCg0, rowCg1, rowDg0, rowDg1);
1330628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
1331628544421d243e0ca8679c5d245728260d9e010dMarek Olšák                                       rowCb0, rowCb1, rowDb0, rowDb1);
1332628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
1333628544421d243e0ca8679c5d245728260d9e010dMarek Olšák                                       rowCa0, rowCa1, rowDa0, rowDa1);
1334628544421d243e0ca8679c5d245728260d9e010dMarek Olšák
1335628544421d243e0ca8679c5d245728260d9e010dMarek Olšák         dst[i] = (a << 30) | (b << 20) | (g << 10) | r;
1336628544421d243e0ca8679c5d245728260d9e010dMarek Olšák      }
1337628544421d243e0ca8679c5d245728260d9e010dMarek Olšák   }
13389d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák
13399d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák   else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) {
13409d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      DECLARE_ROW_POINTERS0(GLuint);
13419d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák
13429d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLfloat res[3];
13439d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3];
13449d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3];
13459d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák
13469d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
13479d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák           i++, j += colStride, k += colStride) {
13489d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowA[j], rowAj);
13499d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowB[j], rowBj);
13509d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowC[j], rowCj);
13519d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowD[j], rowDj);
13529d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowA[k], rowAk);
13539d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowB[k], rowBk);
13549d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowC[k], rowCk);
13559d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         rgb9e5_to_float3(rowD[k], rowDk);
13569d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] +
13579d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák                   rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F;
13589d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] +
13599d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák                   rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F;
13609d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] +
13619d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák                   rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F;
13629d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák         dst[i] = float3_to_rgb9e5(res);
13639d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák      }
13649d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák   }
13659d7698c468f4ea7da8bb4ec00520c98f11cca0faMarek Olšák
1366631d23daa91c569bf268a2191bd466df73a64263Marek Olšák   else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) {
1367631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      DECLARE_ROW_POINTERS0(GLuint);
1368631d23daa91c569bf268a2191bd466df73a64263Marek Olšák
1369631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLfloat res[3];
1370631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3];
1371631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3];
1372631d23daa91c569bf268a2191bd466df73a64263Marek Olšák
1373631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1374631d23daa91c569bf268a2191bd466df73a64263Marek Olšák           i++, j += colStride, k += colStride) {
1375631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowA[j], rowAj);
1376631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowB[j], rowBj);
1377631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowC[j], rowCj);
1378631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowD[j], rowDj);
1379631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowA[k], rowAk);
1380631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowB[k], rowBk);
1381631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowC[k], rowCk);
1382631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         r11g11b10f_to_float3(rowD[k], rowDk);
1383631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] +
1384631d23daa91c569bf268a2191bd466df73a64263Marek Olšák                   rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F;
1385631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] +
1386631d23daa91c569bf268a2191bd466df73a64263Marek Olšák                   rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F;
1387631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] +
1388631d23daa91c569bf268a2191bd466df73a64263Marek Olšák                   rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F;
1389631d23daa91c569bf268a2191bd466df73a64263Marek Olšák         dst[i] = float3_to_r11g11b10f(res);
1390631d23daa91c569bf268a2191bd466df73a64263Marek Olšák      }
1391631d23daa91c569bf268a2191bd466df73a64263Marek Olšák   }
1392631d23daa91c569bf268a2191bd466df73a64263Marek Olšák
1393bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák   else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && comps == 1) {
1394bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      DECLARE_ROW_POINTERS(GLfloat, 2);
1395bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák
1396bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      for (i = j = 0, k = k0; i < (GLuint) dstWidth;
1397bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák           i++, j += colStride, k += colStride) {
1398bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák         FILTER_F_3D(0);
1399bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák      }
1400bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák   }
1401bde6a044588401ebbd14881cd5621095c221f0a5Marek Olšák
1402f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   else {
1403f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick      _mesa_problem(NULL, "bad format in do_row()");
1404f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick   }
1405f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick}
1406f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
1407f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
140824edd9015951dd41898902b6c3973fe605e5871aBrian Paul/*
140924edd9015951dd41898902b6c3973fe605e5871aBrian Paul * These functions generate a 1/2-size mipmap image from a source image.
141024edd9015951dd41898902b6c3973fe605e5871aBrian Paul * Texture borders are handled by copying or averaging the source image's
141124edd9015951dd41898902b6c3973fe605e5871aBrian Paul * border texels, depending on the scale-down factor.
141224edd9015951dd41898902b6c3973fe605e5871aBrian Paul */
141324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
141424edd9015951dd41898902b6c3973fe605e5871aBrian Paulstatic void
1415b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellmake_1d_mipmap(GLenum datatype, GLuint comps, GLint border,
141624edd9015951dd41898902b6c3973fe605e5871aBrian Paul               GLint srcWidth, const GLubyte *srcPtr,
141724edd9015951dd41898902b6c3973fe605e5871aBrian Paul               GLint dstWidth, GLubyte *dstPtr)
141824edd9015951dd41898902b6c3973fe605e5871aBrian Paul{
1419b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   const GLint bpt = bytes_per_pixel(datatype, comps);
142024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLubyte *src;
142124edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLubyte *dst;
142224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
142324edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* skip the border pixel, if any */
142424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   src = srcPtr + border * bpt;
142524edd9015951dd41898902b6c3973fe605e5871aBrian Paul   dst = dstPtr + border * bpt;
142624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
142724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* we just duplicate the input row, kind of hack, saves code */
1428b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   do_row(datatype, comps, srcWidth - 2 * border, src, src,
142924edd9015951dd41898902b6c3973fe605e5871aBrian Paul          dstWidth - 2 * border, dst);
143024edd9015951dd41898902b6c3973fe605e5871aBrian Paul
143124edd9015951dd41898902b6c3973fe605e5871aBrian Paul   if (border) {
143224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* copy left-most pixel from source */
143375dba756b2e3d6850b56376d7c183dc3277a563bVinson Lee      assert(dstPtr);
1434bfdee9cc70f21ef34ca8497d30ab72106ce43bd1Vinson Lee      assert(srcPtr);
1435e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr, srcPtr, bpt);
143624edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* copy right-most pixel from source */
1437e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr + (dstWidth - 1) * bpt,
143824edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + (srcWidth - 1) * bpt,
143924edd9015951dd41898902b6c3973fe605e5871aBrian Paul             bpt);
144024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
144124edd9015951dd41898902b6c3973fe605e5871aBrian Paul}
144224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
144324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
144424edd9015951dd41898902b6c3973fe605e5871aBrian Paulstatic void
1445b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellmake_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
1446101abee6c4fc2c9284ff2ba6f9f9138327d6963dEric Anholt               GLint srcWidth, GLint srcHeight,
1447101abee6c4fc2c9284ff2ba6f9f9138327d6963dEric Anholt	       const GLubyte *srcPtr, GLint srcRowStride,
1448101abee6c4fc2c9284ff2ba6f9f9138327d6963dEric Anholt               GLint dstWidth, GLint dstHeight,
1449101abee6c4fc2c9284ff2ba6f9f9138327d6963dEric Anholt	       GLubyte *dstPtr, GLint dstRowStride)
145024edd9015951dd41898902b6c3973fe605e5871aBrian Paul{
1451b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   const GLint bpt = bytes_per_pixel(datatype, comps);
145224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
145324edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
145424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
145524edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLubyte *srcA, *srcB;
145624edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLubyte *dst;
14574ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul   GLint row, srcRowStep;
145824edd9015951dd41898902b6c3973fe605e5871aBrian Paul
145924edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* Compute src and dst pointers, skipping any border */
146024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
14614ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul   if (srcHeight > 1 && srcHeight > dstHeight) {
14624ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul      /* sample from two source rows */
1463e0304180c32227342dbb67b707bfae446543bb48Brian Paul      srcB = srcA + srcRowStride;
14644ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul      srcRowStep = 2;
14654ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul   }
14664ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul   else {
14674ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul      /* sample from one source row */
146824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      srcB = srcA;
14694ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul      srcRowStep = 1;
14704ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul   }
14714ff3467daf0ac07e4295c7d2e2ad3c3c8c89dff6Brian Paul
147224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
147324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
147424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   for (row = 0; row < dstHeightNB; row++) {
1475b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      do_row(datatype, comps, srcWidthNB, srcA, srcB,
147624edd9015951dd41898902b6c3973fe605e5871aBrian Paul             dstWidthNB, dst);
1477e0304180c32227342dbb67b707bfae446543bb48Brian Paul      srcA += srcRowStep * srcRowStride;
1478e0304180c32227342dbb67b707bfae446543bb48Brian Paul      srcB += srcRowStep * srcRowStride;
1479e0304180c32227342dbb67b707bfae446543bb48Brian Paul      dst += dstRowStride;
148024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
148124edd9015951dd41898902b6c3973fe605e5871aBrian Paul
148224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* This is ugly but probably won't be used much */
148324edd9015951dd41898902b6c3973fe605e5871aBrian Paul   if (border > 0) {
148424edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* fill in dest border */
148524edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* lower-left border pixel */
148675dba756b2e3d6850b56376d7c183dc3277a563bVinson Lee      assert(dstPtr);
148775dba756b2e3d6850b56376d7c183dc3277a563bVinson Lee      assert(srcPtr);
1488e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr, srcPtr, bpt);
148924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* lower-right border pixel */
1490e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr + (dstWidth - 1) * bpt,
149124edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
149224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* upper-left border pixel */
1493e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
149424edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
149524edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* upper-right border pixel */
1496e197de56cdb86835f1437688a9161cd909792d80Brian Paul      memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
149724edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
149824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* lower border */
1499b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      do_row(datatype, comps, srcWidthNB,
150024edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + bpt,
150124edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + bpt,
150224edd9015951dd41898902b6c3973fe605e5871aBrian Paul             dstWidthNB, dstPtr + bpt);
150324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* upper border */
1504b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell      do_row(datatype, comps, srcWidthNB,
150524edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
150624edd9015951dd41898902b6c3973fe605e5871aBrian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
150724edd9015951dd41898902b6c3973fe605e5871aBrian Paul             dstWidthNB,
150824edd9015951dd41898902b6c3973fe605e5871aBrian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
150924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* left and right borders */
151024edd9015951dd41898902b6c3973fe605e5871aBrian Paul      if (srcHeight == dstHeight) {
151124edd9015951dd41898902b6c3973fe605e5871aBrian Paul         /* copy border pixel from src to dst */
151224edd9015951dd41898902b6c3973fe605e5871aBrian Paul         for (row = 1; row < srcHeight; row++) {
1513e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dstPtr + dstWidth * row * bpt,
151424edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + srcWidth * row * bpt, bpt);
1515e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
151624edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
151724edd9015951dd41898902b6c3973fe605e5871aBrian Paul         }
151824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
151924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      else {
152024edd9015951dd41898902b6c3973fe605e5871aBrian Paul         /* average two src pixels each dest pixel */
152124edd9015951dd41898902b6c3973fe605e5871aBrian Paul         for (row = 0; row < dstHeightNB; row += 2) {
1522b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            do_row(datatype, comps, 1,
152324edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
152424edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
152524edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
1526b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell            do_row(datatype, comps, 1,
152724edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
152824edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
152924edd9015951dd41898902b6c3973fe605e5871aBrian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
153024edd9015951dd41898902b6c3973fe605e5871aBrian Paul         }
153124edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
153224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
153324edd9015951dd41898902b6c3973fe605e5871aBrian Paul}
153424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
153524edd9015951dd41898902b6c3973fe605e5871aBrian Paul
153624edd9015951dd41898902b6c3973fe605e5871aBrian Paulstatic void
1537b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwellmake_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
153824edd9015951dd41898902b6c3973fe605e5871aBrian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
1539e0304180c32227342dbb67b707bfae446543bb48Brian Paul               const GLubyte **srcPtr, GLint srcRowStride,
154024edd9015951dd41898902b6c3973fe605e5871aBrian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
1541e0304180c32227342dbb67b707bfae446543bb48Brian Paul               GLubyte **dstPtr, GLint dstRowStride)
154224edd9015951dd41898902b6c3973fe605e5871aBrian Paul{
1543b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell   const GLint bpt = bytes_per_pixel(datatype, comps);
154424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
154524edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
154624edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
154724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
154824edd9015951dd41898902b6c3973fe605e5871aBrian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
154924edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLint img, row;
155024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
155124edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
155224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   GLint srcImageOffset, srcRowOffset;
155324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
155424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   (void) srcDepthNB; /* silence warnings */
155524edd9015951dd41898902b6c3973fe605e5871aBrian Paul
155624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
155724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
155824edd9015951dd41898902b6c3973fe605e5871aBrian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
155924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
156024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   bytesPerSrcRow = srcWidth * bpt;
156124edd9015951dd41898902b6c3973fe605e5871aBrian Paul   bytesPerDstRow = dstWidth * bpt;
156224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
156324edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* Offset between adjacent src images to be averaged together */
1564e0304180c32227342dbb67b707bfae446543bb48Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : 1;
156524edd9015951dd41898902b6c3973fe605e5871aBrian Paul
156624edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* Offset between adjacent src rows to be averaged together */
156724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
156824edd9015951dd41898902b6c3973fe605e5871aBrian Paul
156924edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /*
157024edd9015951dd41898902b6c3973fe605e5871aBrian Paul    * Need to average together up to 8 src pixels for each dest pixel.
157124edd9015951dd41898902b6c3973fe605e5871aBrian Paul    * Break that down into 3 operations:
157224edd9015951dd41898902b6c3973fe605e5871aBrian Paul    *   1. take two rows from source image and average them together.
157324edd9015951dd41898902b6c3973fe605e5871aBrian Paul    *   2. take two rows from next source image and average them together.
157424edd9015951dd41898902b6c3973fe605e5871aBrian Paul    *   3. take the two averaged rows and average them for the final dst row.
157524edd9015951dd41898902b6c3973fe605e5871aBrian Paul    */
157624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
157724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /*
1578298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
157924edd9015951dd41898902b6c3973fe605e5871aBrian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
158024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   */
158124edd9015951dd41898902b6c3973fe605e5871aBrian Paul
158224edd9015951dd41898902b6c3973fe605e5871aBrian Paul   for (img = 0; img < dstDepthNB; img++) {
158324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* first source image pointer, skipping border */
1584e0304180c32227342dbb67b707bfae446543bb48Brian Paul      const GLubyte *imgSrcA = srcPtr[img * 2 + border]
1585e0304180c32227342dbb67b707bfae446543bb48Brian Paul         + bytesPerSrcRow * border + bpt * border;
158624edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* second source image pointer, skipping border */
1587e0304180c32227342dbb67b707bfae446543bb48Brian Paul      const GLubyte *imgSrcB = srcPtr[img * 2 + srcImageOffset + border]
1588e0304180c32227342dbb67b707bfae446543bb48Brian Paul         + bytesPerSrcRow * border + bpt * border;
1589e0304180c32227342dbb67b707bfae446543bb48Brian Paul
159024edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* address of the dest image, skipping border */
1591e0304180c32227342dbb67b707bfae446543bb48Brian Paul      GLubyte *imgDst = dstPtr[img + border]
1592e0304180c32227342dbb67b707bfae446543bb48Brian Paul         + bytesPerDstRow * border + bpt * border;
159324edd9015951dd41898902b6c3973fe605e5871aBrian Paul
159424edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* setup the four source row pointers and the dest row pointer */
159524edd9015951dd41898902b6c3973fe605e5871aBrian Paul      const GLubyte *srcImgARowA = imgSrcA;
159624edd9015951dd41898902b6c3973fe605e5871aBrian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
159724edd9015951dd41898902b6c3973fe605e5871aBrian Paul      const GLubyte *srcImgBRowA = imgSrcB;
159824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
159924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      GLubyte *dstImgRow = imgDst;
160024edd9015951dd41898902b6c3973fe605e5871aBrian Paul
160124edd9015951dd41898902b6c3973fe605e5871aBrian Paul      for (row = 0; row < dstHeightNB; row++) {
1602f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick         do_row_3D(datatype, comps, srcWidthNB,
1603f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   srcImgARowA, srcImgARowB,
1604f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   srcImgBRowA, srcImgBRowB,
1605f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick                   dstWidthNB, dstImgRow);
1606f83f5ec8f5f1159cfd0ec2596ceab725c073266eIan Romanick
160724edd9015951dd41898902b6c3973fe605e5871aBrian Paul         /* advance to next rows */
160824edd9015951dd41898902b6c3973fe605e5871aBrian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
160924edd9015951dd41898902b6c3973fe605e5871aBrian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
161024edd9015951dd41898902b6c3973fe605e5871aBrian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
161124edd9015951dd41898902b6c3973fe605e5871aBrian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
161224edd9015951dd41898902b6c3973fe605e5871aBrian Paul         dstImgRow += bytesPerDstRow;
161324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
161424edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
161524edd9015951dd41898902b6c3973fe605e5871aBrian Paul
161624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
161724edd9015951dd41898902b6c3973fe605e5871aBrian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
161824edd9015951dd41898902b6c3973fe605e5871aBrian Paul   if (border > 0) {
161924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* do front border image */
1620e0304180c32227342dbb67b707bfae446543bb48Brian Paul      make_2d_mipmap(datatype, comps, 1,
1621e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     srcWidth, srcHeight, srcPtr[0], srcRowStride,
1622e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     dstWidth, dstHeight, dstPtr[0], dstRowStride);
162324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* do back border image */
1624e0304180c32227342dbb67b707bfae446543bb48Brian Paul      make_2d_mipmap(datatype, comps, 1,
1625e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     srcWidth, srcHeight, srcPtr[srcDepth - 1], srcRowStride,
1626e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     dstWidth, dstHeight, dstPtr[dstDepth - 1], dstRowStride);
1627e0304180c32227342dbb67b707bfae446543bb48Brian Paul
162824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* do four remaining border edges that span the image slices */
162924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      if (srcDepth == dstDepth) {
163024edd9015951dd41898902b6c3973fe605e5871aBrian Paul         /* just copy border pixels from src to dst */
163124edd9015951dd41898902b6c3973fe605e5871aBrian Paul         for (img = 0; img < dstDepthNB; img++) {
163224edd9015951dd41898902b6c3973fe605e5871aBrian Paul            const GLubyte *src;
163324edd9015951dd41898902b6c3973fe605e5871aBrian Paul            GLubyte *dst;
163424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
163524edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=0][col=0] */
1636e0304180c32227342dbb67b707bfae446543bb48Brian Paul            src = srcPtr[img * 2];
1637e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img];
1638e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dst, src, bpt);
163924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
164024edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=dstHeight-1][col=0] */
1641e0304180c32227342dbb67b707bfae446543bb48Brian Paul            src = srcPtr[img * 2] + (srcHeight - 1) * bytesPerSrcRow;
1642e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
1643e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dst, src, bpt);
164424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
164524edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=0][col=dstWidth-1] */
1646e0304180c32227342dbb67b707bfae446543bb48Brian Paul            src = srcPtr[img * 2] + (srcWidth - 1) * bpt;
1647e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (dstWidth - 1) * bpt;
1648e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dst, src, bpt);
164924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
165024edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
1651e0304180c32227342dbb67b707bfae446543bb48Brian Paul            src = srcPtr[img * 2] + (bytesPerSrcImage - bpt);
1652e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (bytesPerDstImage - bpt);
1653e197de56cdb86835f1437688a9161cd909792d80Brian Paul            memcpy(dst, src, bpt);
165424edd9015951dd41898902b6c3973fe605e5871aBrian Paul         }
165524edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
165624edd9015951dd41898902b6c3973fe605e5871aBrian Paul      else {
165724edd9015951dd41898902b6c3973fe605e5871aBrian Paul         /* average border pixels from adjacent src image pairs */
165824edd9015951dd41898902b6c3973fe605e5871aBrian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
165924edd9015951dd41898902b6c3973fe605e5871aBrian Paul         for (img = 0; img < dstDepthNB; img++) {
1660e0304180c32227342dbb67b707bfae446543bb48Brian Paul            const GLubyte *srcA, *srcB;
166124edd9015951dd41898902b6c3973fe605e5871aBrian Paul            GLubyte *dst;
166224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
166324edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=0][col=0] */
1664e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcA = srcPtr[img * 2 + 0];
1665e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcB = srcPtr[img * 2 + srcImageOffset];
1666e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img];
1667e0304180c32227342dbb67b707bfae446543bb48Brian Paul            do_row(datatype, comps, 1, srcA, srcB, 1, dst);
166824edd9015951dd41898902b6c3973fe605e5871aBrian Paul
166924edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=dstHeight-1][col=0] */
1670e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcA = srcPtr[img * 2 + 0]
1671e0304180c32227342dbb67b707bfae446543bb48Brian Paul               + (srcHeight - 1) * bytesPerSrcRow;
1672e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcB = srcPtr[img * 2 + srcImageOffset]
1673e0304180c32227342dbb67b707bfae446543bb48Brian Paul               + (srcHeight - 1) * bytesPerSrcRow;
1674e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
1675e0304180c32227342dbb67b707bfae446543bb48Brian Paul            do_row(datatype, comps, 1, srcA, srcB, 1, dst);
167624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
167724edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=0][col=dstWidth-1] */
1678e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcA = srcPtr[img * 2 + 0] + (srcWidth - 1) * bpt;
1679e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcB = srcPtr[img * 2 + srcImageOffset] + (srcWidth - 1) * bpt;
1680e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (dstWidth - 1) * bpt;
1681e0304180c32227342dbb67b707bfae446543bb48Brian Paul            do_row(datatype, comps, 1, srcA, srcB, 1, dst);
168224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
168324edd9015951dd41898902b6c3973fe605e5871aBrian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
1684e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcA = srcPtr[img * 2 + 0] + (bytesPerSrcImage - bpt);
1685e0304180c32227342dbb67b707bfae446543bb48Brian Paul            srcB = srcPtr[img * 2 + srcImageOffset] + (bytesPerSrcImage - bpt);
1686e0304180c32227342dbb67b707bfae446543bb48Brian Paul            dst = dstPtr[img] + (bytesPerDstImage - bpt);
1687e0304180c32227342dbb67b707bfae446543bb48Brian Paul            do_row(datatype, comps, 1, srcA, srcB, 1, dst);
168824edd9015951dd41898902b6c3973fe605e5871aBrian Paul         }
168924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
169024edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
169124edd9015951dd41898902b6c3973fe605e5871aBrian Paul}
169224edd9015951dd41898902b6c3973fe605e5871aBrian Paul
1693bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
169424edd9015951dd41898902b6c3973fe605e5871aBrian Paul/**
1695abb465cdc71da566d431f44feeec31594e01086fBrian * Down-sample a texture image to produce the next lower mipmap level.
1696adabd0e81e287cd5dac60fa63841d8b096d10d5fBrian Paul * \param comps  components per texel (1, 2, 3 or 4)
1697e0304180c32227342dbb67b707bfae446543bb48Brian Paul * \param srcData  array[slice] of pointers to source image slices
1698e0304180c32227342dbb67b707bfae446543bb48Brian Paul * \param dstData  array[slice] of pointers to dest image slices
1699e0304180c32227342dbb67b707bfae446543bb48Brian Paul * \param srcRowStride  stride between source rows, in bytes
1700e0304180c32227342dbb67b707bfae446543bb48Brian Paul * \param dstRowStride  stride between destination rows, in bytes
1701abb465cdc71da566d431f44feeec31594e01086fBrian */
1702abb465cdc71da566d431f44feeec31594e01086fBrianvoid
1703abb465cdc71da566d431f44feeec31594e01086fBrian_mesa_generate_mipmap_level(GLenum target,
1704abb465cdc71da566d431f44feeec31594e01086fBrian                            GLenum datatype, GLuint comps,
1705abb465cdc71da566d431f44feeec31594e01086fBrian                            GLint border,
1706abb465cdc71da566d431f44feeec31594e01086fBrian                            GLint srcWidth, GLint srcHeight, GLint srcDepth,
1707e0304180c32227342dbb67b707bfae446543bb48Brian Paul                            const GLubyte **srcData,
1708abb465cdc71da566d431f44feeec31594e01086fBrian                            GLint srcRowStride,
1709abb465cdc71da566d431f44feeec31594e01086fBrian                            GLint dstWidth, GLint dstHeight, GLint dstDepth,
1710e0304180c32227342dbb67b707bfae446543bb48Brian Paul                            GLubyte **dstData,
1711abb465cdc71da566d431f44feeec31594e01086fBrian                            GLint dstRowStride)
1712abb465cdc71da566d431f44feeec31594e01086fBrian{
17136fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt   int i;
17146fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt
1715abb465cdc71da566d431f44feeec31594e01086fBrian   switch (target) {
1716abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_1D:
1717abb465cdc71da566d431f44feeec31594e01086fBrian      make_1d_mipmap(datatype, comps, border,
1718e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     srcWidth, srcData[0],
1719e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     dstWidth, dstData[0]);
1720abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1721abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_2D:
1722abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1723abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1724abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1725abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1726abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1727abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1728abb465cdc71da566d431f44feeec31594e01086fBrian      make_2d_mipmap(datatype, comps, border,
1729e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     srcWidth, srcHeight, srcData[0], srcRowStride,
1730e0304180c32227342dbb67b707bfae446543bb48Brian Paul                     dstWidth, dstHeight, dstData[0], dstRowStride);
1731abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1732abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_3D:
1733abb465cdc71da566d431f44feeec31594e01086fBrian      make_3d_mipmap(datatype, comps, border,
1734abb465cdc71da566d431f44feeec31594e01086fBrian                     srcWidth, srcHeight, srcDepth,
1735abb465cdc71da566d431f44feeec31594e01086fBrian                     srcData, srcRowStride,
1736abb465cdc71da566d431f44feeec31594e01086fBrian                     dstWidth, dstHeight, dstDepth,
1737abb465cdc71da566d431f44feeec31594e01086fBrian                     dstData, dstRowStride);
1738abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1739abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_1D_ARRAY_EXT:
17406fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      assert(srcHeight == 1);
17416fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      assert(dstHeight == 1);
17426fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      for (i = 0; i < dstDepth; i++) {
17436fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt	 make_1d_mipmap(datatype, comps, border,
17446fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt			srcWidth, srcData[i],
17456fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt			dstWidth, dstData[i]);
17466fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      }
1747abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1748abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_2D_ARRAY_EXT:
1749372cf26698881d3a71019a85759ca49652757642Eric Anholt      for (i = 0; i < dstDepth; i++) {
1750372cf26698881d3a71019a85759ca49652757642Eric Anholt	 make_2d_mipmap(datatype, comps, border,
1751372cf26698881d3a71019a85759ca49652757642Eric Anholt			srcWidth, srcHeight, srcData[i], srcRowStride,
1752372cf26698881d3a71019a85759ca49652757642Eric Anholt			dstWidth, dstHeight, dstData[i], dstRowStride);
1753372cf26698881d3a71019a85759ca49652757642Eric Anholt      }
1754abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1755abb465cdc71da566d431f44feeec31594e01086fBrian   case GL_TEXTURE_RECTANGLE_NV:
17560c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   case GL_TEXTURE_EXTERNAL_OES:
1757abb465cdc71da566d431f44feeec31594e01086fBrian      /* no mipmaps, do nothing */
1758abb465cdc71da566d431f44feeec31594e01086fBrian      break;
1759abb465cdc71da566d431f44feeec31594e01086fBrian   default:
1760e0304180c32227342dbb67b707bfae446543bb48Brian Paul      _mesa_problem(NULL, "bad tex target in _mesa_generate_mipmaps");
1761abb465cdc71da566d431f44feeec31594e01086fBrian      return;
1762abb465cdc71da566d431f44feeec31594e01086fBrian   }
1763abb465cdc71da566d431f44feeec31594e01086fBrian}
1764abb465cdc71da566d431f44feeec31594e01086fBrian
1765abb465cdc71da566d431f44feeec31594e01086fBrian
1766abb465cdc71da566d431f44feeec31594e01086fBrian/**
176774c64fa748c833a9688d3a141a7807686701e24fBrian * compute next (level+1) image size
176874c64fa748c833a9688d3a141a7807686701e24fBrian * \return GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size)
176974c64fa748c833a9688d3a141a7807686701e24fBrian */
177074c64fa748c833a9688d3a141a7807686701e24fBrianstatic GLboolean
177174c64fa748c833a9688d3a141a7807686701e24fBriannext_mipmap_level_size(GLenum target, GLint border,
177274c64fa748c833a9688d3a141a7807686701e24fBrian                       GLint srcWidth, GLint srcHeight, GLint srcDepth,
177374c64fa748c833a9688d3a141a7807686701e24fBrian                       GLint *dstWidth, GLint *dstHeight, GLint *dstDepth)
177474c64fa748c833a9688d3a141a7807686701e24fBrian{
177574c64fa748c833a9688d3a141a7807686701e24fBrian   if (srcWidth - 2 * border > 1) {
177674c64fa748c833a9688d3a141a7807686701e24fBrian      *dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
177774c64fa748c833a9688d3a141a7807686701e24fBrian   }
177874c64fa748c833a9688d3a141a7807686701e24fBrian   else {
177974c64fa748c833a9688d3a141a7807686701e24fBrian      *dstWidth = srcWidth; /* can't go smaller */
178074c64fa748c833a9688d3a141a7807686701e24fBrian   }
178174c64fa748c833a9688d3a141a7807686701e24fBrian
178274c64fa748c833a9688d3a141a7807686701e24fBrian   if ((srcHeight - 2 * border > 1) &&
178374c64fa748c833a9688d3a141a7807686701e24fBrian       (target != GL_TEXTURE_1D_ARRAY_EXT)) {
178474c64fa748c833a9688d3a141a7807686701e24fBrian      *dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
178574c64fa748c833a9688d3a141a7807686701e24fBrian   }
178674c64fa748c833a9688d3a141a7807686701e24fBrian   else {
178774c64fa748c833a9688d3a141a7807686701e24fBrian      *dstHeight = srcHeight; /* can't go smaller */
178874c64fa748c833a9688d3a141a7807686701e24fBrian   }
178974c64fa748c833a9688d3a141a7807686701e24fBrian
179074c64fa748c833a9688d3a141a7807686701e24fBrian   if ((srcDepth - 2 * border > 1) &&
179174c64fa748c833a9688d3a141a7807686701e24fBrian       (target != GL_TEXTURE_2D_ARRAY_EXT)) {
179274c64fa748c833a9688d3a141a7807686701e24fBrian      *dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
179374c64fa748c833a9688d3a141a7807686701e24fBrian   }
179474c64fa748c833a9688d3a141a7807686701e24fBrian   else {
179574c64fa748c833a9688d3a141a7807686701e24fBrian      *dstDepth = srcDepth; /* can't go smaller */
179674c64fa748c833a9688d3a141a7807686701e24fBrian   }
179774c64fa748c833a9688d3a141a7807686701e24fBrian
179874c64fa748c833a9688d3a141a7807686701e24fBrian   if (*dstWidth == srcWidth &&
179974c64fa748c833a9688d3a141a7807686701e24fBrian       *dstHeight == srcHeight &&
180074c64fa748c833a9688d3a141a7807686701e24fBrian       *dstDepth == srcDepth) {
180174c64fa748c833a9688d3a141a7807686701e24fBrian      return GL_FALSE;
180274c64fa748c833a9688d3a141a7807686701e24fBrian   }
180374c64fa748c833a9688d3a141a7807686701e24fBrian   else {
180474c64fa748c833a9688d3a141a7807686701e24fBrian      return GL_TRUE;
180574c64fa748c833a9688d3a141a7807686701e24fBrian   }
180674c64fa748c833a9688d3a141a7807686701e24fBrian}
180774c64fa748c833a9688d3a141a7807686701e24fBrian
1808d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1809d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul/**
1810d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul * Helper function for mipmap generation.
1811d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul * Make sure the specified destination mipmap level is the right size/format
1812d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul * for mipmap generation.  If not, (re) allocate it.
1813d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop
1814d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul */
1815d77b963245fd286aecd6c04f7beb748ad22129cfBrian PaulGLboolean
1816d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul_mesa_prepare_mipmap_level(struct gl_context *ctx,
1817d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                           struct gl_texture_object *texObj, GLuint level,
1818d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                           GLsizei width, GLsizei height, GLsizei depth,
1819d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                           GLsizei border, GLenum intFormat, gl_format format)
1820d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul{
182146751edca9a95baff81771aa69986fa6e2422ed6Brian Paul   const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1822d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   GLuint face;
1823d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1824d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   if (texObj->Immutable) {
1825d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      /* The texture was created with glTexStorage() so the number/size of
1826d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul       * mipmap levels is fixed and the storage for all images is already
1827d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul       * allocated.
1828d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul       */
1829d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (!texObj->Image[0][level]) {
1830d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         /* No more levels to create - we're done */
1831d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         return GL_FALSE;
1832d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      }
1833d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      else {
1834d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         /* Nothing to do - the texture memory must have already been
1835d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          * allocated to the right size so we're all set.
1836d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          */
1837d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         return GL_TRUE;
1838d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      }
1839d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   }
1840d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1841d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   for (face = 0; face < numFaces; face++) {
1842d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      struct gl_texture_image *dstImage;
1843d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      GLenum target;
1844d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1845d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (numFaces == 1)
1846d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         target = texObj->Target;
1847d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      else
1848d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
1849d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1850d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      dstImage = _mesa_get_tex_image(ctx, texObj, target, level);
1851d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (!dstImage) {
1852d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         /* out of memory */
1853d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         return GL_FALSE;
1854d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      }
1855d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1856d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (dstImage->Width != width ||
1857d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          dstImage->Height != height ||
1858d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          dstImage->Depth != depth ||
1859d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          dstImage->Border != border ||
1860d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          dstImage->InternalFormat != intFormat ||
1861d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul          dstImage->TexFormat != format) {
1862d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         /* need to (re)allocate image */
1863d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
1864d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1865892a2542a3f0753a7064c710b96f077dd5490624Brian Paul         _mesa_init_teximage_fields(ctx, dstImage,
1866d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                    width, height, depth,
1867d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                    border, intFormat, format);
1868d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1869c9a7dfcf92e6adb4b85338c2c8dbbfbaf39fbfe7Pauli Nieminen         ctx->Driver.AllocTextureImageBuffer(ctx, dstImage);
1870d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1871d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         /* in case the mipmap level is part of an FBO: */
1872d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         _mesa_update_fbo_texture(ctx, texObj, face, level);
1873d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1874d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         ctx->NewState |= _NEW_TEXTURE;
1875d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      }
1876d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   }
1877d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1878d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul   return GL_TRUE;
1879d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul}
1880d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1881d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul
1882ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholtstatic void
1883ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholtgenerate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
1884ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt			     struct gl_texture_object *texObj,
1885ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt			     const struct gl_texture_image *srcImage,
1886ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt			     GLuint maxLevel)
1887ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt{
1888ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   GLint level;
1889ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   GLenum datatype;
1890ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   GLuint comps;
189174c64fa748c833a9688d3a141a7807686701e24fBrian
18922bfd81df0a05351d79613b84908f167d6c5ad0afEric Anholt   _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps);
1893ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
1894ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   for (level = texObj->BaseLevel; level < maxLevel; level++) {
1895ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      /* generate image[level+1] from image[level] */
1896e0304180c32227342dbb67b707bfae446543bb48Brian Paul      struct gl_texture_image *srcImage, *dstImage;
1897e0304180c32227342dbb67b707bfae446543bb48Brian Paul      GLint srcRowStride, dstRowStride;
1898ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      GLint srcWidth, srcHeight, srcDepth;
1899ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      GLint dstWidth, dstHeight, dstDepth;
1900ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      GLint border;
1901e0304180c32227342dbb67b707bfae446543bb48Brian Paul      GLint slice;
1902ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      GLboolean nextLevel;
1903e0304180c32227342dbb67b707bfae446543bb48Brian Paul      GLubyte **srcMaps, **dstMaps;
1904c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      GLboolean success = GL_TRUE;
1905ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
1906ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      /* get src image parameters */
1907ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
1908ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      ASSERT(srcImage);
1909ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      srcWidth = srcImage->Width;
1910ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      srcHeight = srcImage->Height;
1911ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      srcDepth = srcImage->Depth;
1912ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      border = srcImage->Border;
1913ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
1914ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      nextLevel = next_mipmap_level_size(target, border,
1915ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt                                         srcWidth, srcHeight, srcDepth,
1916ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt                                         &dstWidth, &dstHeight, &dstDepth);
19172bfd81df0a05351d79613b84908f167d6c5ad0afEric Anholt      if (!nextLevel)
1918ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt         return;
1919ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
1920d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
1921d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      dstWidth, dstHeight, dstDepth,
1922d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      border, srcImage->InternalFormat,
1923d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      srcImage->TexFormat)) {
1924ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt         return;
1925ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      }
1926ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
1927d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      /* get dest gl_texture_image */
1928d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
1929d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (!dstImage) {
193078026b8acef9d6eea4f37d9c5435447944d1befdBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
193178026b8acef9d6eea4f37d9c5435447944d1befdBrian Paul         return;
1932ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      }
1933ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
19346fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      if (target == GL_TEXTURE_1D_ARRAY) {
19356fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt	 srcDepth = srcHeight;
19366fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt	 dstDepth = dstHeight;
19376fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt	 srcHeight = 1;
19386fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt	 dstHeight = 1;
19396fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      }
19406fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt
1941e0304180c32227342dbb67b707bfae446543bb48Brian Paul      /* Map src texture image slices */
1942c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      srcMaps = (GLubyte **) calloc(srcDepth, sizeof(GLubyte *));
1943c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (srcMaps) {
1944c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         for (slice = 0; slice < srcDepth; slice++) {
1945c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            ctx->Driver.MapTextureImage(ctx, srcImage, slice,
1946c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        0, 0, srcWidth, srcHeight,
1947c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        GL_MAP_READ_BIT,
1948c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        &srcMaps[slice], &srcRowStride);
1949c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            if (!srcMaps[slice]) {
1950c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               success = GL_FALSE;
1951c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               break;
1952c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            }
1953c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         }
1954c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      }
1955c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      else {
1956c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         success = GL_FALSE;
1957e0304180c32227342dbb67b707bfae446543bb48Brian Paul      }
1958e0304180c32227342dbb67b707bfae446543bb48Brian Paul
1959e0304180c32227342dbb67b707bfae446543bb48Brian Paul      /* Map dst texture image slices */
1960c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      dstMaps = (GLubyte **) calloc(dstDepth, sizeof(GLubyte *));
1961c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (dstMaps) {
1962c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         for (slice = 0; slice < dstDepth; slice++) {
1963c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            ctx->Driver.MapTextureImage(ctx, dstImage, slice,
1964c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        0, 0, dstWidth, dstHeight,
1965c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        GL_MAP_WRITE_BIT,
1966c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                        &dstMaps[slice], &dstRowStride);
1967c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            if (!dstMaps[slice]) {
1968c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               success = GL_FALSE;
1969c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               break;
1970c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            }
1971c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         }
1972c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      }
1973c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      else {
1974c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         success = GL_FALSE;
1975e0304180c32227342dbb67b707bfae446543bb48Brian Paul      }
1976e0304180c32227342dbb67b707bfae446543bb48Brian Paul
1977c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (success) {
1978c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         /* generate one mipmap level (for 1D/2D/3D/array/etc texture) */
1979c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         _mesa_generate_mipmap_level(target, datatype, comps, border,
1980c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                     srcWidth, srcHeight, srcDepth,
1981c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                     (const GLubyte **) srcMaps, srcRowStride,
1982c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                     dstWidth, dstHeight, dstDepth,
1983c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul                                     dstMaps, dstRowStride);
1984c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      }
1985e0304180c32227342dbb67b707bfae446543bb48Brian Paul
1986e0304180c32227342dbb67b707bfae446543bb48Brian Paul      /* Unmap src image slices */
1987c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (srcMaps) {
1988c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         for (slice = 0; slice < srcDepth; slice++) {
1989c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            if (srcMaps[slice]) {
1990c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               ctx->Driver.UnmapTextureImage(ctx, srcImage, slice);
1991c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            }
1992c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         }
1993c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         free(srcMaps);
1994e0304180c32227342dbb67b707bfae446543bb48Brian Paul      }
1995e0304180c32227342dbb67b707bfae446543bb48Brian Paul
19966fc576fd8aa2680e7e35dc7108e29d0091472e33Eric Anholt      /* Unmap dst image slices */
1997c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (dstMaps) {
1998c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         for (slice = 0; slice < dstDepth; slice++) {
1999c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            if (dstMaps[slice]) {
2000c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul               ctx->Driver.UnmapTextureImage(ctx, dstImage, slice);
2001c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul            }
2002c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         }
2003c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         free(dstMaps);
2004e0304180c32227342dbb67b707bfae446543bb48Brian Paul      }
2005ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2006c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      if (!success) {
2007c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation");
2008c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul         break;
2009c5012c1d56dfbf11cd631b3b37890b40d56ac884Brian Paul      }
2010ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   } /* loop over mipmap levels */
2011ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt}
2012ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2013e0304180c32227342dbb67b707bfae446543bb48Brian Paul
2014ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholtstatic void
2015ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholtgenerate_mipmap_compressed(struct gl_context *ctx, GLenum target,
2016ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt			   struct gl_texture_object *texObj,
20170386d9ac7782f51996ce8417083d32493b377003Brian Paul			   struct gl_texture_image *srcImage,
2018ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt			   GLuint maxLevel)
201924edd9015951dd41898902b6c3973fe605e5871aBrian Paul{
2020ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   GLint level;
2021b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt   gl_format temp_format;
202210e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt   GLint components;
2023e0304180c32227342dbb67b707bfae446543bb48Brian Paul   GLuint temp_src_stride; /* in bytes */
2024529b9360f326dd25bd12cf8e036b9ac1c63a8032Brian Paul   GLubyte *temp_src = NULL, *temp_dst = NULL;
20250386d9ac7782f51996ce8417083d32493b377003Brian Paul   GLenum temp_datatype;
20260386d9ac7782f51996ce8417083d32493b377003Brian Paul   GLenum temp_base_format;
202724edd9015951dd41898902b6c3973fe605e5871aBrian Paul
20280386d9ac7782f51996ce8417083d32493b377003Brian Paul   /* only two types of compressed textures at this time */
2029b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt   assert(texObj->Target == GL_TEXTURE_2D ||
2030b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt	  texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);
2031b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt
20320386d9ac7782f51996ce8417083d32493b377003Brian Paul   /*
20330386d9ac7782f51996ce8417083d32493b377003Brian Paul    * Choose a format for the temporary, uncompressed base image.
20340386d9ac7782f51996ce8417083d32493b377003Brian Paul    * Then, get number of components, choose temporary image datatype,
20350386d9ac7782f51996ce8417083d32493b377003Brian Paul    * and get base format.
20360386d9ac7782f51996ce8417083d32493b377003Brian Paul    */
20370386d9ac7782f51996ce8417083d32493b377003Brian Paul   temp_format = _mesa_get_uncompressed_format(srcImage->TexFormat);
20380386d9ac7782f51996ce8417083d32493b377003Brian Paul
20390386d9ac7782f51996ce8417083d32493b377003Brian Paul   components = _mesa_format_num_components(temp_format);
20400386d9ac7782f51996ce8417083d32493b377003Brian Paul
20410386d9ac7782f51996ce8417083d32493b377003Brian Paul   /* Revisit this if we get compressed formats with >8 bits per component */
20420386d9ac7782f51996ce8417083d32493b377003Brian Paul   if (_mesa_get_format_datatype(srcImage->TexFormat)
20430386d9ac7782f51996ce8417083d32493b377003Brian Paul       == GL_SIGNED_NORMALIZED) {
20440386d9ac7782f51996ce8417083d32493b377003Brian Paul      temp_datatype = GL_BYTE;
20450386d9ac7782f51996ce8417083d32493b377003Brian Paul   }
20460386d9ac7782f51996ce8417083d32493b377003Brian Paul   else {
20470386d9ac7782f51996ce8417083d32493b377003Brian Paul      temp_datatype = GL_UNSIGNED_BYTE;
2048b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt   }
204924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
20500386d9ac7782f51996ce8417083d32493b377003Brian Paul   temp_base_format = _mesa_get_format_base_format(temp_format);
20510386d9ac7782f51996ce8417083d32493b377003Brian Paul
20520386d9ac7782f51996ce8417083d32493b377003Brian Paul
20530386d9ac7782f51996ce8417083d32493b377003Brian Paul   /* allocate storage for the temporary, uncompressed image */
2054b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt   /* 20 extra bytes, just be safe when calling last FetchTexel */
20550386d9ac7782f51996ce8417083d32493b377003Brian Paul   temp_src_stride = _mesa_format_row_stride(temp_format, srcImage->Width);
205610e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt   temp_src = (GLubyte *) malloc(temp_src_stride * srcImage->Height + 20);
205710e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt   if (!temp_src) {
2058b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
2059b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt      return;
2060b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt   }
206124edd9015951dd41898902b6c3973fe605e5871aBrian Paul
206210e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt   /* decompress base image to the temporary */
20630386d9ac7782f51996ce8417083d32493b377003Brian Paul   {
20640386d9ac7782f51996ce8417083d32493b377003Brian Paul      /* save pixel packing mode */
20650386d9ac7782f51996ce8417083d32493b377003Brian Paul      struct gl_pixelstore_attrib save = ctx->Pack;
20660386d9ac7782f51996ce8417083d32493b377003Brian Paul      /* use default/tight packing parameters */
20670386d9ac7782f51996ce8417083d32493b377003Brian Paul      ctx->Pack = ctx->DefaultPacking;
20680386d9ac7782f51996ce8417083d32493b377003Brian Paul
20690386d9ac7782f51996ce8417083d32493b377003Brian Paul      /* Get the uncompressed image */
20704368a657670f1f3f13d8497f749cb5439f91529eBrian Paul      assert(srcImage->Level == texObj->BaseLevel);
20714368a657670f1f3f13d8497f749cb5439f91529eBrian Paul      ctx->Driver.GetTexImage(ctx,
20720386d9ac7782f51996ce8417083d32493b377003Brian Paul                              temp_base_format, temp_datatype,
20734368a657670f1f3f13d8497f749cb5439f91529eBrian Paul                              temp_src, srcImage);
20740386d9ac7782f51996ce8417083d32493b377003Brian Paul      /* restore packing mode */
20750386d9ac7782f51996ce8417083d32493b377003Brian Paul      ctx->Pack = save;
207624edd9015951dd41898902b6c3973fe605e5871aBrian Paul   }
207724edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2078b08200237968e3129d0cb35e03b2a5514b1dcb53Keith Whitwell
2079ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   for (level = texObj->BaseLevel; level < maxLevel; level++) {
208024edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* generate image[level+1] from image[level] */
208124edd9015951dd41898902b6c3973fe605e5871aBrian Paul      const struct gl_texture_image *srcImage;
208224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      struct gl_texture_image *dstImage;
208324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      GLint srcWidth, srcHeight, srcDepth;
208424edd9015951dd41898902b6c3973fe605e5871aBrian Paul      GLint dstWidth, dstHeight, dstDepth;
208557fc2e7802d1903848c2d7799f7e36308818b2e2Brian Paul      GLint border;
208674c64fa748c833a9688d3a141a7807686701e24fBrian      GLboolean nextLevel;
2087e0304180c32227342dbb67b707bfae446543bb48Brian Paul      GLuint temp_dst_stride; /* in bytes */
208824edd9015951dd41898902b6c3973fe605e5871aBrian Paul
208924edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* get src image parameters */
2090faba58c447c9eeeea0f7ef405fa1ba1f73991375Brian Paul      srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
209124edd9015951dd41898902b6c3973fe605e5871aBrian Paul      ASSERT(srcImage);
209224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      srcWidth = srcImage->Width;
209324edd9015951dd41898902b6c3973fe605e5871aBrian Paul      srcHeight = srcImage->Height;
209424edd9015951dd41898902b6c3973fe605e5871aBrian Paul      srcDepth = srcImage->Depth;
209524edd9015951dd41898902b6c3973fe605e5871aBrian Paul      border = srcImage->Border;
209624edd9015951dd41898902b6c3973fe605e5871aBrian Paul
209774c64fa748c833a9688d3a141a7807686701e24fBrian      nextLevel = next_mipmap_level_size(target, border,
209874c64fa748c833a9688d3a141a7807686701e24fBrian                                         srcWidth, srcHeight, srcDepth,
209974c64fa748c833a9688d3a141a7807686701e24fBrian                                         &dstWidth, &dstHeight, &dstDepth);
210010e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt      if (!nextLevel)
210110e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 break;
210210e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt
210310e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt      temp_dst_stride = _mesa_format_row_stride(temp_format, dstWidth);
210410e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt      if (!temp_dst) {
210510e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 temp_dst = (GLubyte *) malloc(temp_dst_stride * dstHeight);
210610e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 if (!temp_dst) {
210710e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
210810e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	    break;
210910e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 }
211024edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
211124edd9015951dd41898902b6c3973fe605e5871aBrian Paul
211224edd9015951dd41898902b6c3973fe605e5871aBrian Paul      /* get dest gl_texture_image */
2113faba58c447c9eeeea0f7ef405fa1ba1f73991375Brian Paul      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
211424edd9015951dd41898902b6c3973fe605e5871aBrian Paul      if (!dstImage) {
211524edd9015951dd41898902b6c3973fe605e5871aBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
21169ec5050898877baa6120fd9a04464651c7cb28adBrian Paul         free(temp_dst);
211724edd9015951dd41898902b6c3973fe605e5871aBrian Paul         return;
211824edd9015951dd41898902b6c3973fe605e5871aBrian Paul      }
211924edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2120d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      /* rescale src image to dest image */
21210386d9ac7782f51996ce8417083d32493b377003Brian Paul      _mesa_generate_mipmap_level(target, temp_datatype, components, border,
212210e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt                                  srcWidth, srcHeight, srcDepth,
2123e0304180c32227342dbb67b707bfae446543bb48Brian Paul                                  (const GLubyte **) &temp_src,
2124e0304180c32227342dbb67b707bfae446543bb48Brian Paul                                  temp_src_stride,
212510e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt                                  dstWidth, dstHeight, dstDepth,
2126e0304180c32227342dbb67b707bfae446543bb48Brian Paul                                  &temp_dst, temp_dst_stride);
212724edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2128d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
2129d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      dstWidth, dstHeight, dstDepth,
2130d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      border, srcImage->InternalFormat,
2131d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul                                      srcImage->TexFormat)) {
2132b688700edc0ee8a4dcbac9b4cc5b0388691b7b43Vinson Lee         free(temp_dst);
2133d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul         return;
2134d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      }
2135e0304180c32227342dbb67b707bfae446543bb48Brian Paul
2136d77b963245fd286aecd6c04f7beb748ad22129cfBrian Paul      /* The image space was allocated above so use glTexSubImage now */
2137e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul      ctx->Driver.TexSubImage(ctx, 2, dstImage,
2138e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                              0, 0, 0, dstWidth, dstHeight, 1,
2139e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                              temp_base_format, temp_datatype,
2140e42d00b3f4503a0840575c8e5f4517a66c8af613Brian Paul                              temp_dst, &ctx->DefaultPacking);
2141b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt
2142b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt      /* swap src and dest pointers */
2143b0c4db68b2bea1d41ba42211a3ff6b41dfee21a8Eric Anholt      {
2144529b9360f326dd25bd12cf8e036b9ac1c63a8032Brian Paul	 GLubyte *temp = temp_src;
214510e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 temp_src = temp_dst;
214610e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 temp_dst = temp;
214710e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt	 temp_src_stride = temp_dst_stride;
214810e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt      }
214924edd9015951dd41898902b6c3973fe605e5871aBrian Paul   } /* loop over mipmap levels */
215010e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt
2151529b9360f326dd25bd12cf8e036b9ac1c63a8032Brian Paul   free(temp_src);
215210e418f3815d690b2526e835bc7eb421b6be7050Eric Anholt   free(temp_dst);
215324edd9015951dd41898902b6c3973fe605e5871aBrian Paul}
215424edd9015951dd41898902b6c3973fe605e5871aBrian Paul
2155ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt/**
2156ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * Automatic mipmap generation.
2157ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * This is the fallback/default function for ctx->Driver.GenerateMipmap().
2158ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * Generate a complete set of mipmaps from texObj's BaseLevel image.
2159ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
2160ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * For cube maps, target will be one of
2161ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP.
2162ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt */
2163ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholtvoid
2164ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
2165ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt                      struct gl_texture_object *texObj)
2166ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt{
21670386d9ac7782f51996ce8417083d32493b377003Brian Paul   struct gl_texture_image *srcImage;
2168ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   GLint maxLevel;
2169ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2170ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   ASSERT(texObj);
2171ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
2172ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   ASSERT(srcImage);
2173ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2174ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1;
2175ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   ASSERT(maxLevel >= 0);  /* bad target */
2176ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2177ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   maxLevel = MIN2(maxLevel, texObj->MaxLevel);
2178ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt
2179ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   if (_mesa_is_format_compressed(srcImage->TexFormat)) {
2180ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      generate_mipmap_compressed(ctx, target, texObj, srcImage, maxLevel);
2181ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   } else {
2182ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt      generate_mipmap_uncompressed(ctx, target, texObj, srcImage, maxLevel);
2183ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt   }
2184ba55ccd312e8a025f568ffcdc622660f146e2147Eric Anholt}
2185